Loading packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java +32 −25 Original line number Diff line number Diff line Loading @@ -15,12 +15,15 @@ */ package com.android.systemui.theme; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.om.OverlayManagerTransaction; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; Loading Loading @@ -229,47 +232,51 @@ public class ThemeOverlayApplier implements Dumpable { final List<OverlayInfo> overlays = new ArrayList<>(); targetPackagesToQuery.forEach(targetPackage -> overlays.addAll(mOverlayManager .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM))); final Map<String, String> overlaysToDisable = overlays.stream() final List<Pair<String, String>> overlaysToDisable = overlays.stream() .filter(o -> mTargetPackageToCategories.get(o.targetPackageName).contains(o.category)) .filter(o -> overlayCategoriesToDisable.contains(o.category)) .filter(o -> o.isEnabled()) .collect(Collectors.toMap((o) -> o.category, (o) -> o.packageName)); .map(o -> new Pair<>(o.category, o.packageName)) .collect(Collectors.toList()); OverlayManagerTransaction.Builder transaction = getTransactionBuilder(); // Toggle overlays in the order of THEME_CATEGORIES. for (String category : THEME_CATEGORIES) { if (categoryToPackage.containsKey(category)) { setEnabled(categoryToPackage.get(category), category, userHandles, true); } else if (overlaysToDisable.containsKey(category)) { setEnabled(overlaysToDisable.get(category), category, userHandles, false); OverlayIdentifier overlayInfo = new OverlayIdentifier(categoryToPackage.get(category)); setEnabled(transaction, overlayInfo, category, userHandles, true); } } for (Pair<String, String> packageToDisable : overlaysToDisable) { OverlayIdentifier overlayInfo = new OverlayIdentifier(packageToDisable.second); setEnabled(transaction, overlayInfo, packageToDisable.first, userHandles, false); } private void setEnabled( String packageName, String category, Set<UserHandle> handles, boolean enabled) { for (UserHandle userHandle : handles) { setEnabledAsync(packageName, userHandle, enabled); } if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) { setEnabledAsync(packageName, UserHandle.SYSTEM, enabled); mExecutor.execute(() -> { mOverlayManager.commit(transaction.build()); }); } @VisibleForTesting protected OverlayManagerTransaction.Builder getTransactionBuilder() { return new OverlayManagerTransaction.Builder(); } private void setEnabledAsync(String pkg, UserHandle userHandle, boolean enabled) { mExecutor.execute(() -> { if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled)); try { if (enabled) { mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle); } else { mOverlayManager.setEnabled(pkg, false, userHandle); private void setEnabled(OverlayManagerTransaction.Builder transaction, OverlayIdentifier identifier, String category, Set<UserHandle> handles, boolean enabled) { if (DEBUG) { Log.d(TAG, "setEnabled: " + identifier.getPackageName() + " category: " + category + ": " + enabled); } } catch (SecurityException | IllegalStateException e) { Log.e(TAG, String.format("setEnabled failed: %s %s %b", pkg, userHandle, enabled), e); for (UserHandle userHandle : handles) { transaction.setEnabled(identifier, enabled, userHandle.getIdentifier()); } if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) { transaction.setEnabled(identifier, enabled, UserHandle.SYSTEM.getIdentifier()); } }); } /** Loading packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java +40 −17 Original line number Diff line number Diff line Loading @@ -32,13 +32,16 @@ import static com.android.systemui.theme.ThemeOverlayApplier.THEME_CATEGORIES; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.om.OverlayManagerTransaction; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -87,6 +90,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { OverlayManager mOverlayManager; @Mock DumpManager mDumpManager; @Mock OverlayManagerTransaction.Builder mTransactionBuilder; private ThemeOverlayApplier mManager; Loading @@ -94,7 +99,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { public void setup() throws Exception { MockitoAnnotations.initMocks(this); mManager = new ThemeOverlayApplier(mOverlayManager, MoreExecutors.directExecutor(), LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager); LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager) { @Override protected OverlayManagerTransaction.Builder getTransactionBuilder() { return mTransactionBuilder; } }; when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM)) .thenReturn(Lists.newArrayList( createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, Loading Loading @@ -148,9 +158,11 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void allCategoriesSpecified_allEnabledExclusively() { mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); verify(mOverlayManager).commit(any()); for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); } } Loading @@ -160,11 +172,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { for (Map.Entry<String, String> entry : ALL_CATEGORIES_MAP.entrySet()) { if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) { verify(mOverlayManager).setEnabledExclusiveInCategory( entry.getValue(), UserHandle.SYSTEM); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(entry.getValue())), eq(true), eq(UserHandle.SYSTEM.getIdentifier())); } else { verify(mOverlayManager, never()).setEnabledExclusiveInCategory( entry.getValue(), UserHandle.SYSTEM); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier(entry.getValue())), eq(true), eq(UserHandle.SYSTEM.getIdentifier())); } } } Loading @@ -177,8 +190,10 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, userHandles); for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, newUserHandle); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(newUserHandle.getIdentifier())); } } Loading @@ -199,12 +214,15 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); for (String overlayPackage : categoryToPackage.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); } verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS, false, TEST_USER); verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID, false, TEST_USER); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS)), eq(false), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID)), eq(false), eq(TEST_USER.getIdentifier())); } @Test Loading @@ -212,7 +230,9 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(Maps.newArrayMap(), TEST_USER_HANDLES); for (String category : THEME_CATEGORIES) { verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + category, false, TEST_USER); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + category)), eq(false), eq(TEST_USER.getIdentifier())); } } Loading @@ -223,9 +243,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); verify(mOverlayManager, never()).setEnabled("com.example.blah.category", false, TEST_USER); verify(mOverlayManager, never()).setEnabledExclusiveInCategory("com.example.blah.category", TEST_USER); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier("com.example.blah.category")), eq(false), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier("com.example.blah.category")), eq(true), eq(TEST_USER.getIdentifier())); } @Test Loading Loading
packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java +32 −25 Original line number Diff line number Diff line Loading @@ -15,12 +15,15 @@ */ package com.android.systemui.theme; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.om.OverlayManagerTransaction; import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; Loading Loading @@ -229,47 +232,51 @@ public class ThemeOverlayApplier implements Dumpable { final List<OverlayInfo> overlays = new ArrayList<>(); targetPackagesToQuery.forEach(targetPackage -> overlays.addAll(mOverlayManager .getOverlayInfosForTarget(targetPackage, UserHandle.SYSTEM))); final Map<String, String> overlaysToDisable = overlays.stream() final List<Pair<String, String>> overlaysToDisable = overlays.stream() .filter(o -> mTargetPackageToCategories.get(o.targetPackageName).contains(o.category)) .filter(o -> overlayCategoriesToDisable.contains(o.category)) .filter(o -> o.isEnabled()) .collect(Collectors.toMap((o) -> o.category, (o) -> o.packageName)); .map(o -> new Pair<>(o.category, o.packageName)) .collect(Collectors.toList()); OverlayManagerTransaction.Builder transaction = getTransactionBuilder(); // Toggle overlays in the order of THEME_CATEGORIES. for (String category : THEME_CATEGORIES) { if (categoryToPackage.containsKey(category)) { setEnabled(categoryToPackage.get(category), category, userHandles, true); } else if (overlaysToDisable.containsKey(category)) { setEnabled(overlaysToDisable.get(category), category, userHandles, false); OverlayIdentifier overlayInfo = new OverlayIdentifier(categoryToPackage.get(category)); setEnabled(transaction, overlayInfo, category, userHandles, true); } } for (Pair<String, String> packageToDisable : overlaysToDisable) { OverlayIdentifier overlayInfo = new OverlayIdentifier(packageToDisable.second); setEnabled(transaction, overlayInfo, packageToDisable.first, userHandles, false); } private void setEnabled( String packageName, String category, Set<UserHandle> handles, boolean enabled) { for (UserHandle userHandle : handles) { setEnabledAsync(packageName, userHandle, enabled); } if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) { setEnabledAsync(packageName, UserHandle.SYSTEM, enabled); mExecutor.execute(() -> { mOverlayManager.commit(transaction.build()); }); } @VisibleForTesting protected OverlayManagerTransaction.Builder getTransactionBuilder() { return new OverlayManagerTransaction.Builder(); } private void setEnabledAsync(String pkg, UserHandle userHandle, boolean enabled) { mExecutor.execute(() -> { if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled)); try { if (enabled) { mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle); } else { mOverlayManager.setEnabled(pkg, false, userHandle); private void setEnabled(OverlayManagerTransaction.Builder transaction, OverlayIdentifier identifier, String category, Set<UserHandle> handles, boolean enabled) { if (DEBUG) { Log.d(TAG, "setEnabled: " + identifier.getPackageName() + " category: " + category + ": " + enabled); } } catch (SecurityException | IllegalStateException e) { Log.e(TAG, String.format("setEnabled failed: %s %s %b", pkg, userHandle, enabled), e); for (UserHandle userHandle : handles) { transaction.setEnabled(identifier, enabled, userHandle.getIdentifier()); } if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) { transaction.setEnabled(identifier, enabled, UserHandle.SYSTEM.getIdentifier()); } }); } /** Loading
packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java +40 −17 Original line number Diff line number Diff line Loading @@ -32,13 +32,16 @@ import static com.android.systemui.theme.ThemeOverlayApplier.THEME_CATEGORIES; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.om.OverlayIdentifier; import android.content.om.OverlayInfo; import android.content.om.OverlayManager; import android.content.om.OverlayManagerTransaction; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading Loading @@ -87,6 +90,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { OverlayManager mOverlayManager; @Mock DumpManager mDumpManager; @Mock OverlayManagerTransaction.Builder mTransactionBuilder; private ThemeOverlayApplier mManager; Loading @@ -94,7 +99,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { public void setup() throws Exception { MockitoAnnotations.initMocks(this); mManager = new ThemeOverlayApplier(mOverlayManager, MoreExecutors.directExecutor(), LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager); LAUNCHER_PACKAGE, THEMEPICKER_PACKAGE, mDumpManager) { @Override protected OverlayManagerTransaction.Builder getTransactionBuilder() { return mTransactionBuilder; } }; when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM)) .thenReturn(Lists.newArrayList( createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR, Loading Loading @@ -148,9 +158,11 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { @Test public void allCategoriesSpecified_allEnabledExclusively() { mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); verify(mOverlayManager).commit(any()); for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); } } Loading @@ -160,11 +172,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { for (Map.Entry<String, String> entry : ALL_CATEGORIES_MAP.entrySet()) { if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) { verify(mOverlayManager).setEnabledExclusiveInCategory( entry.getValue(), UserHandle.SYSTEM); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(entry.getValue())), eq(true), eq(UserHandle.SYSTEM.getIdentifier())); } else { verify(mOverlayManager, never()).setEnabledExclusiveInCategory( entry.getValue(), UserHandle.SYSTEM); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier(entry.getValue())), eq(true), eq(UserHandle.SYSTEM.getIdentifier())); } } } Loading @@ -177,8 +190,10 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, userHandles); for (String overlayPackage : ALL_CATEGORIES_MAP.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, newUserHandle); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(newUserHandle.getIdentifier())); } } Loading @@ -199,12 +214,15 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); for (String overlayPackage : categoryToPackage.values()) { verify(mOverlayManager).setEnabledExclusiveInCategory(overlayPackage, TEST_USER); verify(mTransactionBuilder).setEnabled(eq(new OverlayIdentifier(overlayPackage)), eq(true), eq(TEST_USER.getIdentifier())); } verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS, false, TEST_USER); verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID, false, TEST_USER); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_SETTINGS)), eq(false), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID)), eq(false), eq(TEST_USER.getIdentifier())); } @Test Loading @@ -212,7 +230,9 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(Maps.newArrayMap(), TEST_USER_HANDLES); for (String category : THEME_CATEGORIES) { verify(mOverlayManager).setEnabled(TEST_ENABLED_PREFIX + category, false, TEST_USER); verify(mTransactionBuilder).setEnabled( eq(new OverlayIdentifier(TEST_ENABLED_PREFIX + category)), eq(false), eq(TEST_USER.getIdentifier())); } } Loading @@ -223,9 +243,12 @@ public class ThemeOverlayApplierTest extends SysuiTestCase { mManager.applyCurrentUserOverlays(categoryToPackage, TEST_USER_HANDLES); verify(mOverlayManager, never()).setEnabled("com.example.blah.category", false, TEST_USER); verify(mOverlayManager, never()).setEnabledExclusiveInCategory("com.example.blah.category", TEST_USER); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier("com.example.blah.category")), eq(false), eq(TEST_USER.getIdentifier())); verify(mTransactionBuilder, never()).setEnabled( eq(new OverlayIdentifier("com.example.blah.category")), eq(true), eq(TEST_USER.getIdentifier())); } @Test Loading