Loading packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +63 −41 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.util.concurrency.Execution import com.android.systemui.util.settings.SecureSettings import java.lang.RuntimeException Loading @@ -67,6 +68,7 @@ class LockscreenSmartspaceController @Inject constructor( private val contentResolver: ContentResolver, private val configurationController: ConfigurationController, private val statusBarStateController: StatusBarStateController, private val deviceProvisionedController: DeviceProvisionedController, private val execution: Execution, @Main private val uiExecutor: Executor, @Main private val handler: Handler, Loading Loading @@ -95,6 +97,55 @@ class LockscreenSmartspaceController @Inject constructor( } } private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() val filteredTargets = targets.filter(::filterSmartspaceTarget) plugin?.onTargetsAvailable(filteredTargets) } private val userTrackerCallback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { execution.assertIsMainThread() reloadSmartspace() } } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { execution.assertIsMainThread() reloadSmartspace() } } private val configChangeListener = object : ConfigurationController.ConfigurationListener { override fun onThemeChanged() { execution.assertIsMainThread() updateTextColorFromWallpaper() } } private val statusBarStateListener = object : StatusBarStateController.StateListener { override fun onDozeAmountChanged(linear: Float, eased: Float) { execution.assertIsMainThread() smartspaceViews.forEach { it.setDozeAmount(eased) } } } private val deviceProvisionedListener = object : DeviceProvisionedController.DeviceProvisionedListener { override fun onDeviceProvisionedChanged() { connectSession() } override fun onUserSetupChanged() { connectSession() } } init { deviceProvisionedController.addCallback(deviceProvisionedListener) } fun isEnabled(): Boolean { execution.assertIsMainThread() Loading Loading @@ -145,10 +196,20 @@ class LockscreenSmartspaceController @Inject constructor( if (plugin == null || session != null) { return } val session = smartspaceManager.createSmartspaceSession( // Only connect after the device is fully provisioned to avoid connection caching // issues if (!deviceProvisionedController.isDeviceProvisioned() || !deviceProvisionedController.isCurrentUserSetup()) { return } val newSession = smartspaceManager.createSmartspaceSession( SmartspaceConfig.Builder(context, "lockscreen").build()) session.addOnTargetsAvailableListener(uiExecutor, sessionListener) newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener) this.session = newSession deviceProvisionedController.removeCallback(deviceProvisionedListener) userTracker.addCallback(userTrackerCallback, uiExecutor) contentResolver.registerContentObserver( secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS), Loading @@ -159,8 +220,6 @@ class LockscreenSmartspaceController @Inject constructor( configurationController.addCallback(configChangeListener) statusBarStateController.addCallback(statusBarStateListener) this.session = session reloadSmartspace() } Loading Loading @@ -197,43 +256,6 @@ class LockscreenSmartspaceController @Inject constructor( plugin?.unregisterListener(listener) } private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() val filteredTargets = targets.filter(::filterSmartspaceTarget) plugin?.onTargetsAvailable(filteredTargets) } private val userTrackerCallback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { execution.assertIsMainThread() reloadSmartspace() } override fun onProfilesChanged(profiles: List<UserInfo>) { } } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { execution.assertIsMainThread() reloadSmartspace() } } private val configChangeListener = object : ConfigurationController.ConfigurationListener { override fun onThemeChanged() { execution.assertIsMainThread() updateTextColorFromWallpaper() } } private val statusBarStateListener = object : StatusBarStateController.StateListener { override fun onDozeAmountChanged(linear: Float, eased: Float) { execution.assertIsMainThread() smartspaceViews.forEach { it.setDozeAmount(eased) } } } private fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean { return when (t.userHandle) { userTracker.userHandle -> { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +34 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ import com.android.systemui.settings.UserTracker import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener import com.android.systemui.util.concurrency.FakeExecution import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any Loading Loading @@ -89,6 +91,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @Mock private lateinit var handler: Handler @Mock Loading @@ -106,12 +110,15 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { private lateinit var configChangeListenerCaptor: ArgumentCaptor<ConfigurationListener> @Captor private lateinit var statusBarStateListenerCaptor: ArgumentCaptor<StateListener> @Captor private lateinit var deviceProvisionedCaptor: ArgumentCaptor<DeviceProvisionedListener> private lateinit var sessionListener: OnTargetsAvailableListener private lateinit var userListener: UserTracker.Callback private lateinit var settingsObserver: ContentObserver private lateinit var configChangeListener: ConfigurationListener private lateinit var statusBarStateListener: StateListener private lateinit var deviceProvisionedListener: DeviceProvisionedListener private lateinit var smartspaceView: SmartspaceView Loading Loading @@ -145,6 +152,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { `when`(plugin.getView(any())).thenReturn(createSmartspaceView(), createSmartspaceView()) `when`(userTracker.userProfiles).thenReturn(userList) `when`(statusBarStateController.dozeAmount).thenReturn(0.5f) `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) setActiveUser(userHandlePrimary) setAllowPrivateNotifications(userHandlePrimary, true) Loading @@ -162,11 +171,15 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { contentResolver, configurationController, statusBarStateController, deviceProvisionedController, execution, executor, handler, Optional.of(plugin) ) verify(deviceProvisionedController).addCallback(capture(deviceProvisionedCaptor)) deviceProvisionedListener = deviceProvisionedCaptor.value } @Test(expected = RuntimeException::class) Loading @@ -180,6 +193,27 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN an exception is thrown } @Test fun connectOnlyAfterDeviceIsProvisioned() { // GIVEN an unprovisioned device and an attempt to connect `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(false) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(false) // WHEN a connection attempt is made controller.buildAndConnectView(fakeParent) // THEN no session is created verify(smartspaceManager, never()).createSmartspaceSession(any()) // WHEN it does become provisioned `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) deviceProvisionedListener.onUserSetupChanged() // THEN the session is created verify(smartspaceManager).createSmartspaceSession(any()) } @Test fun testListenersAreRegistered() { // GIVEN a listener is added after a session is created Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +63 −41 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.util.concurrency.Execution import com.android.systemui.util.settings.SecureSettings import java.lang.RuntimeException Loading @@ -67,6 +68,7 @@ class LockscreenSmartspaceController @Inject constructor( private val contentResolver: ContentResolver, private val configurationController: ConfigurationController, private val statusBarStateController: StatusBarStateController, private val deviceProvisionedController: DeviceProvisionedController, private val execution: Execution, @Main private val uiExecutor: Executor, @Main private val handler: Handler, Loading Loading @@ -95,6 +97,55 @@ class LockscreenSmartspaceController @Inject constructor( } } private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() val filteredTargets = targets.filter(::filterSmartspaceTarget) plugin?.onTargetsAvailable(filteredTargets) } private val userTrackerCallback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { execution.assertIsMainThread() reloadSmartspace() } } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { execution.assertIsMainThread() reloadSmartspace() } } private val configChangeListener = object : ConfigurationController.ConfigurationListener { override fun onThemeChanged() { execution.assertIsMainThread() updateTextColorFromWallpaper() } } private val statusBarStateListener = object : StatusBarStateController.StateListener { override fun onDozeAmountChanged(linear: Float, eased: Float) { execution.assertIsMainThread() smartspaceViews.forEach { it.setDozeAmount(eased) } } } private val deviceProvisionedListener = object : DeviceProvisionedController.DeviceProvisionedListener { override fun onDeviceProvisionedChanged() { connectSession() } override fun onUserSetupChanged() { connectSession() } } init { deviceProvisionedController.addCallback(deviceProvisionedListener) } fun isEnabled(): Boolean { execution.assertIsMainThread() Loading Loading @@ -145,10 +196,20 @@ class LockscreenSmartspaceController @Inject constructor( if (plugin == null || session != null) { return } val session = smartspaceManager.createSmartspaceSession( // Only connect after the device is fully provisioned to avoid connection caching // issues if (!deviceProvisionedController.isDeviceProvisioned() || !deviceProvisionedController.isCurrentUserSetup()) { return } val newSession = smartspaceManager.createSmartspaceSession( SmartspaceConfig.Builder(context, "lockscreen").build()) session.addOnTargetsAvailableListener(uiExecutor, sessionListener) newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener) this.session = newSession deviceProvisionedController.removeCallback(deviceProvisionedListener) userTracker.addCallback(userTrackerCallback, uiExecutor) contentResolver.registerContentObserver( secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS), Loading @@ -159,8 +220,6 @@ class LockscreenSmartspaceController @Inject constructor( configurationController.addCallback(configChangeListener) statusBarStateController.addCallback(statusBarStateListener) this.session = session reloadSmartspace() } Loading Loading @@ -197,43 +256,6 @@ class LockscreenSmartspaceController @Inject constructor( plugin?.unregisterListener(listener) } private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() val filteredTargets = targets.filter(::filterSmartspaceTarget) plugin?.onTargetsAvailable(filteredTargets) } private val userTrackerCallback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { execution.assertIsMainThread() reloadSmartspace() } override fun onProfilesChanged(profiles: List<UserInfo>) { } } private val settingsObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { execution.assertIsMainThread() reloadSmartspace() } } private val configChangeListener = object : ConfigurationController.ConfigurationListener { override fun onThemeChanged() { execution.assertIsMainThread() updateTextColorFromWallpaper() } } private val statusBarStateListener = object : StatusBarStateController.StateListener { override fun onDozeAmountChanged(linear: Float, eased: Float) { execution.assertIsMainThread() smartspaceViews.forEach { it.setDozeAmount(eased) } } } private fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean { return when (t.userHandle) { userTracker.userHandle -> { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +34 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ import com.android.systemui.settings.UserTracker import com.android.systemui.flags.FeatureFlags import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener import com.android.systemui.util.concurrency.FakeExecution import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any Loading Loading @@ -89,6 +91,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @Mock private lateinit var handler: Handler @Mock Loading @@ -106,12 +110,15 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { private lateinit var configChangeListenerCaptor: ArgumentCaptor<ConfigurationListener> @Captor private lateinit var statusBarStateListenerCaptor: ArgumentCaptor<StateListener> @Captor private lateinit var deviceProvisionedCaptor: ArgumentCaptor<DeviceProvisionedListener> private lateinit var sessionListener: OnTargetsAvailableListener private lateinit var userListener: UserTracker.Callback private lateinit var settingsObserver: ContentObserver private lateinit var configChangeListener: ConfigurationListener private lateinit var statusBarStateListener: StateListener private lateinit var deviceProvisionedListener: DeviceProvisionedListener private lateinit var smartspaceView: SmartspaceView Loading Loading @@ -145,6 +152,8 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { `when`(plugin.getView(any())).thenReturn(createSmartspaceView(), createSmartspaceView()) `when`(userTracker.userProfiles).thenReturn(userList) `when`(statusBarStateController.dozeAmount).thenReturn(0.5f) `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) setActiveUser(userHandlePrimary) setAllowPrivateNotifications(userHandlePrimary, true) Loading @@ -162,11 +171,15 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { contentResolver, configurationController, statusBarStateController, deviceProvisionedController, execution, executor, handler, Optional.of(plugin) ) verify(deviceProvisionedController).addCallback(capture(deviceProvisionedCaptor)) deviceProvisionedListener = deviceProvisionedCaptor.value } @Test(expected = RuntimeException::class) Loading @@ -180,6 +193,27 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN an exception is thrown } @Test fun connectOnlyAfterDeviceIsProvisioned() { // GIVEN an unprovisioned device and an attempt to connect `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(false) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(false) // WHEN a connection attempt is made controller.buildAndConnectView(fakeParent) // THEN no session is created verify(smartspaceManager, never()).createSmartspaceSession(any()) // WHEN it does become provisioned `when`(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true) `when`(deviceProvisionedController.isCurrentUserSetup()).thenReturn(true) deviceProvisionedListener.onUserSetupChanged() // THEN the session is created verify(smartspaceManager).createSmartspaceSession(any()) } @Test fun testListenersAreRegistered() { // GIVEN a listener is added after a session is created Loading