
Playback and indexing now occur in the same service through a new bridge called AuxioService. AuxioService contains the existing service instances as Fragment implementations, and then forwards typical service events to them (albeit this will drift more and more as I continue to deal with lifecycle issues). This should be the first step in enabling true service independence, as it means that the service will now immediately initialize and load music as soon as possible.
153 lines
5.7 KiB
Kotlin
153 lines
5.7 KiB
Kotlin
/*
|
|
* Copyright (c) 2021 Auxio Project
|
|
* MainActivity.kt is part of Auxio.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package org.oxycblt.auxio
|
|
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import android.view.View
|
|
import androidx.activity.viewModels
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.appcompat.app.AppCompatDelegate
|
|
import androidx.core.view.WindowCompat
|
|
import androidx.core.view.updatePadding
|
|
import dagger.hilt.android.AndroidEntryPoint
|
|
import javax.inject.Inject
|
|
import org.oxycblt.auxio.databinding.ActivityMainBinding
|
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
|
import org.oxycblt.auxio.playback.state.DeferredPlayback
|
|
import org.oxycblt.auxio.service.AuxioService
|
|
import org.oxycblt.auxio.ui.UISettings
|
|
import org.oxycblt.auxio.util.isNight
|
|
import org.oxycblt.auxio.util.logD
|
|
import org.oxycblt.auxio.util.logW
|
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
|
|
|
/**
|
|
* Auxio's single [AppCompatActivity].
|
|
*
|
|
* @author Alexander Capehart (OxygenCobalt)
|
|
*
|
|
* TODO: Add error screens
|
|
* TODO: Custom language support
|
|
* TODO: Use proper material attributes (Not the weird dimen attributes I currently have)
|
|
* TODO: Migrate to material animation system
|
|
* TODO: Unit testing
|
|
* TODO: Fix UID naming
|
|
* TODO: Leverage FlexibleListAdapter more in dialogs (Disable item anims)
|
|
* TODO: Improve multi-threading support in shared objects
|
|
*/
|
|
@AndroidEntryPoint
|
|
class MainActivity : AppCompatActivity() {
|
|
private val playbackModel: PlaybackViewModel by viewModels()
|
|
@Inject lateinit var uiSettings: UISettings
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setupTheme()
|
|
// Inflate the views after setting up the theme so that the theme attributes are applied.
|
|
val binding = ActivityMainBinding.inflate(layoutInflater)
|
|
setContentView(binding.root)
|
|
setupEdgeToEdge(binding.root)
|
|
logD("Activity created")
|
|
}
|
|
|
|
override fun onResume() {
|
|
super.onResume()
|
|
|
|
startService(Intent(this, AuxioService::class.java))
|
|
|
|
if (!startIntentAction(intent)) {
|
|
// No intent action to do, just restore the previously saved state.
|
|
playbackModel.playDeferred(DeferredPlayback.RestoreState)
|
|
}
|
|
}
|
|
|
|
override fun onNewIntent(intent: Intent?) {
|
|
super.onNewIntent(intent)
|
|
startIntentAction(intent)
|
|
}
|
|
|
|
private fun setupTheme() {
|
|
// Apply the theme configuration.
|
|
AppCompatDelegate.setDefaultNightMode(uiSettings.theme)
|
|
// Apply the color scheme. The black theme requires it's own set of themes since
|
|
// it's not possible to modify the themes at run-time.
|
|
if (isNight && uiSettings.useBlackTheme) {
|
|
logD("Applying black theme [accent ${uiSettings.accent}]")
|
|
setTheme(uiSettings.accent.blackTheme)
|
|
} else {
|
|
logD("Applying normal theme [accent ${uiSettings.accent}]")
|
|
setTheme(uiSettings.accent.theme)
|
|
}
|
|
}
|
|
|
|
private fun setupEdgeToEdge(contentView: View) {
|
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
|
contentView.setOnApplyWindowInsetsListener { view, insets ->
|
|
// Automatically inset the view to the left/right, as component support for
|
|
// these insets are highly lacking.
|
|
val bars = insets.systemBarInsetsCompat
|
|
view.updatePadding(left = bars.left, right = bars.right)
|
|
insets
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Transform an [Intent] given to [MainActivity] into a [DeferredPlayback] that can be used in
|
|
* the playback system.
|
|
*
|
|
* @param intent The (new) [Intent] given to this [MainActivity], or null if there is no intent.
|
|
* @return true If the analogous [DeferredPlayback] to the given [Intent] was started, false
|
|
* otherwise.
|
|
*/
|
|
private fun startIntentAction(intent: Intent?): Boolean {
|
|
if (intent == null) {
|
|
// Nothing to do.
|
|
logD("No intent to handle")
|
|
return false
|
|
}
|
|
|
|
if (intent.getBooleanExtra(KEY_INTENT_USED, false)) {
|
|
// Don't commit the action, but also return that the intent was applied.
|
|
// This is because onStart can run multiple times, and thus we really don't
|
|
// want to return false and override the original delayed action with a
|
|
// RestoreState action.
|
|
logD("Already used this intent")
|
|
return true
|
|
}
|
|
intent.putExtra(KEY_INTENT_USED, true)
|
|
|
|
val action =
|
|
when (intent.action) {
|
|
Intent.ACTION_VIEW -> DeferredPlayback.Open(intent.data ?: return false)
|
|
Auxio.INTENT_KEY_SHORTCUT_SHUFFLE -> DeferredPlayback.ShuffleAll
|
|
else -> {
|
|
logW("Unexpected intent ${intent.action}")
|
|
return false
|
|
}
|
|
}
|
|
logD("Translated intent to $action")
|
|
playbackModel.playDeferred(action)
|
|
return true
|
|
}
|
|
|
|
private companion object {
|
|
const val KEY_INTENT_USED = BuildConfig.APPLICATION_ID + ".key.FILE_INTENT_USED"
|
|
}
|
|
}
|