blob: 109be40ce10ff013a3ae8df75448585f86149418 [file] [log] [blame]
package com.android.systemui
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.FlagListenable
import com.android.systemui.flags.Flags
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
@SysUISingleton
class ChooserSelector @Inject constructor(
context: Context,
private val featureFlags: FeatureFlags,
@Application private val coroutineScope: CoroutineScope,
@Background private val bgDispatcher: CoroutineDispatcher
) : CoreStartable(context) {
private val packageManager = context.packageManager
private val chooserComponent = ComponentName.unflattenFromString(
context.resources.getString(ChooserSelectorResourceHelper.CONFIG_CHOOSER_ACTIVITY))
override fun start() {
coroutineScope.launch {
val listener = FlagListenable.Listener { event ->
if (event.flagId == Flags.CHOOSER_UNBUNDLED.id) {
launch { updateUnbundledChooserEnabled() }
event.requestNoRestart()
}
}
featureFlags.addListener(Flags.CHOOSER_UNBUNDLED, listener)
updateUnbundledChooserEnabled()
awaitCancellationAndThen { featureFlags.removeListener(listener) }
}
}
private suspend fun updateUnbundledChooserEnabled() {
setUnbundledChooserEnabled(withContext(bgDispatcher) {
featureFlags.isEnabled(Flags.CHOOSER_UNBUNDLED)
})
}
private fun setUnbundledChooserEnabled(enabled: Boolean) {
val newState = if (enabled) {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
} else {
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
}
packageManager.setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0)
}
suspend inline fun awaitCancellation(): Nothing = suspendCancellableCoroutine { }
suspend inline fun awaitCancellationAndThen(block: () -> Unit): Nothing = try {
awaitCancellation()
} finally {
block()
}
}