diff options
10 files changed, 10 insertions, 612 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 36a9fdef8b39..8e9992fdd296 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -30,7 +30,6 @@ import com.android.systemui.dagger.qualifiers.PerUser import com.android.systemui.globalactions.GlobalActionsComponent import com.android.systemui.keyboard.KeyboardUI import com.android.systemui.keyguard.KeyguardViewMediator -import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable import com.android.systemui.log.SessionTracker import com.android.systemui.media.dialog.MediaOutputSwitcherDialogUI import com.android.systemui.media.RingtonePlayer @@ -287,12 +286,4 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(StylusUsiPowerStartable::class) abstract fun bindStylusUsiPowerStartable(sysui: StylusUsiPowerStartable): CoreStartable - - /** Inject into MuteQuickAffordanceCoreStartable*/ - @Binds - @IntoMap - @ClassKey(MuteQuickAffordanceCoreStartable::class) - abstract fun bindMuteQuickAffordanceCoreStartable( - sysui: MuteQuickAffordanceCoreStartable - ): CoreStartable } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt index 80675d373b8e..76c2430e37ad 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt @@ -29,7 +29,6 @@ object BuiltInKeyguardQuickAffordanceKeys { const val DO_NOT_DISTURB = "do_not_disturb" const val FLASHLIGHT = "flashlight" const val HOME_CONTROLS = "home" - const val MUTE = "mute" const val QR_CODE_SCANNER = "qr_code_scanner" const val QUICK_ACCESS_WALLET = "wallet" const val VIDEO_CAMERA = "video_camera" diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt index 45561959a7df..a1cce5c670ba 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt @@ -33,13 +33,12 @@ interface KeyguardDataQuickAffordanceModule { @Provides @ElementsIntoSet fun quickAffordanceConfigs( - camera: CameraQuickAffordanceConfig, doNotDisturb: DoNotDisturbQuickAffordanceConfig, flashlight: FlashlightQuickAffordanceConfig, home: HomeControlsKeyguardQuickAffordanceConfig, - mute: MuteQuickAffordanceConfig, quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig, qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig, + camera: CameraQuickAffordanceConfig, videoCamera: VideoCameraQuickAffordanceConfig, ): Set<KeyguardQuickAffordanceConfig> { return setOf( @@ -47,7 +46,6 @@ interface KeyguardDataQuickAffordanceModule { doNotDisturb, flashlight, home, - mute, quickAccessWallet, qrCodeScanner, videoCamera, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt deleted file mode 100644 index d085db9a1eda..000000000000 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.android.systemui.keyguard.data.quickaffordance - -import android.content.Context -import android.media.AudioManager -import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer -import com.android.systemui.R -import com.android.systemui.animation.Expandable -import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow -import com.android.systemui.common.shared.model.ContentDescription -import com.android.systemui.common.shared.model.Icon -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.keyguard.shared.quickaffordance.ActivationState -import com.android.systemui.settings.UserFileManager -import com.android.systemui.settings.UserTracker -import com.android.systemui.util.RingerModeTracker -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.onStart -import javax.inject.Inject - -@SysUISingleton -class MuteQuickAffordanceConfig @Inject constructor( - context: Context, - private val userTracker: UserTracker, - private val userFileManager: UserFileManager, - private val ringerModeTracker: RingerModeTracker, - private val audioManager: AudioManager, -) : KeyguardQuickAffordanceConfig { - - private var previousNonSilentMode: Int = DEFAULT_LAST_NON_SILENT_VALUE - - override val key: String = BuiltInKeyguardQuickAffordanceKeys.MUTE - - override val pickerName: String = context.getString(R.string.volume_ringer_status_silent) - - override val pickerIconResourceId: Int = R.drawable.ic_notifications_silence - - override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> = - ringerModeTracker.ringerModeInternal.asFlow() - .onStart { emit(getLastNonSilentRingerMode()) } - .distinctUntilChanged() - .onEach { mode -> - // only remember last non-SILENT ringer mode - if (mode != null && mode != AudioManager.RINGER_MODE_SILENT) { - previousNonSilentMode = mode - } - } - .map { mode -> - val (activationState, contentDescriptionRes) = when { - audioManager.isVolumeFixed -> - ActivationState.NotSupported to - R.string.volume_ringer_hint_mute - mode == AudioManager.RINGER_MODE_SILENT -> - ActivationState.Active to - R.string.volume_ringer_hint_mute - else -> - ActivationState.Inactive to - R.string.volume_ringer_hint_unmute - } - - KeyguardQuickAffordanceConfig.LockScreenState.Visible( - Icon.Resource( - R.drawable.ic_notifications_silence, - ContentDescription.Resource(contentDescriptionRes), - ), - activationState, - ) - } - - override fun onTriggered( - expandable: Expandable? - ): KeyguardQuickAffordanceConfig.OnTriggeredResult { - val newRingerMode: Int - val currentRingerMode = - ringerModeTracker.ringerModeInternal.value ?: DEFAULT_LAST_NON_SILENT_VALUE - if (currentRingerMode == AudioManager.RINGER_MODE_SILENT) { - newRingerMode = previousNonSilentMode - } else { - previousNonSilentMode = currentRingerMode - newRingerMode = AudioManager.RINGER_MODE_SILENT - } - - if (currentRingerMode != newRingerMode) { - audioManager.ringerModeInternal = newRingerMode - } - return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled - } - - override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState = - if (audioManager.isVolumeFixed) { - KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice - } else { - KeyguardQuickAffordanceConfig.PickerScreenState.Default() - } - - /** - * Gets the last non-silent ringer mode from shared-preferences if it exists. This is - * cached by [MuteQuickAffordanceCoreStartable] while this affordance is selected - */ - private fun getLastNonSilentRingerMode(): Int = - userFileManager.getSharedPreferences( - MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME, - Context.MODE_PRIVATE, - userTracker.userId - ).getInt( - LAST_NON_SILENT_RINGER_MODE_KEY, - ringerModeTracker.ringerModeInternal.value ?: DEFAULT_LAST_NON_SILENT_VALUE - ) - - private fun <T> LiveData<T>.asFlow(): Flow<T?> = - conflatedCallbackFlow { - val observer = Observer { value: T -> trySend(value) } - observeForever(observer) - send(value) - awaitClose { removeObserver(observer) } - } - - companion object { - const val LAST_NON_SILENT_RINGER_MODE_KEY = "key_last_non_silent_ringer_mode" - const val MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME = "quick_affordance_mute_ringer_mode_cache" - private const val DEFAULT_LAST_NON_SILENT_VALUE = AudioManager.RINGER_MODE_NORMAL - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt deleted file mode 100644 index 12a6310ccc85..000000000000 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartable.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.android.systemui.keyguard.data.quickaffordance - -import android.content.Context -import android.media.AudioManager -import androidx.lifecycle.Observer -import com.android.systemui.CoreStartable -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags -import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository -import com.android.systemui.settings.UserFileManager -import com.android.systemui.settings.UserTracker -import com.android.systemui.util.RingerModeTracker -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import javax.inject.Inject - -/** - * Store previous non-silent Ringer Mode into shared prefs to be used for Mute Lockscreen Shortcut - */ -@SysUISingleton -class MuteQuickAffordanceCoreStartable @Inject constructor( - private val featureFlags: FeatureFlags, - private val userTracker: UserTracker, - private val ringerModeTracker: RingerModeTracker, - private val userFileManager: UserFileManager, - private val keyguardQuickAffordanceRepository: KeyguardQuickAffordanceRepository, - @Application private val coroutineScope: CoroutineScope, -) : CoreStartable { - - private val observer = Observer(this::updateLastNonSilentRingerMode) - - override fun start() { - if (!featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)) return - - // only listen to ringerModeInternal changes when Mute is one of the selected affordances - keyguardQuickAffordanceRepository - .selections - .map { selections -> - // determines if Mute is selected in any lockscreen shortcut position - val muteSelected: Boolean = selections.values.any { configList -> - configList.any { config -> - config.key == BuiltInKeyguardQuickAffordanceKeys.MUTE - } - } - if (muteSelected) { - ringerModeTracker.ringerModeInternal.observeForever(observer) - } else { - ringerModeTracker.ringerModeInternal.removeObserver(observer) - } - } - .launchIn(coroutineScope) - } - - private fun updateLastNonSilentRingerMode(lastRingerMode: Int) { - if (AudioManager.RINGER_MODE_SILENT != lastRingerMode) { - userFileManager.getSharedPreferences( - MuteQuickAffordanceConfig.MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME, - Context.MODE_PRIVATE, - userTracker.userId - ) - .edit() - .putInt(MuteQuickAffordanceConfig.LAST_NON_SILENT_RINGER_MODE_KEY, lastRingerMode) - .apply() - } - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt index 8ece3183fd56..2b2b9d0703fa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt @@ -146,7 +146,7 @@ constructor( * Returns a snapshot of the [KeyguardQuickAffordanceConfig] instances of the affordances at the * slot with the given ID. The configs are sorted in descending priority order. */ - fun getCurrentSelections(slotId: String): List<KeyguardQuickAffordanceConfig> { + fun getSelections(slotId: String): List<KeyguardQuickAffordanceConfig> { val selections = selectionManager.value.getSelections().getOrDefault(slotId, emptyList()) return configs.filter { selections.contains(it.key) } } @@ -155,7 +155,7 @@ constructor( * Returns a snapshot of the IDs of the selected affordances, indexed by slot ID. The configs * are sorted in descending priority order. */ - fun getCurrentSelections(): Map<String, List<String>> { + fun getSelections(): Map<String, List<String>> { return selectionManager.value.getSelections() } @@ -217,7 +217,7 @@ constructor( private inner class Dumpster : Dumpable { override fun dump(pw: PrintWriter, args: Array<out String>) { val slotPickerRepresentations = getSlotPickerRepresentations() - val selectionsBySlotId = getCurrentSelections() + val selectionsBySlotId = getSelections() pw.println("Slots & selections:") slotPickerRepresentations.forEach { slotPickerRepresentation -> val slotId = slotPickerRepresentation.id diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt index 4ccb99d4654b..c219380ad263 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt @@ -154,7 +154,7 @@ constructor( val slots = repository.get().getSlotPickerRepresentations() val slot = slots.find { it.id == slotId } ?: return false val selections = - repository.get().getCurrentSelections().getOrDefault(slotId, emptyList()).toMutableList() + repository.get().getSelections().getOrDefault(slotId, emptyList()).toMutableList() val alreadySelected = selections.remove(affordanceId) if (!alreadySelected) { while (selections.size > 0 && selections.size >= slot.maxSelectedAffordances) { @@ -193,7 +193,7 @@ constructor( if (affordanceId.isNullOrEmpty()) { return if ( - repository.get().getCurrentSelections().getOrDefault(slotId, emptyList()).isEmpty() + repository.get().getSelections().getOrDefault(slotId, emptyList()).isEmpty() ) { false } else { @@ -203,7 +203,7 @@ constructor( } val selections = - repository.get().getCurrentSelections().getOrDefault(slotId, emptyList()).toMutableList() + repository.get().getSelections().getOrDefault(slotId, emptyList()).toMutableList() return if (selections.remove(affordanceId)) { repository .get() @@ -220,7 +220,7 @@ constructor( /** Returns affordance IDs indexed by slot ID, for all known slots. */ suspend fun getSelections(): Map<String, List<KeyguardQuickAffordancePickerRepresentation>> { val slots = repository.get().getSlotPickerRepresentations() - val selections = repository.get().getCurrentSelections() + val selections = repository.get().getSelections() val affordanceById = getAffordancePickerRepresentations().associateBy { affordance -> affordance.id } return slots.associate { slot -> diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt deleted file mode 100644 index a3740d88e1a9..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.android.systemui.keyguard.data.quickaffordance - -import android.content.Context -import android.media.AudioManager -import androidx.lifecycle.LiveData -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.settings.UserFileManager -import com.android.systemui.settings.UserTracker -import com.android.systemui.util.RingerModeTracker -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.runTest -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.mockito.Mock -import org.mockito.Mockito.times -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations - -@OptIn(ExperimentalCoroutinesApi::class) -@SmallTest -@RunWith(JUnit4::class) -class MuteQuickAffordanceConfigTest : SysuiTestCase() { - - private lateinit var underTest: MuteQuickAffordanceConfig - @Mock - private lateinit var ringerModeTracker: RingerModeTracker - @Mock - private lateinit var audioManager: AudioManager - @Mock - private lateinit var userTracker: UserTracker - @Mock - private lateinit var userFileManager: UserFileManager - - private lateinit var testScope: TestScope - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - - testScope = TestScope() - - whenever(userTracker.userContext).thenReturn(context) - whenever(userFileManager.getSharedPreferences(any(), any(), any())) - .thenReturn(context.getSharedPreferences("mutequickaffordancetest", Context.MODE_PRIVATE)) - - underTest = MuteQuickAffordanceConfig( - context, - userTracker, - userFileManager, - ringerModeTracker, - audioManager - ) - } - - @Test - fun `picker state - volume fixed - not available`() = testScope.runTest { - //given - whenever(audioManager.isVolumeFixed).thenReturn(true) - - //when - val result = underTest.getPickerScreenState() - - //then - assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice, result) - } - - @Test - fun `picker state - volume not fixed - available`() = testScope.runTest { - //given - whenever(audioManager.isVolumeFixed).thenReturn(false) - - //when - val result = underTest.getPickerScreenState() - - //then - assertEquals(KeyguardQuickAffordanceConfig.PickerScreenState.Default(), result) - } - - @Test - fun `triggered - state was previously NORMAL - currently SILENT - move to previous state`() { - //given - val ringerModeCapture = argumentCaptor<Int>() - val ringerModeInternal = mock<LiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - whenever(ringerModeInternal.value).thenReturn(AudioManager.RINGER_MODE_NORMAL) - underTest.onTriggered(null) - whenever(ringerModeInternal.value).thenReturn(AudioManager.RINGER_MODE_SILENT) - - //when - val result = underTest.onTriggered(null) - verify(audioManager, times(2)).ringerModeInternal = ringerModeCapture.capture() - - //then - assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result) - assertEquals(AudioManager.RINGER_MODE_NORMAL, ringerModeCapture.value) - } - - @Test - fun `triggered - state is not SILENT - move to SILENT ringer`() { - //given - val ringerModeCapture = argumentCaptor<Int>() - val ringerModeInternal = mock<LiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - whenever(ringerModeInternal.value).thenReturn(AudioManager.RINGER_MODE_NORMAL) - - //when - val result = underTest.onTriggered(null) - verify(audioManager).ringerModeInternal = ringerModeCapture.capture() - - //then - assertEquals(KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled, result) - assertEquals(AudioManager.RINGER_MODE_SILENT, ringerModeCapture.value) - } -}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt deleted file mode 100644 index 26601b63e02d..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.android.systemui.keyguard.data.quickaffordance - -import android.content.Context -import android.media.AudioManager -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.Observer -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags -import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository -import com.android.systemui.settings.UserFileManager -import com.android.systemui.settings.UserTracker -import com.android.systemui.util.RingerModeTracker -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor -import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.cancelChildren -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.runCurrent -import kotlinx.coroutines.test.runTest -import org.junit.Assert.assertEquals - -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.MockitoAnnotations - -@OptIn(ExperimentalCoroutinesApi::class) -@SmallTest -@RunWith(JUnit4::class) -class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() { - - @Mock - private lateinit var featureFlags: FeatureFlags - @Mock - private lateinit var userTracker: UserTracker - @Mock - private lateinit var ringerModeTracker: RingerModeTracker - @Mock - private lateinit var userFileManager: UserFileManager - @Mock - private lateinit var keyguardQuickAffordanceRepository: KeyguardQuickAffordanceRepository - - private lateinit var testScope: TestScope - - private lateinit var underTest: MuteQuickAffordanceCoreStartable - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - - whenever(featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)).thenReturn(true) - - val config: KeyguardQuickAffordanceConfig = mock() - whenever(config.key).thenReturn(BuiltInKeyguardQuickAffordanceKeys.MUTE) - - val emission = MutableStateFlow(mapOf("testQuickAffordanceKey" to listOf(config))) - whenever(keyguardQuickAffordanceRepository.selections).thenReturn(emission) - - testScope = TestScope() - - underTest = MuteQuickAffordanceCoreStartable( - featureFlags, - userTracker, - ringerModeTracker, - userFileManager, - keyguardQuickAffordanceRepository, - testScope, - ) - } - - @Test - fun `feature flag is OFF - do nothing with keyguardQuickAffordanceRepository`() = testScope.runTest { - //given - whenever(featureFlags.isEnabled(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES)).thenReturn(false) - - //when - underTest.start() - - //then - verifyZeroInteractions(keyguardQuickAffordanceRepository) - coroutineContext.cancelChildren() - } - - @Test - fun `feature flag is ON - call to keyguardQuickAffordanceRepository`() = testScope.runTest { - //given - val ringerModeInternal = mock<MutableLiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - - //when - underTest.start() - runCurrent() - - //then - verify(keyguardQuickAffordanceRepository).selections - coroutineContext.cancelChildren() - } - - @Test - fun `ringer mode is changed to SILENT - do not save to shared preferences`() = testScope.runTest { - //given - val ringerModeInternal = mock<MutableLiveData<Int>>() - val observerCaptor = argumentCaptor<Observer<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - - //when - underTest.start() - runCurrent() - verify(ringerModeInternal).observeForever(observerCaptor.capture()) - observerCaptor.value.onChanged(AudioManager.RINGER_MODE_SILENT) - - //then - verifyZeroInteractions(userFileManager) - coroutineContext.cancelChildren() - } - - @Test - fun `ringerModeInternal changes to something not SILENT - is set in sharedpreferences`() = testScope.runTest { - //given - val newRingerMode = 99 - val observerCaptor = argumentCaptor<Observer<Int>>() - val ringerModeInternal = mock<MutableLiveData<Int>>() - val sharedPrefs = context.getSharedPreferences("quick_affordance_mute_ringer_mode_cache_test", Context.MODE_PRIVATE) - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - whenever( - userFileManager.getSharedPreferences(eq("quick_affordance_mute_ringer_mode_cache"), any(), any()) - ).thenReturn(sharedPrefs) - - //when - underTest.start() - runCurrent() - verify(ringerModeInternal).observeForever(observerCaptor.capture()) - observerCaptor.value.onChanged(newRingerMode) - val result = sharedPrefs.getInt("key_last_non_silent_ringer_mode", -1) - - //then - assertEquals(newRingerMode, result) - coroutineContext.cancelChildren() - } - - @Test - fun `MUTE is in selections - observe ringerModeInternal`() = testScope.runTest { - //given - val ringerModeInternal = mock<MutableLiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - - //when - underTest.start() - runCurrent() - - //then - verify(ringerModeInternal).observeForever(any()) - coroutineContext.cancelChildren() - } - - @Test - fun `MUTE is in selections 2x - observe ringerModeInternal`() = testScope.runTest { - //given - val config: KeyguardQuickAffordanceConfig = mock() - whenever(config.key).thenReturn(BuiltInKeyguardQuickAffordanceKeys.MUTE) - val emission = MutableStateFlow(mapOf("testKey" to listOf(config), "testkey2" to listOf(config))) - whenever(keyguardQuickAffordanceRepository.selections).thenReturn(emission) - val ringerModeInternal = mock<MutableLiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - - //when - underTest.start() - runCurrent() - - //then - verify(ringerModeInternal).observeForever(any()) - coroutineContext.cancelChildren() - } - - @Test - fun `MUTE is not in selections - stop observing ringerModeInternal`() = testScope.runTest { - //given - val config: KeyguardQuickAffordanceConfig = mock() - whenever(config.key).thenReturn("notmutequickaffordance") - val emission = MutableStateFlow(mapOf("testKey" to listOf(config))) - whenever(keyguardQuickAffordanceRepository.selections).thenReturn(emission) - val ringerModeInternal = mock<MutableLiveData<Int>>() - whenever(ringerModeTracker.ringerModeInternal).thenReturn(ringerModeInternal) - - //when - underTest.start() - runCurrent() - - //then - verify(ringerModeInternal).removeObserver(any()) - coroutineContext.cancelChildren() - } -}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt index 6099f011a90d..b071a028865d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt @@ -275,10 +275,10 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() { expected: Map<String, List<KeyguardQuickAffordanceConfig>>, ) { assertThat(observed).isEqualTo(expected) - assertThat(underTest.getCurrentSelections()) + assertThat(underTest.getSelections()) .isEqualTo(expected.mapValues { (_, configs) -> configs.map { it.key } }) expected.forEach { (slotId, configs) -> - assertThat(underTest.getCurrentSelections(slotId)).isEqualTo(configs) + assertThat(underTest.getSelections(slotId)).isEqualTo(configs) } } |