Defer color events until end of SUW
Color events might recreate activities, disrupting the setup wizard flow
Test: atest ThemeOverlayControllerTest
Test: manual
Bug: 182560740
Change-Id: Id924b3356c37c533dfbcb92048f95295a29a3dfd
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index d317712..fc9a35d 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -19,9 +19,9 @@
import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
import android.annotation.Nullable;
-import android.app.ActivityManager;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
+import android.app.WallpaperManager.OnColorsChangedListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -49,8 +49,10 @@
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.util.settings.SecureSettings;
import org.json.JSONException;
@@ -92,8 +94,9 @@
private final Executor mMainExecutor;
private final Handler mBgHandler;
private final WallpaperManager mWallpaperManager;
- private final KeyguardStateController mKeyguardStateController;
private final boolean mIsMonetEnabled;
+ private final UserTracker mUserTracker;
+ private DeviceProvisionedController mDeviceProvisionedController;
private WallpaperColors mSystemColors;
// If fabricated overlays were already created for the current theme.
private boolean mNeedsOverlayCreation;
@@ -107,17 +110,76 @@
private FabricatedOverlay mNeutralOverlay;
// If wallpaper color event will be accepted and change the UI colors.
private boolean mAcceptColorEvents = true;
+ // Defers changing themes until Setup Wizard is done.
+ private boolean mDeferredThemeEvaluation;
+
+ private final DeviceProvisionedListener mDeviceProvisionedListener =
+ new DeviceProvisionedListener() {
+ @Override
+ public void onUserSetupChanged() {
+ if (!mDeviceProvisionedController.isCurrentUserSetup()) {
+ return;
+ }
+ if (!mDeferredThemeEvaluation) {
+ return;
+ }
+ Log.i(TAG, "Applying deferred theme");
+ mDeferredThemeEvaluation = false;
+ reevaluateSystemTheme(true /* forceReload */);
+ }
+ };
+
+ private final OnColorsChangedListener mOnColorsChangedListener = (wallpaperColors, which) -> {
+ if (!mAcceptColorEvents) {
+ Log.i(TAG, "Wallpaper color event rejected: " + wallpaperColors);
+ return;
+ }
+ if (wallpaperColors != null) {
+ mAcceptColorEvents = false;
+ }
+
+ if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+ mSystemColors = wallpaperColors;
+ if (DEBUG) {
+ Log.d(TAG, "got new lock colors: " + wallpaperColors + " where: " + which);
+ }
+ }
+
+ if (mDeviceProvisionedController != null
+ && !mDeviceProvisionedController.isCurrentUserSetup()) {
+ Log.i(TAG, "Wallpaper color event deferred until setup is finished: "
+ + wallpaperColors);
+ mDeferredThemeEvaluation = true;
+ return;
+ }
+ reevaluateSystemTheme(false /* forceReload */);
+ };
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())
+ || Intent.ACTION_MANAGED_PROFILE_ADDED.equals(intent.getAction())) {
+ if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
+ reevaluateSystemTheme(true /* forceReload */);
+ } else if (Intent.ACTION_WALLPAPER_CHANGED.equals(intent.getAction())) {
+ mAcceptColorEvents = true;
+ Log.i(TAG, "Allowing color events again");
+ }
+ }
+ };
@Inject
public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher,
@Background Handler bgHandler, @Main Executor mainExecutor,
@Background Executor bgExecutor, ThemeOverlayApplier themeOverlayApplier,
SecureSettings secureSettings, WallpaperManager wallpaperManager,
- UserManager userManager, KeyguardStateController keyguardStateController,
- DumpManager dumpManager, FeatureFlags featureFlags) {
+ UserManager userManager, DeviceProvisionedController deviceProvisionedController,
+ UserTracker userTracker, DumpManager dumpManager, FeatureFlags featureFlags) {
super(context);
mIsMonetEnabled = featureFlags.isMonetEnabled();
+ mDeviceProvisionedController = deviceProvisionedController;
mBroadcastDispatcher = broadcastDispatcher;
mUserManager = userManager;
mBgExecutor = bgExecutor;
@@ -126,7 +188,7 @@
mThemeManager = themeOverlayApplier;
mSecureSettings = secureSettings;
mWallpaperManager = wallpaperManager;
- mKeyguardStateController = keyguardStateController;
+ mUserTracker = userTracker;
dumpManager.registerDumpable(TAG, this);
}
@@ -137,19 +199,8 @@
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
filter.addAction(Intent.ACTION_WALLPAPER_CHANGED);
- mBroadcastDispatcher.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())
- || Intent.ACTION_MANAGED_PROFILE_ADDED.equals(intent.getAction())) {
- if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
- reevaluateSystemTheme(true /* forceReload */);
- } else if (Intent.ACTION_WALLPAPER_CHANGED.equals(intent.getAction())) {
- mAcceptColorEvents = true;
- Log.i(TAG, "Allowing color events again");
- }
- }
- }, filter, mMainExecutor, UserHandle.ALL);
+ mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, mMainExecutor,
+ UserHandle.ALL);
mSecureSettings.registerContentObserverForUser(
Settings.Secure.getUriFor(Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES),
false,
@@ -158,12 +209,19 @@
public void onChange(boolean selfChange, Collection<Uri> collection, int flags,
int userId) {
if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId);
- if (ActivityManager.getCurrentUser() == userId) {
- reevaluateSystemTheme(true /* forceReload */);
+ if (mUserTracker.getUserId() != userId) {
+ return;
}
+ if (!mDeviceProvisionedController.isUserSetup(userId)) {
+ Log.i(TAG, "Theme application deferred when setting changed.");
+ mDeferredThemeEvaluation = true;
+ return;
+ }
+ reevaluateSystemTheme(true /* forceReload */);
}
},
UserHandle.USER_ALL);
+ mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
// Upon boot, make sure we have the most up to date colors
mBgExecutor.execute(() -> {
@@ -174,23 +232,8 @@
reevaluateSystemTheme(false /* forceReload */);
});
});
- mWallpaperManager.addOnColorsChangedListener((wallpaperColors, which) -> {
- if (!mAcceptColorEvents) {
- Log.i(TAG, "Wallpaper color event rejected: " + wallpaperColors);
- return;
- }
- if (wallpaperColors != null && mAcceptColorEvents) {
- mAcceptColorEvents = false;
- }
-
- if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
- mSystemColors = wallpaperColors;
- if (DEBUG) {
- Log.d(TAG, "got new lock colors: " + wallpaperColors + " where: " + which);
- }
- }
- reevaluateSystemTheme(false /* forceReload */);
- }, null, UserHandle.USER_ALL);
+ mWallpaperManager.addOnColorsChangedListener(mOnColorsChangedListener, null,
+ UserHandle.USER_ALL);
}
private void reevaluateSystemTheme(boolean forceReload) {
@@ -252,7 +295,7 @@
}
private void updateThemeOverlays() {
- final int currentUser = ActivityManager.getCurrentUser();
+ final int currentUser = mUserTracker.getUserId();
final String overlayPackageJson = mSecureSettings.getStringForUser(
Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
currentUser);
@@ -360,5 +403,6 @@
pw.println("mIsMonetEnabled=" + mIsMonetEnabled);
pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation);
pw.println("mAcceptColorEvents=" + mAcceptColorEvents);
+ pw.println("mDeferredThemeEvaluation=" + mDeferredThemeEvaluation);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 4e7e0a3..ddf0537 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -26,6 +26,8 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -49,8 +51,10 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.FeatureFlags;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.util.settings.SecureSettings;
import org.junit.Before;
@@ -86,24 +90,29 @@
@Mock
private UserManager mUserManager;
@Mock
- private KeyguardStateController mKeyguardStateController;
+ private UserTracker mUserTracker;
@Mock
private DumpManager mDumpManager;
@Mock
+ private DeviceProvisionedController mDeviceProvisionedController;
+ @Mock
private FeatureFlags mFeatureFlags;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
@Captor
private ArgumentCaptor<WallpaperManager.OnColorsChangedListener> mColorsListener;
+ @Captor
+ private ArgumentCaptor<DeviceProvisionedListener> mDeviceProvisionedListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mFeatureFlags.isMonetEnabled()).thenReturn(true);
+ when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
mThemeOverlayController = new ThemeOverlayController(null /* context */,
mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
- mSecureSettings, mWallpaperManager, mUserManager, mKeyguardStateController,
- mDumpManager, mFeatureFlags) {
+ mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
+ mUserTracker, mDumpManager, mFeatureFlags) {
@Nullable
@Override
protected FabricatedOverlay getOverlay(int color, int type) {
@@ -120,6 +129,7 @@
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiver.capture(), any(),
eq(mMainExecutor), any());
verify(mDumpManager).registerDumpable(any(), any());
+ verify(mDeviceProvisionedController).addCallback(mDeviceProvisionedListener.capture());
}
@Test
@@ -191,6 +201,22 @@
}
@Test
+ public void onWallpaperColorsChanged_defersUntilSetupIsCompleted() {
+ reset(mDeviceProvisionedController);
+ WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
+ Color.valueOf(Color.BLUE), null);
+ mColorsListener.getValue().onColorsChanged(mainColors, WallpaperManager.FLAG_SYSTEM);
+
+ verify(mThemeOverlayApplier, never())
+ .applyCurrentUserOverlays(any(), any(), anyInt(), any());
+
+ when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
+ mDeviceProvisionedListener.getValue().onUserSetupChanged();
+
+ verify(mThemeOverlayApplier).applyCurrentUserOverlays(any(), any(), anyInt(), any());
+ }
+
+ @Test
public void onWallpaperColorsChanged_parsesColorsFromWallpaperPicker() {
WallpaperColors mainColors = new WallpaperColors(Color.valueOf(Color.RED),
Color.valueOf(Color.BLUE), null);