From a57e4ce3ed33e9e9b7bbf99dca2029ec8ea33aa5 Mon Sep 17 00:00:00 2001 From: Grace Date: Tue, 19 Jul 2022 03:42:09 +0000 Subject: [PATCH] Add Region Sampler to Lockscreen Smartspace This change adds region sampling to the views for lockscreen smartspace. It also modifies how the region sampling instance is created. The clock parameter is replaced with an interface that specifies how the updating of colors should be done. This allows for a more generalized usage of the region sampling instance class. Bug: 202758428 Test: atest LockscreenSmartspaceControllerTest Change-Id: Id890309c95eab1251d09485ce560e1eae5c15900 --- .../regionsampling/RegionSamplingInstance.kt | 20 +++-- .../android/keyguard/ClockEventController.kt | 30 +++---- .../LockscreenSmartspaceController.kt | 86 +++++++++++++++---- .../LockscreenSmartspaceControllerTest.kt | 5 ++ 4 files changed, 101 insertions(+), 40 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt index f8f7c24c7c149..bc5003e85b2e5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt @@ -15,10 +15,8 @@ */ package com.android.systemui.shared.regionsampling -import android.content.res.Resources import android.graphics.Rect import android.view.View -import com.android.systemui.plugins.Clock import com.android.systemui.plugins.RegionDarkness import com.android.systemui.shared.navigationbar.RegionSamplingHelper import com.android.systemui.shared.navigationbar.RegionSamplingHelper.SamplingCallback @@ -33,13 +31,23 @@ class RegionSamplingInstance( mainExecutor: Executor?, bgExecutor: Executor?, regionSamplingEnabled: Boolean, - clock: Clock?, - resources: Resources + updateFun: UpdateColorCallback ) { private var isDark = RegionDarkness.DEFAULT private var samplingBounds = Rect() private var regionSampler: RegionSamplingHelper? = null + /** + * Interface for method to be passed into RegionSamplingHelper + */ + @FunctionalInterface + interface UpdateColorCallback { + /** + * Method to update the text colors after clock darkness changed. + */ + fun updateColors() + } + private fun convertToClockDarkness(isRegionDark: Boolean): RegionDarkness { return if (isRegionDark) { RegionDarkness.DARK @@ -48,7 +56,7 @@ class RegionSamplingInstance( } } - fun currentClockDarkness(): RegionDarkness { + fun currentRegionDarkness(): RegionDarkness { return isDark } @@ -86,7 +94,7 @@ class RegionSamplingInstance( object : SamplingCallback { override fun onRegionDarknessChanged(isRegionDark: Boolean) { isDark = convertToClockDarkness(isRegionDark) - clock?.events?.onColorPaletteChanged(resources, isDark, isDark) + updateFun.updateColors() } override fun getSampledRegion(sampledView: View): Rect { diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index bc1c10af5065b..0d1158c959e52 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -72,11 +72,13 @@ class ClockEventController @Inject constructor( private val regionSamplingEnabled = featureFlags.isEnabled(com.android.systemui.flags.Flags.REGION_SAMPLING) - private fun updateColors(currentClock: Clock?) { - smallClockIsDark = smallRegionSamplingInstance.currentClockDarkness() - largeClockIsDark = largeRegionSamplingInstance.currentClockDarkness() + private val updateFun = object : RegionSamplingInstance.UpdateColorCallback { + override fun updateColors() { + smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness() + largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness() - currentClock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark) + clock?.events?.onColorPaletteChanged(resources, smallClockIsDark, largeClockIsDark) + } } fun updateRegionSamplers(currentClock: Clock?) { @@ -88,8 +90,7 @@ class ClockEventController @Inject constructor( mainExecutor, bgExecutor, regionSamplingEnabled, - currentClock, - resources + updateFun ) largeRegionSamplingInstance = RegionSamplingInstance( @@ -97,14 +98,13 @@ class ClockEventController @Inject constructor( mainExecutor, bgExecutor, regionSamplingEnabled, - currentClock, - resources + updateFun ) smallRegionSamplingInstance.startRegionSampler() largeRegionSamplingInstance.startRegionSampler() - updateColors(currentClock) + updateFun.updateColors() } var smallRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance( @@ -112,8 +112,7 @@ class ClockEventController @Inject constructor( mainExecutor, bgExecutor, regionSamplingEnabled, - clock, - resources + updateFun ) var largeRegionSamplingInstance: RegionSamplingInstance = RegionSamplingInstance( @@ -121,16 +120,15 @@ class ClockEventController @Inject constructor( mainExecutor, bgExecutor, regionSamplingEnabled, - clock, - resources + updateFun ) - private var smallClockIsDark = smallRegionSamplingInstance.currentClockDarkness() - private var largeClockIsDark = largeRegionSamplingInstance.currentClockDarkness() + private var smallClockIsDark = smallRegionSamplingInstance.currentRegionDarkness() + private var largeClockIsDark = largeRegionSamplingInstance.currentRegionDarkness() private val configListener = object : ConfigurationController.ConfigurationListener { override fun onThemeChanged() { - updateColors(clock) + updateFun.updateColors() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index a509fcaad4ee5..dfba8cd4a081a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -31,11 +31,13 @@ import android.os.UserHandle import android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS import android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS import android.util.Log +import android.view.ContextThemeWrapper import android.view.View import android.view.ViewGroup import com.android.settingslib.Utils import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -46,6 +48,7 @@ import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker +import com.android.systemui.shared.regionsampling.RegionSamplingInstance import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.DeviceProvisionedController @@ -60,22 +63,23 @@ import javax.inject.Inject */ @SysUISingleton class LockscreenSmartspaceController @Inject constructor( - private val context: Context, - private val featureFlags: FeatureFlags, - private val smartspaceManager: SmartspaceManager, - private val activityStarter: ActivityStarter, - private val falsingManager: FalsingManager, - private val secureSettings: SecureSettings, - private val userTracker: UserTracker, - private val contentResolver: ContentResolver, - private val configurationController: ConfigurationController, - private val statusBarStateController: StatusBarStateController, - private val deviceProvisionedController: DeviceProvisionedController, - private val bypassController: KeyguardBypassController, - private val execution: Execution, - @Main private val uiExecutor: Executor, - @Main private val handler: Handler, - optionalPlugin: Optional + private val context: Context, + private val featureFlags: FeatureFlags, + private val smartspaceManager: SmartspaceManager, + private val activityStarter: ActivityStarter, + private val falsingManager: FalsingManager, + private val secureSettings: SecureSettings, + private val userTracker: UserTracker, + private val contentResolver: ContentResolver, + private val configurationController: ConfigurationController, + private val statusBarStateController: StatusBarStateController, + private val deviceProvisionedController: DeviceProvisionedController, + private val bypassController: KeyguardBypassController, + private val execution: Execution, + @Main private val uiExecutor: Executor, + @Background private val bgExecutor: Executor, + @Main private val handler: Handler, + optionalPlugin: Optional ) { companion object { private const val TAG = "LockscreenSmartspaceController" @@ -86,15 +90,37 @@ class LockscreenSmartspaceController @Inject constructor( // Smartspace can be used on multiple displays, such as when the user casts their screen private var smartspaceViews = mutableSetOf() + private var regionSamplingInstances = + mutableMapOf() + + private val regionSamplingEnabled = + featureFlags.isEnabled(Flags.REGION_SAMPLING) private var showNotifications = false private var showSensitiveContentForCurrentUser = false private var showSensitiveContentForManagedUser = false private var managedUserHandle: UserHandle? = null + private val updateFun = object : RegionSamplingInstance.UpdateColorCallback { + override fun updateColors() { + updateTextColorFromRegionSampler() + } + } + + // TODO: Move logic into SmartspaceView var stateChangeListener = object : View.OnAttachStateChangeListener { override fun onViewAttachedToWindow(v: View) { smartspaceViews.add(v as SmartspaceView) + + var regionSamplingInstance = RegionSamplingInstance( + v, + uiExecutor, + bgExecutor, + regionSamplingEnabled, + updateFun + ) + regionSamplingInstance.startRegionSampler() + regionSamplingInstances.put(v, regionSamplingInstance) connectSession() updateTextColorFromWallpaper() @@ -104,6 +130,10 @@ class LockscreenSmartspaceController @Inject constructor( override fun onViewDetachedFromWindow(v: View) { smartspaceViews.remove(v as SmartspaceView) + var regionSamplingInstance = regionSamplingInstances.getValue(v) + regionSamplingInstance.stopRegionSampler() + regionSamplingInstances.remove(v) + if (smartspaceViews.isEmpty()) { disconnect() } @@ -332,9 +362,29 @@ class LockscreenSmartspaceController @Inject constructor( } } + private fun updateTextColorFromRegionSampler() { + smartspaceViews.forEach { + val isRegionDark = regionSamplingInstances.getValue(it).currentRegionDarkness() + val themeID = if (isRegionDark.isDark) { + R.style.Theme_SystemUI + } else { + R.style.Theme_SystemUI_LightWallpaper + } + val themedContext = ContextThemeWrapper(context, themeID) + val wallpaperTextColor = + Utils.getColorAttrDefaultColor(themedContext, R.attr.wallpaperTextColor) + it.setPrimaryTextColor(wallpaperTextColor) + } + } + private fun updateTextColorFromWallpaper() { - val wallpaperTextColor = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor) - smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) } + if (!regionSamplingEnabled) { + val wallpaperTextColor = + Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor) + smartspaceViews.forEach { it.setPrimaryTextColor(wallpaperTextColor) } + } else { + updateTextColorFromRegionSampler() + } } private fun reloadSmartspace() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt index 20747a05a360b..790865bb496fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt @@ -56,6 +56,7 @@ import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.time.FakeSystemClock import java.util.Optional +import java.util.concurrent.Executor import org.junit.Before import org.junit.Test import org.mockito.ArgumentCaptor @@ -104,6 +105,9 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController + @Mock + private lateinit var bgExecutor: Executor + @Mock private lateinit var handler: Handler @@ -203,6 +207,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { keyguardBypassController, execution, executor, + bgExecutor, handler, Optional.of(plugin) )