Smartspace - Allow primary card colors to be updated

This is largely for both AOD and lockscreen, while may have different
colors than launcher. Particularly for AOD, we need to transition to a
WHITE color. Set a primary text color, with expectations that a
secondary color will later be set in order to support cards with
various background colors.

Fixes: 185211979
Test: manual, change to AOD <-> LS
Change-Id: I36fb8e5cfcbac1ec999b2b9df08f42d47507990f
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index 35423a9..53ff9f0 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -58,5 +58,7 @@
     /** View to which this plugin can be registered, in order to get updates. */
     interface SmartspaceView {
         void registerDataProvider(BcSmartspaceDataPlugin plugin);
+
+        void setPrimaryTextColor(int color);
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index cb825c0..f89e365 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -26,14 +26,18 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.view.View;
 import android.widget.FrameLayout;
 import android.widget.RelativeLayout;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.graphics.ColorUtils;
 import com.android.keyguard.clock.ClockManager;
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -50,6 +54,7 @@
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.ViewController;
 
 import java.util.Locale;
@@ -87,6 +92,10 @@
     private Executor mUiExecutor;
     private SmartspaceSession mSmartspaceSession;
     private SmartspaceSession.Callback mSmartspaceCallback;
+    private float mDozeAmount;
+    private int mWallpaperTextColor;
+    private int mDozeColor = Color.WHITE;
+    private ConfigurationController mConfigurationController;
 
     /**
      * Listener for changes to the color palette.
@@ -103,8 +112,25 @@
         }
     };
 
+    private final ConfigurationController.ConfigurationListener mConfigurationListener =
+            new ConfigurationController.ConfigurationListener() {
+        @Override
+        public void onThemeChanged() {
+            updateWallpaperColor();
+        }
+    };
+
     private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
 
+    private final StatusBarStateController.StateListener mStatusBarStateListener =
+            new StatusBarStateController.StateListener() {
+                @Override
+                public void onDozeAmountChanged(float linear, float eased) {
+                    mDozeAmount = eased;
+                    updateSmartspaceColor();
+                }
+            };
+
     // If set, will replace keyguard_status_area
     private BcSmartspaceDataPlugin.SmartspaceView mSmartspaceView;
 
@@ -121,7 +147,8 @@
             PluginManager pluginManager,
             FeatureFlags featureFlags,
             @Main Executor uiExecutor,
-            BatteryController batteryController) {
+            BatteryController batteryController,
+            ConfigurationController configurationController) {
         super(keyguardClockSwitch);
         mResources = resources;
         mStatusBarStateController = statusBarStateController;
@@ -134,6 +161,7 @@
         mIsSmartspaceEnabled = featureFlags.isSmartspaceEnabled();
         mUiExecutor = uiExecutor;
         mBatteryController = batteryController;
+        mConfigurationController = configurationController;
     }
 
     /**
@@ -172,6 +200,12 @@
                 mBatteryController);
         mLargeClockViewController.init();
 
+        mDozeAmount = mStatusBarStateController.getDozeAmount();
+        updateWallpaperColor();
+
+        mStatusBarStateController.addCallback(mStatusBarStateListener);
+        mConfigurationController.addCallback(mConfigurationListener);
+
         // If a smartspace plugin is detected, replace the existing smartspace
         // (keyguard_status_area), and initialize a new session
         mPluginListener = new PluginListener<BcSmartspaceDataPlugin>() {
@@ -186,6 +220,7 @@
 
                 mSmartspaceView = plugin.getView(mView);
                 mSmartspaceView.registerDataProvider(plugin);
+                updateSmartspaceColor();
                 View asView = (View) mSmartspaceView;
 
                 // Place plugin view below normal clock...
@@ -242,6 +277,19 @@
         mPluginManager.addPluginListener(mPluginListener, BcSmartspaceDataPlugin.class, false);
     }
 
+    private void updateWallpaperColor() {
+        mWallpaperTextColor = Utils.getColorAttrDefaultColor(getContext(),
+                R.attr.wallpaperTextColor);
+        updateSmartspaceColor();
+    }
+
+    private void updateSmartspaceColor() {
+        if (mSmartspaceView != null) {
+            int color = ColorUtils.blendARGB(mWallpaperTextColor, mDozeColor, mDozeAmount);
+            mSmartspaceView.setPrimaryTextColor(color);
+        }
+    }
+
     @Override
     protected void onViewDetached() {
         if (CUSTOM_CLOCKS_ENABLED) {
@@ -256,6 +304,8 @@
             mSmartspaceSession = null;
         }
         mPluginManager.removePluginListener(mPluginListener);
+        mStatusBarStateController.removeCallback(mStatusBarStateListener);
+        mConfigurationController.removeCallback(mConfigurationListener);
     }
 
     /**
@@ -399,4 +449,9 @@
     private int getCurrentLayoutDirection() {
         return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault());
     }
+
+    @VisibleForTesting
+    ConfigurationController.ConfigurationListener getConfigurationListener() {
+        return mConfigurationListener;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index e2e28b8..a870915 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -49,6 +50,7 @@
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -102,8 +104,11 @@
     private FrameLayout mLargeClockFrame;
     @Mock
     BatteryController mBatteryController;
+    @Mock
+    ConfigurationController mConfigurationController;
 
     private KeyguardClockSwitchController mController;
+    private View mStatusArea;
 
     @Before
     public void setup() {
@@ -111,6 +116,8 @@
 
         when(mView.findViewById(R.id.left_aligned_notification_icon_container))
                 .thenReturn(mNotificationIcons);
+        when(mNotificationIcons.getLayoutParams()).thenReturn(
+                mock(RelativeLayout.LayoutParams.class));
         when(mView.getContext()).thenReturn(getContext());
 
         when(mView.findViewById(R.id.animatable_clock_view)).thenReturn(mClockView);
@@ -135,10 +142,15 @@
                 mPluginManager,
                 mFeatureFlags,
                 mExecutor,
-                mBatteryController);
+                mBatteryController,
+                mConfigurationController);
 
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
         when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors);
+
+        mStatusArea = mock(View.class);
+        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
+
     }
 
     @Test
@@ -201,39 +213,40 @@
     public void testSmartspacePluginConnectedRemovesKeyguardStatusArea() {
         mController.init();
 
-        View statusArea = mock(View.class);
-        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
-
-        View nic = mock(View.class);
-        when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
-        when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
-
         BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
         TestView view = mock(TestView.class);
         when(plugin.getView(any())).thenReturn(view);
 
         mController.mPluginListener.onPluginConnected(plugin, mContext);
-        verify(statusArea).setVisibility(View.GONE);
+        verify(mStatusArea).setVisibility(View.GONE);
     }
 
     @Test
     public void testSmartspacePluginDisconnectedShowsKeyguardStatusArea() {
         mController.init();
 
-        View statusArea = mock(View.class);
-        when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea);
-
-        View nic = mock(View.class);
-        when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic);
-        when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class));
-
         BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
         TestView view = mock(TestView.class);
         when(plugin.getView(any())).thenReturn(view);
 
         mController.mPluginListener.onPluginConnected(plugin, mContext);
         mController.mPluginListener.onPluginDisconnected(plugin);
-        verify(statusArea).setVisibility(View.VISIBLE);
+        verify(mStatusArea).setVisibility(View.VISIBLE);
+    }
+
+    @Test
+    public void testThemeChangeNotifiesSmartspace() {
+        mController.init();
+
+        BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class);
+        TestView view = mock(TestView.class);
+        when(plugin.getView(any())).thenReturn(view);
+
+        mController.mPluginListener.onPluginConnected(plugin, mContext);
+
+        reset(view);
+        mController.getConfigurationListener().onThemeChanged();
+        verify(view).setPrimaryTextColor(anyInt());
     }
 
     private void verifyAttachment(VerificationMode times) {
@@ -250,5 +263,7 @@
         }
 
         public void registerDataProvider(BcSmartspaceDataPlugin plugin) { }
+
+        public void setPrimaryTextColor(int color) { }
     }
 }