Merge "[flexiglass] Fixes back navigation." into udc-qpr-dev

This commit is contained in:
Ale Nijamkin
2023-07-21 14:16:21 +00:00
committed by Android (Google) Code Review
4 changed files with 164 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
/*
* Copyright 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.model
import com.android.systemui.dagger.qualifiers.DisplayId
/**
* In-bulk updates multiple flag values and commits the update.
*
* Example:
* ```
* sysuiState.updateFlags(
* displayId,
* SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to (sceneKey != SceneKey.Gone),
* SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to (sceneKey == SceneKey.Shade),
* SYSUI_STATE_QUICK_SETTINGS_EXPANDED to (sceneKey == SceneKey.QuickSettings),
* SYSUI_STATE_BOUNCER_SHOWING to (sceneKey == SceneKey.Bouncer),
* SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to (sceneKey == SceneKey.Lockscreen),
* )
* ```
*
* You can inject [displayId] by injecting it using:
* ```
* @DisplayId private val displayId: Int`,
* ```
*/
fun SysUiState.updateFlags(
@DisplayId displayId: Int,
vararg flagValuePairs: Pair<Int, Boolean>,
) {
flagValuePairs.forEach { (flag, enabled) -> setFlag(flag, enabled) }
commitUpdate(displayId)
}

View File

@@ -20,14 +20,22 @@ import com.android.systemui.CoreStartable
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.DisplayId
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState
import com.android.systemui.model.updateFlags
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@@ -49,12 +57,15 @@ constructor(
private val authenticationInteractor: AuthenticationInteractor, private val authenticationInteractor: AuthenticationInteractor,
private val keyguardInteractor: KeyguardInteractor, private val keyguardInteractor: KeyguardInteractor,
private val featureFlags: FeatureFlags, private val featureFlags: FeatureFlags,
private val sysUiState: SysUiState,
@DisplayId private val displayId: Int,
) : CoreStartable { ) : CoreStartable {
override fun start() { override fun start() {
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) { if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
hydrateVisibility() hydrateVisibility()
automaticallySwitchScenes() automaticallySwitchScenes()
hydrateSystemUiState()
} }
} }
@@ -121,6 +132,27 @@ constructor(
} }
} }
/** Keeps [SysUiState] up-to-date */
private fun hydrateSystemUiState() {
applicationScope.launch {
sceneInteractor
.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT)
.map { it.key }
.distinctUntilChanged()
.collect { sceneKey ->
sysUiState.updateFlags(
displayId,
SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to (sceneKey != SceneKey.Gone),
SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to (sceneKey == SceneKey.Shade),
SYSUI_STATE_QUICK_SETTINGS_EXPANDED to (sceneKey == SceneKey.QuickSettings),
SYSUI_STATE_BOUNCER_SHOWING to (sceneKey == SceneKey.Bouncer),
SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to
(sceneKey == SceneKey.Lockscreen),
)
}
}
}
private fun switchToScene(targetSceneKey: SceneKey) { private fun switchToScene(targetSceneKey: SceneKey) {
sceneInteractor.setCurrentScene( sceneInteractor.setCurrentScene(
containerName = CONTAINER_NAME, containerName = CONTAINER_NAME,

View File

@@ -0,0 +1,47 @@
/*
* Copyright 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.model
import android.view.Display
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeDisplayTracker
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@SmallTest
@RunWith(JUnit4::class)
class SysUiStateExtTest : SysuiTestCase() {
private val underTest = SysUiState(FakeDisplayTracker(context))
@Test
fun updateFlags() {
underTest.updateFlags(
Display.DEFAULT_DISPLAY,
1 to true,
2 to false,
3 to true,
)
assertThat(underTest.flags and 1).isNotEqualTo(0)
assertThat(underTest.flags and 2).isEqualTo(0)
assertThat(underTest.flags and 3).isNotEqualTo(0)
}
}

View File

@@ -14,8 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
@file:OptIn(ExperimentalCoroutinesApi::class)
package com.android.systemui.scene.domain.startable package com.android.systemui.scene.domain.startable
import android.view.Display
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
@@ -23,17 +26,24 @@ import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.WakeSleepReason import com.android.systemui.keyguard.shared.model.WakeSleepReason
import com.android.systemui.keyguard.shared.model.WakefulnessModel import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.junit.runners.JUnit4 import org.junit.runners.JUnit4
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@SmallTest @SmallTest
@RunWith(JUnit4::class) @RunWith(JUnit4::class)
@@ -53,6 +63,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
utils.keyguardInteractor( utils.keyguardInteractor(
repository = keyguardRepository, repository = keyguardRepository,
) )
private val sysUiState: SysUiState = mock()
private val underTest = private val underTest =
SystemUiDefaultSceneContainerStartable( SystemUiDefaultSceneContainerStartable(
@@ -61,6 +72,8 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
authenticationInteractor = authenticationInteractor, authenticationInteractor = authenticationInteractor,
keyguardInteractor = keyguardInteractor, keyguardInteractor = keyguardInteractor,
featureFlags = featureFlags, featureFlags = featureFlags,
sysUiState = sysUiState,
displayId = Display.DEFAULT_DISPLAY,
) )
@Before @Before
@@ -375,6 +388,31 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
assertThat(currentSceneKey).isEqualTo(SceneKey.Shade) assertThat(currentSceneKey).isEqualTo(SceneKey.Shade)
} }
@Test
fun hydrateSystemUiState() =
testScope.runTest {
underTest.start()
runCurrent()
clearInvocations(sysUiState)
listOf(
SceneKey.Gone,
SceneKey.Lockscreen,
SceneKey.Bouncer,
SceneKey.Shade,
SceneKey.QuickSettings,
)
.forEachIndexed { index, sceneKey ->
sceneInteractor.setCurrentScene(
SceneContainerNames.SYSTEM_UI_DEFAULT,
SceneModel(sceneKey),
)
runCurrent()
verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY)
}
}
private fun prepareState( private fun prepareState(
isFeatureEnabled: Boolean = true, isFeatureEnabled: Boolean = true,
isDeviceUnlocked: Boolean = false, isDeviceUnlocked: Boolean = false,