Only enable overlay where package is installed
We cannot try to enable icon overlay on managed users because neither launcher nor the wallpaper picker is installed on managed profiles. Trying to do so will result in a SecurityException. Fixes: 180461062 Test: manual Test: atest ThemeOverlayApplierTest ThemeOverlayControllerTest Change-Id: I25a07f7a6aa41b6c92c8928091219c4b0fb22770
This commit is contained in:
@@ -161,10 +161,10 @@ public class ThemeOverlayApplier implements Dumpable {
|
||||
void applyCurrentUserOverlays(
|
||||
Map<String, OverlayIdentifier> categoryToPackage,
|
||||
FabricatedOverlay[] pendingCreation,
|
||||
Set<UserHandle> userHandles) {
|
||||
int currentUser,
|
||||
Set<UserHandle> managedProfiles) {
|
||||
// Disable all overlays that have not been specified in the user setting.
|
||||
final Set<String> overlayCategoriesToDisable = new HashSet<>(THEME_CATEGORIES);
|
||||
overlayCategoriesToDisable.removeAll(categoryToPackage.keySet());
|
||||
final Set<String> targetPackagesToQuery = overlayCategoriesToDisable.stream()
|
||||
.map(category -> mCategoryToTargetPackage.get(category))
|
||||
.collect(Collectors.toSet());
|
||||
@@ -175,6 +175,7 @@ public class ThemeOverlayApplier implements Dumpable {
|
||||
.filter(o ->
|
||||
mTargetPackageToCategories.get(o.targetPackageName).contains(o.category))
|
||||
.filter(o -> overlayCategoriesToDisable.contains(o.category))
|
||||
.filter(o -> !categoryToPackage.containsValue(new OverlayIdentifier(o.packageName)))
|
||||
.filter(o -> o.isEnabled())
|
||||
.map(o -> new Pair<>(o.category, o.packageName))
|
||||
.collect(Collectors.toList());
|
||||
@@ -186,17 +187,18 @@ public class ThemeOverlayApplier implements Dumpable {
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle overlays in the order of THEME_CATEGORIES.
|
||||
for (Pair<String, String> packageToDisable : overlaysToDisable) {
|
||||
OverlayIdentifier overlayInfo = new OverlayIdentifier(packageToDisable.second);
|
||||
setEnabled(transaction, overlayInfo, packageToDisable.first, currentUser,
|
||||
managedProfiles, false);
|
||||
}
|
||||
|
||||
for (String category : THEME_CATEGORIES) {
|
||||
if (categoryToPackage.containsKey(category)) {
|
||||
OverlayIdentifier overlayInfo = categoryToPackage.get(category);
|
||||
setEnabled(transaction, overlayInfo, category, userHandles, true);
|
||||
setEnabled(transaction, overlayInfo, category, currentUser, managedProfiles, true);
|
||||
}
|
||||
}
|
||||
for (Pair<String, String> packageToDisable : overlaysToDisable) {
|
||||
OverlayIdentifier overlayInfo = new OverlayIdentifier(packageToDisable.second);
|
||||
setEnabled(transaction, overlayInfo, packageToDisable.first, userHandles, false);
|
||||
}
|
||||
|
||||
mExecutor.execute(() -> {
|
||||
try {
|
||||
@@ -213,18 +215,30 @@ public class ThemeOverlayApplier implements Dumpable {
|
||||
}
|
||||
|
||||
private void setEnabled(OverlayManagerTransaction.Builder transaction,
|
||||
OverlayIdentifier identifier, String category, Set<UserHandle> handles,
|
||||
boolean enabled) {
|
||||
OverlayIdentifier identifier, String category, int currentUser,
|
||||
Set<UserHandle> managedProfiles, boolean enabled) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setEnabled: " + identifier.getPackageName() + " category: "
|
||||
+ category + ": " + enabled);
|
||||
}
|
||||
for (UserHandle userHandle : handles) {
|
||||
transaction.setEnabled(identifier, enabled, userHandle.getIdentifier());
|
||||
}
|
||||
if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) {
|
||||
|
||||
transaction.setEnabled(identifier, enabled, currentUser);
|
||||
if (currentUser != UserHandle.SYSTEM.getIdentifier()
|
||||
&& SYSTEM_USER_CATEGORIES.contains(category)) {
|
||||
transaction.setEnabled(identifier, enabled, UserHandle.SYSTEM.getIdentifier());
|
||||
}
|
||||
|
||||
// Do not apply Launcher or Theme picker overlays to managed users. Apps are not
|
||||
// installed in there.
|
||||
OverlayInfo overlayInfo = mOverlayManager.getOverlayInfo(identifier, UserHandle.SYSTEM);
|
||||
if (overlayInfo == null || overlayInfo.targetPackageName.equals(mLauncherPackage)
|
||||
|| overlayInfo.targetPackageName.equals(mThemePickerPackage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (UserHandle userHandle : managedProfiles) {
|
||||
transaction.setEnabled(identifier, enabled, userHandle.getIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,14 +55,13 @@ import com.android.systemui.statusbar.FeatureFlags;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import com.google.android.collect.Sets;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -151,7 +150,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (DEBUG) Log.d(TAG, "Updating overlays for user switch / profile added.");
|
||||
updateThemeOverlays();
|
||||
reevaluateSystemTheme(true /* forceReload */);
|
||||
}
|
||||
}, filter, mBgExecutor, UserHandle.ALL);
|
||||
mSecureSettings.registerContentObserverForUser(
|
||||
@@ -163,7 +162,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
int userId) {
|
||||
if (DEBUG) Log.d(TAG, "Overlay changed for user: " + userId);
|
||||
if (ActivityManager.getCurrentUser() == userId) {
|
||||
updateThemeOverlays();
|
||||
reevaluateSystemTheme(true /* forceReload */);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -180,7 +179,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
mLockColors = lockColors;
|
||||
}
|
||||
mSystemColors = systemColor;
|
||||
reevaluateSystemTheme();
|
||||
reevaluateSystemTheme(false /* forceReload */);
|
||||
});
|
||||
});
|
||||
if (USE_LOCK_SCREEN_WALLPAPER) {
|
||||
@@ -192,7 +191,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
}
|
||||
// It's possible that the user has a lock screen wallpaper. On this case we'll
|
||||
// end up with different colors after unlocking.
|
||||
reevaluateSystemTheme();
|
||||
reevaluateSystemTheme(false /* forceReload */);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -209,11 +208,11 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
Log.d(TAG, "got new lock colors: " + wallpaperColors + " where: " + which);
|
||||
}
|
||||
}
|
||||
reevaluateSystemTheme();
|
||||
reevaluateSystemTheme(false /* forceReload */);
|
||||
}, null, UserHandle.USER_ALL);
|
||||
}
|
||||
|
||||
private void reevaluateSystemTheme() {
|
||||
private void reevaluateSystemTheme(boolean forceReload) {
|
||||
WallpaperColors currentColors =
|
||||
mKeyguardStateController.isShowing() && mLockColors != null
|
||||
? mLockColors : mSystemColors;
|
||||
@@ -228,7 +227,8 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
accentCandidate = getAccentColor(currentColors);
|
||||
}
|
||||
|
||||
if (mMainWallpaperColor == mainColor && mWallpaperAccentColor == accentCandidate) {
|
||||
if (mMainWallpaperColor == mainColor && mWallpaperAccentColor == accentCandidate
|
||||
&& !forceReload) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -309,6 +309,16 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
} catch (NumberFormatException e) {
|
||||
Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName());
|
||||
}
|
||||
} else if (!mIsMonetEnabled && systemPalette != null) {
|
||||
try {
|
||||
// It's possible that we flipped the flag off and still have a @ColorInt in the
|
||||
// setting. We need to sanitize the input, otherwise the overlay transaction will
|
||||
// fail.
|
||||
Integer.parseInt(systemPalette.getPackageName().toLowerCase(), 16);
|
||||
categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
|
||||
} catch (NumberFormatException e) {
|
||||
// This is a package name. All good, let's continue
|
||||
}
|
||||
}
|
||||
|
||||
// Same for accent color.
|
||||
@@ -322,6 +332,13 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
} catch (NumberFormatException e) {
|
||||
Log.w(TAG, "Invalid color definition: " + accentPalette.getPackageName());
|
||||
}
|
||||
} else if (!mIsMonetEnabled && accentPalette != null) {
|
||||
try {
|
||||
Integer.parseInt(accentPalette.getPackageName().toLowerCase(), 16);
|
||||
categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
|
||||
} catch (NumberFormatException e) {
|
||||
// This is a package name. All good, let's continue
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibility with legacy themes, where full packages were defined, instead of just
|
||||
@@ -337,10 +354,10 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, mSecondaryOverlay.getIdentifier());
|
||||
}
|
||||
|
||||
Set<UserHandle> userHandles = Sets.newHashSet(UserHandle.of(currentUser));
|
||||
Set<UserHandle> managedProfiles = new HashSet<>();
|
||||
for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) {
|
||||
if (userInfo.isManagedProfile()) {
|
||||
userHandles.add(userInfo.getUserHandle());
|
||||
managedProfiles.add(userInfo.getUserHandle());
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
@@ -352,9 +369,10 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
|
||||
mNeedsOverlayCreation = false;
|
||||
mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[] {
|
||||
mPrimaryOverlay, mSecondaryOverlay, mNeutralOverlay
|
||||
}, userHandles);
|
||||
}, currentUser, managedProfiles);
|
||||
} else {
|
||||
mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, userHandles);
|
||||
mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser,
|
||||
managedProfiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import static com.android.systemui.theme.ThemeOverlayApplier.SYSUI_PACKAGE;
|
||||
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.mock;
|
||||
@@ -88,7 +87,9 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
private static final String THEMEPICKER_PACKAGE = "com.android.wallpaper";
|
||||
private static final String LAUNCHER_PACKAGE = "com.android.launcher3";
|
||||
private static final UserHandle TEST_USER = UserHandle.of(5);
|
||||
private static final Set<UserHandle> TEST_USER_HANDLES = Sets.newHashSet(TEST_USER);
|
||||
private static final UserHandle TEST_USER_MANAGED_PROFILE = UserHandle.of(6);
|
||||
private static final Set<UserHandle> TEST_USER_HANDLES =
|
||||
Sets.newHashSet(TEST_USER_MANAGED_PROFILE);
|
||||
|
||||
@Mock
|
||||
OverlayManager mOverlayManager;
|
||||
@@ -159,13 +160,19 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
THEMEPICKER_PACKAGE, OVERLAY_CATEGORY_ICON_THEME_PICKER, false),
|
||||
createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ICON_THEME_PICKER,
|
||||
THEMEPICKER_PACKAGE, OVERLAY_CATEGORY_ICON_THEME_PICKER, true)));
|
||||
|
||||
OverlayInfo launcherTargetInfo = new OverlayInfo("packageName", LAUNCHER_PACKAGE,
|
||||
null, null, "/", 0, 0, 0, false);
|
||||
when(mOverlayManager.getOverlayInfo(any(OverlayIdentifier.class), any()))
|
||||
.thenReturn(launcherTargetInfo);
|
||||
clearInvocations(mOverlayManager);
|
||||
verify(mDumpManager).registerDumpable(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allCategoriesSpecified_allEnabledExclusively() {
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES);
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
|
||||
TEST_USER_HANDLES);
|
||||
verify(mOverlayManager).commit(any());
|
||||
|
||||
for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) {
|
||||
@@ -176,7 +183,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() {
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES);
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
|
||||
TEST_USER_HANDLES);
|
||||
|
||||
for (Map.Entry<String, OverlayIdentifier> entry : ALL_CATEGORIES_MAP.entrySet()) {
|
||||
if (SYSTEM_USER_CATEGORIES.contains(entry.getKey())) {
|
||||
@@ -192,48 +200,39 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void allCategoriesSpecified_enabledForAllUserHandles() {
|
||||
Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES);
|
||||
UserHandle newUserHandle = UserHandle.of(10);
|
||||
userHandles.add(newUserHandle);
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, userHandles);
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER.getIdentifier(),
|
||||
userHandles);
|
||||
|
||||
for (OverlayIdentifier overlayPackage : ALL_CATEGORIES_MAP.values()) {
|
||||
verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true),
|
||||
eq(TEST_USER.getIdentifier()));
|
||||
verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true),
|
||||
eq(newUserHandle.getIdentifier()));
|
||||
// Not enabled for work profile because the target package is LAUNCHER_PACKAGE
|
||||
verify(mTransactionBuilder, never()).setEnabled(eq(overlayPackage), eq(true),
|
||||
eq(TEST_USER_MANAGED_PROFILE.getIdentifier()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyCurrentUserOverlays_createsPendingOverlays() {
|
||||
Set<UserHandle> userHandles = Sets.newHashSet(TEST_USER_HANDLES);
|
||||
UserHandle newUserHandle = UserHandle.of(10);
|
||||
userHandles.add(newUserHandle);
|
||||
FabricatedOverlay[] pendingCreation = new FabricatedOverlay[] {
|
||||
FabricatedOverlay[] pendingCreation = new FabricatedOverlay[]{
|
||||
mock(FabricatedOverlay.class)
|
||||
};
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, pendingCreation, userHandles);
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, pendingCreation,
|
||||
TEST_USER.getIdentifier(), TEST_USER_HANDLES);
|
||||
|
||||
for (FabricatedOverlay overlay : pendingCreation) {
|
||||
verify(mTransactionBuilder).registerFabricatedOverlay(eq(overlay));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allCategoriesSpecified_overlayManagerNotQueried() {
|
||||
mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, null, TEST_USER_HANDLES);
|
||||
|
||||
verify(mOverlayManager, never())
|
||||
.getOverlayInfosForTarget(anyString(), any(UserHandle.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void someCategoriesSpecified_specifiedEnabled_unspecifiedDisabled() {
|
||||
Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
|
||||
categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS);
|
||||
categoryToPackage.remove(OVERLAY_CATEGORY_ICON_ANDROID);
|
||||
|
||||
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES);
|
||||
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER.getIdentifier(),
|
||||
TEST_USER_HANDLES);
|
||||
|
||||
for (OverlayIdentifier overlayPackage : categoryToPackage.values()) {
|
||||
verify(mTransactionBuilder).setEnabled(eq(overlayPackage), eq(true),
|
||||
@@ -249,7 +248,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void zeroCategoriesSpecified_allDisabled() {
|
||||
mManager.applyCurrentUserOverlays(Maps.newArrayMap(), null, TEST_USER_HANDLES);
|
||||
mManager.applyCurrentUserOverlays(Maps.newArrayMap(), null, TEST_USER.getIdentifier(),
|
||||
TEST_USER_HANDLES);
|
||||
|
||||
for (String category : THEME_CATEGORIES) {
|
||||
verify(mTransactionBuilder).setEnabled(
|
||||
@@ -263,7 +263,8 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
|
||||
categoryToPackage.put("blah.category", new OverlayIdentifier("com.example.blah.category"));
|
||||
|
||||
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES);
|
||||
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER.getIdentifier(),
|
||||
TEST_USER_HANDLES);
|
||||
|
||||
verify(mTransactionBuilder, never()).setEnabled(
|
||||
eq(new OverlayIdentifier("com.example.blah.category")), eq(false),
|
||||
@@ -273,23 +274,6 @@ public class ThemeOverlayApplierTest extends SysuiTestCase {
|
||||
eq(TEST_USER.getIdentifier()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overlayManagerOnlyQueriedForUnspecifiedPackages() {
|
||||
Map<String, OverlayIdentifier> categoryToPackage = new HashMap<>(ALL_CATEGORIES_MAP);
|
||||
categoryToPackage.remove(OVERLAY_CATEGORY_ICON_SETTINGS);
|
||||
|
||||
mManager.applyCurrentUserOverlays(categoryToPackage, null, TEST_USER_HANDLES);
|
||||
|
||||
verify(mOverlayManager).getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.SYSTEM);
|
||||
verify(mOverlayManager, never()).getOverlayInfosForTarget(ANDROID_PACKAGE,
|
||||
UserHandle.SYSTEM);
|
||||
verify(mOverlayManager, never()).getOverlayInfosForTarget(SYSUI_PACKAGE, UserHandle.SYSTEM);
|
||||
verify(mOverlayManager, never()).getOverlayInfosForTarget(LAUNCHER_PACKAGE,
|
||||
UserHandle.SYSTEM);
|
||||
verify(mOverlayManager, never()).getOverlayInfosForTarget(THEMEPICKER_PACKAGE,
|
||||
UserHandle.SYSTEM);
|
||||
}
|
||||
|
||||
private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName,
|
||||
String category, boolean enabled) {
|
||||
return new OverlayInfo(packageName, null, targetPackageName, null, category, "",
|
||||
|
||||
@@ -143,7 +143,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
ArgumentCaptor.forClass(Map.class);
|
||||
|
||||
verify(mThemeOverlayApplier)
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), any());
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
|
||||
|
||||
// Assert that we received the colors that we were expecting
|
||||
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
|
||||
@@ -175,7 +175,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
ArgumentCaptor.forClass(Map.class);
|
||||
|
||||
verify(mThemeOverlayApplier)
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), any());
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
|
||||
|
||||
// Assert that we received the colors that we were expecting
|
||||
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
|
||||
@@ -198,7 +198,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
|
||||
ArgumentCaptor.forClass(Map.class);
|
||||
|
||||
verify(mThemeOverlayApplier)
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), any());
|
||||
.applyCurrentUserOverlays(themeOverlays.capture(), any(), anyInt(), any());
|
||||
|
||||
// Assert that we received the colors that we were expecting
|
||||
assertThat(themeOverlays.getValue().get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
|
||||
|
||||
Reference in New Issue
Block a user