diff options
author | 2025-03-12 20:03:02 -0700 | |
---|---|---|
committer | 2025-03-12 20:03:02 -0700 | |
commit | 7e9e9181e14b63c70f4e659c807d665625f7ee85 (patch) | |
tree | 5393fec2ce1e73ca34275b3a88075513f02ea445 | |
parent | 7969886b3e665ba6fae75e4de7bdf77ec230ed0a (diff) | |
parent | 33966c3f18ac584395edf2d00d159bc0a4339165 (diff) |
Merge "Determine when to show communal based on hub specific setting." into main
7 files changed, 140 insertions, 34 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt index f4a1c90a5471..95334b5aaf09 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt @@ -55,9 +55,11 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { fun setUp() { runBlocking { kosmos.fakeUserRepository.asMainUser() } with(kosmos.fakeSettings) { - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, false, MAIN_USER_ID) - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, false, MAIN_USER_ID) - putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, false, MAIN_USER_ID) + putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_NEVER, + MAIN_USER_ID, + ) } } @@ -67,9 +69,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING, MAIN_USER_ID, ) @@ -91,9 +93,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_DOCKED, MAIN_USER_ID, ) @@ -118,9 +120,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, - true, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT, MAIN_USER_ID, ) @@ -144,19 +146,9 @@ class CommunalAutoOpenInteractorTest : SysuiTestCase() { val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen) val suppressionReason by collectLastValue(underTest.suppressionReason) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, - false, - MAIN_USER_ID, - ) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, - false, - MAIN_USER_ID, - ) - fakeSettings.putBoolForUser( - Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, - false, + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_NEVER, MAIN_USER_ID, ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt index 310bf6486413..d6f7145bd770 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt @@ -21,10 +21,12 @@ import android.app.admin.devicePolicyManager import android.content.Intent import android.content.pm.UserInfo import android.os.UserManager +import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest @@ -32,6 +34,7 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository +import com.android.systemui.util.settings.fakeSettings import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull @@ -82,6 +85,19 @@ class CommunalSettingsInteractorTest : SysuiTestCase() { assertEquals(USER_INFO_WORK.id, disallowedUser!!.id) } + @Test + fun whenToStartHub_matchesRepository() = + kosmos.runTest { + fakeSettings.putIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + Settings.Secure.GLANCEABLE_HUB_START_CHARGING, + MAIN_USER_INFO.id, + ) + + val startCondition by collectLastValue(underTest.whenToStartHub) + assertEquals(startCondition, WhenToStartHub.WHILE_CHARGING) + } + private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever( kosmos.devicePolicyManager.getKeyguardDisabledFeatures( diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt index 6f688d172843..42a345b7deb4 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt @@ -32,6 +32,7 @@ import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule.Companion.DEFAULT_BACKGROUND_TYPE import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -64,6 +65,12 @@ interface CommunalSettingsRepository { */ fun getWhenToDreamState(user: UserInfo): Flow<WhenToDream> + /** + * Returns a[WhenToStartHub] for the specified user, indicating what state the device should be + * in to automatically display the hub. + */ + fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub> + /** Returns whether glanceable hub is enabled by the current user. */ fun getSettingEnabledByUser(user: UserInfo): Flow<Boolean> @@ -124,6 +131,10 @@ constructor( resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault) } + private val whenToStartHubByDefault by lazy { + resources.getInteger(com.android.internal.R.integer.config_whenToStartHubModeDefault) + } + private val _suppressionReasons = MutableStateFlow<List<SuppressionReason>>( // Suppress hub by default until we get an initial update. @@ -195,6 +206,31 @@ constructor( } .flowOn(bgDispatcher) + override fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub> = + secureSettings + .observerFlow( + userId = user.id, + names = arrayOf(Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB), + ) + .emitOnStart() + .map { + when ( + secureSettings.getIntForUser( + Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB, + whenToStartHubByDefault, + user.id, + ) + ) { + Settings.Secure.GLANCEABLE_HUB_START_NEVER -> WhenToStartHub.NEVER + Settings.Secure.GLANCEABLE_HUB_START_CHARGING -> WhenToStartHub.WHILE_CHARGING + Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT -> + WhenToStartHub.WHILE_CHARGING_AND_POSTURED + Settings.Secure.GLANCEABLE_HUB_START_DOCKED -> WhenToStartHub.WHILE_DOCKED + else -> WhenToStartHub.NEVER + } + } + .flowOn(bgDispatcher) + override fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> = broadcastDispatcher .broadcastFlow( diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt index 51df3338a18e..20bfabdc5fb9 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt @@ -22,7 +22,7 @@ import com.android.systemui.communal.data.model.FEATURE_AUTO_OPEN import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.posturing.domain.interactor.PosturingInteractor -import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dock.DockManager @@ -49,17 +49,17 @@ constructor( @Named(SWIPE_TO_HUB) private val allowSwipeAlways: Boolean, ) { val shouldAutoOpen: Flow<Boolean> = - communalSettingsInteractor.whenToDream - .flatMapLatestConflated { whenToDream -> - when (whenToDream) { - WhenToDream.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn - WhenToDream.WHILE_DOCKED -> { + communalSettingsInteractor.whenToStartHub + .flatMapLatestConflated { whenToStartHub -> + when (whenToStartHub) { + WhenToStartHub.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn + WhenToStartHub.WHILE_DOCKED -> { allOf(batteryInteractor.isDevicePluggedIn, dockManager.retrieveIsDocked()) } - WhenToDream.WHILE_POSTURED -> { + WhenToStartHub.WHILE_CHARGING_AND_POSTURED -> { allOf(batteryInteractor.isDevicePluggedIn, posturingInteractor.postured) } - WhenToDream.NEVER -> flowOf(false) + WhenToStartHub.NEVER -> flowOf(false) } } .flowOn(backgroundContext) diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt index 0d7a2d9707d7..cf51fa1b61fb 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt @@ -17,7 +17,6 @@ package com.android.systemui.communal.domain.interactor import android.content.pm.UserInfo -import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import com.android.systemui.communal.data.model.FEATURE_AUTO_OPEN import com.android.systemui.communal.data.model.FEATURE_ENABLED import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN @@ -25,10 +24,12 @@ import com.android.systemui.communal.data.model.SuppressionReason import com.android.systemui.communal.data.repository.CommunalSettingsRepository import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToDream +import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserTracker import com.android.systemui.user.domain.interactor.SelectedUserInteractor +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import java.util.concurrent.Executor import javax.inject.Inject @@ -79,6 +80,12 @@ constructor( repository.getWhenToDreamState(user) } + /** When to automatically start hub for the currently selected user. */ + val whenToStartHub: Flow<WhenToStartHub> = + userInteractor.selectedUserInfo.flatMapLatest { user -> + repository.getWhenToStartHubState(user) + } + /** Whether communal hub is allowed by device policy for the current user */ val allowedForCurrentUserByDevicePolicy: Flow<Boolean> = userInteractor.selectedUserInfo.flatMapLatestConflated { user -> diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt new file mode 100644 index 000000000000..be89fda01009 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 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.communal.shared.model + +enum class WhenToStartHub { + NEVER, + WHILE_CHARGING, + WHILE_CHARGING_AND_POSTURED, + WHILE_DOCKED, +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt index f31697e82a45..a6332bf9e3d7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt @@ -289,6 +289,37 @@ class FakeSettings : SecureSettings, SystemSettings, UserSettingsProxy { return putString(name, value) } + override fun getInt(name: String): Int { + return getIntForUser(name, userId) + } + + override fun getInt(name: String, default: Int): Int { + return getIntForUser(name, default, userId) + } + + override fun getIntForUser(name: String, userHandle: Int): Int { + return getIntForUser(name, 0, userHandle) + } + + override fun getIntForUser(name: String, default: Int, userHandle: Int): Int { + return values[SettingsKey(userHandle, getUriFor(name).toString())]?.toInt() ?: default + } + + override fun putIntForUser(name: String, value: Int, userHandle: Int): Boolean { + val key = SettingsKey(userHandle, getUriFor(name).toString()) + values[key] = value.toString() + val uri = getUriFor(name) + contentObservers[key]?.onEach { it.dispatchChange(false, listOf(uri), 0, userHandle) } + contentObserversAllUsers[uri.toString()]?.onEach { + it.dispatchChange(false, listOf(uri), 0, userHandle) + } + return true + } + + override fun putInt(name: String, value: Int): Boolean { + return putIntForUser(name, value, userId) + } + /** Runs current jobs on dispatcher after calling the method. */ private fun <T> advanceDispatcher(f: () -> T): T { val result = f() |