Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1522bcc authored by Jan Lanik's avatar Jan Lanik
Browse files

Disable animation if using new chip style

When we are using the new status bar chip for privacy indicators, we
disable the olde animation.

Flag: com.android.systemui.expanded_privacy_indicators_on_large_screen
Test: Manual verification
Bug: 394074664
Change-Id: I44162ed5d7a0a25d57b79875d4f51c02d4864064
parent 5e0e9c9c
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.PendingDisplay
import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.statusbar.featurepods.vc.domain.interactor.AvControlsChipInteractor
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
@@ -50,9 +51,11 @@ class SystemEventCoordinatorTest : SysuiTestCase() {

    @Mock lateinit var batteryController: BatteryController
    @Mock lateinit var privacyController: PrivacyItemController
    @Mock lateinit var avControlsChipInteractor: AvControlsChipInteractor
    @Mock lateinit var scheduler: SystemStatusAnimationScheduler

    private lateinit var systemEventCoordinator: SystemEventCoordinator

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
@@ -61,9 +64,10 @@ class SystemEventCoordinatorTest : SysuiTestCase() {
                    fakeSystemClock,
                    batteryController,
                    privacyController,
                    avControlsChipInteractor,
                    context,
                    TestScope(UnconfinedTestDispatcher()),
                    connectedDisplayInteractor
                    connectedDisplayInteractor,
                )
                .apply { attachScheduler(scheduler) }
    }
@@ -97,13 +101,18 @@ class SystemEventCoordinatorTest : SysuiTestCase() {

    class FakeConnectedDisplayInteractor : ConnectedDisplayInteractor {
        private val flow = MutableSharedFlow<Unit>()

        suspend fun emit() = flow.emit(Unit)

        override val connectedDisplayState: Flow<ConnectedDisplayInteractor.State>
            get() = MutableSharedFlow<ConnectedDisplayInteractor.State>()

        override val connectedDisplayAddition: Flow<Unit>
            get() = flow

        override val pendingDisplay: Flow<PendingDisplay?>
            get() = MutableSharedFlow<PendingDisplay>()

        override val concurrentDisplaysInProgress: Flow<Boolean>
            get() = TODO("Not yet implemented")
    }
+78 −67
Original line number Diff line number Diff line
@@ -20,14 +20,14 @@ import android.annotation.IntRange
import android.content.Context
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_PRIVACY
import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor.State
import com.android.systemui.privacy.PrivacyChipBuilder
import com.android.systemui.privacy.PrivacyItem
import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.res.R
import com.android.systemui.statusbar.featurepods.vc.domain.interactor.AvControlsChipInteractor
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
@@ -47,12 +47,12 @@ constructor(
    private val systemClock: SystemClock,
    private val batteryController: BatteryController,
    private val privacyController: PrivacyItemController,
    private val avControlsChipInteractor: AvControlsChipInteractor,
    private val context: Context,
    @Application private val appScope: CoroutineScope,
    connectedDisplayInteractor: ConnectedDisplayInteractor
    connectedDisplayInteractor: ConnectedDisplayInteractor,
) {
    private val onDisplayConnectedFlow =
        connectedDisplayInteractor.connectedDisplayAddition
    private val onDisplayConnectedFlow = connectedDisplayInteractor.connectedDisplayAddition

    private var connectedDisplayCollectionJob: Job? = null
    private lateinit var scheduler: SystemStatusAnimationScheduler
@@ -82,18 +82,21 @@ constructor(
    }

    fun notifyPrivacyItemsChanged(showAnimation: Boolean = true) {
        val event = PrivacyEvent(showAnimation)
        // Disabling animation in case that the privacy indicator is implemented as a status bar
        // chip
        val shouldShowAnimation = showAnimation && !avControlsChipInteractor.isEnabled.value
        val event = PrivacyEvent(shouldShowAnimation)
        event.privacyItems = privacyStateListener.currentPrivacyItems
        event.contentDescription = run {
            val items = PrivacyChipBuilder(context, event.privacyItems).joinTypes()
            context.getString(
                    R.string.ongoing_privacy_chip_content_multiple_apps, items)
            context.getString(R.string.ongoing_privacy_chip_content_multiple_apps, items)
        }
        scheduler.onStatusEvent(event)
    }

    private fun startConnectedDisplayCollection() {
        val connectedDisplayEvent = ConnectedDisplayEvent().apply {
        val connectedDisplayEvent =
            ConnectedDisplayEvent().apply {
                contentDescription = context.getString(R.string.connected_display_icon_desc)
            }
        connectedDisplayCollectionJob =
@@ -102,9 +105,11 @@ constructor(
                .launchIn(appScope)
    }

    private val batteryStateListener = object : BatteryController.BatteryStateChangeCallback {
    private val batteryStateListener =
        object : BatteryController.BatteryStateChangeCallback {
            private var plugged = false
            private var stateKnown = false

            override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
                if (!stateKnown) {
                    stateKnown = true
@@ -125,7 +130,8 @@ constructor(
            }
        }

    private val privacyStateListener = object : PrivacyItemController.Callback {
    private val privacyStateListener =
        object : PrivacyItemController.Callback {
            var currentPrivacyItems = listOf<PrivacyItem>()
            var previousPrivacyItems = listOf<PrivacyItem>()
            var timeLastEmpty = systemClock.elapsedRealtime()
@@ -146,7 +152,8 @@ constructor(
                if (currentPrivacyItems.isEmpty()) {
                    notifyPrivacyItemsEmpty()
                } else {
                val showAnimation = isChipAnimationEnabled() &&
                    val showAnimation =
                        isChipAnimationEnabled() &&
                            (!uniqueItemsMatch(currentPrivacyItems, previousPrivacyItems) ||
                                systemClock.elapsedRealtime() - timeLastEmpty >= DEBOUNCE_TIME)
                    notifyPrivacyItemsChanged(showAnimation)
@@ -162,7 +169,11 @@ constructor(
            private fun isChipAnimationEnabled(): Boolean {
                val defaultValue =
                    context.resources.getBoolean(R.bool.config_enablePrivacyChipAnimation)
            return DeviceConfig.getBoolean(NAMESPACE_PRIVACY, CHIP_ANIMATION_ENABLED, defaultValue)
                return DeviceConfig.getBoolean(
                    NAMESPACE_PRIVACY,
                    CHIP_ANIMATION_ENABLED,
                    defaultValue,
                )
            }
        }
}
+4 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.statusbar.featurepods.vc.shared.model.AvControlsChip
import com.android.systemui.statusbar.featurepods.vc.shared.model.SensorActivityModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine

/**
@@ -37,8 +38,8 @@ import kotlinx.coroutines.flow.combine
 */
@SysUISingleton
class AvControlsChipInteractor @Inject constructor(privacyChipRepository: PrivacyChipRepository) {
    private val isEnabled = MutableStateFlow(false)

    private val _isEnabled = MutableStateFlow(false)
    val isEnabled = _isEnabled.asStateFlow()
    val model =
        combine(isEnabled, privacyChipRepository.privacyItems) { isEnabled, privacyItems ->
            if (isEnabled) createModel(privacyItems)
@@ -75,6 +76,6 @@ class AvControlsChipInteractor @Inject constructor(privacyChipRepository: Privac
     * factors should initialize the interactor. This must be called from a CoreStartable.
     */
    fun initialize() {
        isEnabled.value = Flags.expandedPrivacyIndicatorsOnLargeScreen()
        _isEnabled.value = Flags.expandedPrivacyIndicatorsOnLargeScreen()
    }
}