diff options
4 files changed, 137 insertions, 54 deletions
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java index 72f16e4e4a82..fbef027ac37f 100644 --- a/core/java/com/android/internal/content/om/OverlayConfig.java +++ b/core/java/com/android/internal/content/om/OverlayConfig.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.content.pm.PackagePartitions; import android.content.pm.parsing.ParsingPackageRead; import android.os.Build; -import android.os.Process; import android.os.Trace; import android.util.ArrayMap; import android.util.Log; @@ -232,20 +231,26 @@ public class OverlayConfig { /** * Returns whether the overlay is enabled by default. - * Overlays that are not configured are disabled by default mutable. + * Overlays that are not configured are disabled by default. + * + * If an immutable overlay has its enabled state change, the new enabled state is applied to the + * overlay. + * + * When a mutable is first seen by the OverlayManagerService, the default-enabled state will be + * applied to the overlay. If the configured default-enabled state changes in a subsequent boot, + * the default-enabled state will not be applied to the overlay. + * + * The configured enabled state will only be applied when: + * <ul> + * <li> The device is factory reset + * <li> The overlay is removed from the device and added back to the device in a future OTA + * <li> The overlay changes its package name + * <li> The overlay changes its target package name or target overlayable name + * <li> An immutable overlay becomes mutable + * </ul> */ public boolean isEnabled(String packageName) { final Configuration config = mConfigurations.get(packageName); - - // STOPSHIP(149499802): Enabling a mutable overlay currently has no effect. Either implement - // some behavior for default-enabled, mutable overlays or prevent parsing of the enabled - // attribute on overlays that are mutable. - if (config != null && config.parsedConfig.mutable) { - Log.w(TAG, "Default-enabled configuration for mutable overlay " - + config.parsedConfig.packageName + " has no effect"); - return OverlayConfigParser.DEFAULT_ENABLED_STATE; - } - return config == null? OverlayConfigParser.DEFAULT_ENABLED_STATE : config.parsedConfig.enabled; } diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index 2493057e0121..ebdd79a9409e 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -102,10 +102,6 @@ final class OverlayManagerServiceImpl { return true; } - if (getPackageConfiguredPriority(theTruth.packageName) != oldSettings.priority) { - return true; - } - // If an immutable overlay changes its configured enabled state, reinitialize the overlay. if (!isMutable && isPackageConfiguredEnabled(theTruth.packageName) != oldSettings.isEnabled()) { @@ -161,6 +157,7 @@ final class OverlayManagerServiceImpl { final PackageInfo overlayPackage = overlayPackages.get(i); final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); + int priority = getPackageConfiguredPriority(overlayPackage.packageName); if (mustReinitializeOverlay(overlayPackage, oi)) { // if targetPackageName has changed the package that *used* to // be the target must also update its assets @@ -174,8 +171,10 @@ final class OverlayManagerServiceImpl { overlayPackage.applicationInfo.getBaseCodePath(), isPackageConfiguredMutable(overlayPackage.packageName), isPackageConfiguredEnabled(overlayPackage.packageName), - getPackageConfiguredPriority(overlayPackage.packageName), - overlayPackage.overlayCategory); + priority, overlayPackage.overlayCategory); + } else if (priority != oi.priority) { + mSettings.setPriority(overlayPackage.packageName, newUserId, priority); + packagesToUpdateAssets.add(oi.targetPackageName); } storedOverlayInfos.remove(overlayPackage.packageName); diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index 6bccdfcf5bb2..bdbaf78439a8 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -71,24 +71,9 @@ final class OverlayManagerSettings { @NonNull final String baseCodePath, boolean isMutable, boolean isEnabled, int priority, @Nullable String overlayCategory) { remove(packageName, userId); - final SettingsItem item = - new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName, - baseCodePath, OverlayInfo.STATE_UNKNOWN, isEnabled, isMutable, priority, - overlayCategory); - - int i; - for (i = mItems.size() - 1; i >= 0; i--) { - SettingsItem parentItem = mItems.get(i); - if (parentItem.mPriority <= priority) { - break; - } - } - int pos = i + 1; - if (pos == mItems.size()) { - mItems.add(item); - } else { - mItems.add(pos, item); - } + insert(new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName, + baseCodePath, OverlayInfo.STATE_UNKNOWN, isEnabled, isMutable, priority, + overlayCategory)); } /** @@ -220,6 +205,21 @@ final class OverlayManagerSettings { } /** + * Reassigns the priority of an overlay maintaining the values of the overlays other settings. + */ + void setPriority(@NonNull final String packageName, final int userId, final int priority) { + final int moveIdx = select(packageName, userId); + if (moveIdx < 0) { + throw new BadKeyException(packageName, userId); + } + + final SettingsItem itemToMove = mItems.get(moveIdx); + mItems.remove(moveIdx); + itemToMove.setPriority(priority); + insert(itemToMove); + } + + /** * Returns true if the settings were modified, false if they remain the same. */ boolean setPriority(@NonNull final String packageName, @@ -284,6 +284,21 @@ final class OverlayManagerSettings { return true; } + /** + * Inserts the item into the list of settings items. + */ + private void insert(@NonNull SettingsItem item) { + int i; + for (i = mItems.size() - 1; i >= 0; i--) { + SettingsItem parentItem = mItems.get(i); + if (parentItem.mPriority <= item.getPriority()) { + break; + } + } + + mItems.add(i + 1, item); + } + void dump(@NonNull final PrintWriter p, @NonNull DumpState dumpState) { // select items to display Stream<SettingsItem> items = mItems.stream(); @@ -583,6 +598,11 @@ final class OverlayManagerSettings { return mCache; } + private void setPriority(int priority) { + mPriority = priority; + invalidateCache(); + } + private void invalidateCache() { mCache = null; } diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java index c4fea77cf1ba..f35eecf05f32 100644 --- a/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java +++ b/services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java @@ -30,6 +30,7 @@ import org.junit.runner.RunWith; import java.util.Arrays; import java.util.List; +import java.util.function.BiConsumer; @RunWith(AndroidJUnit4.class) public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceImplTestsBase { @@ -132,57 +133,115 @@ public class OverlayManagerServiceImplRebootTests extends OverlayManagerServiceI } @Test - public void testMutabilityChange() { + public void testMutableEnabledToImmutableEnabled() { final OverlayManagerServiceImpl impl = getImpl(); installTargetPackage(TARGET, USER); - addOverlayPackage(OVERLAY, TARGET, USER, false, true, 0); + final BiConsumer<Boolean, Boolean> setOverlay = (mutable, enabled) -> { + addOverlayPackage(OVERLAY, TARGET, USER, mutable, enabled, 0); + impl.updateOverlaysForUser(USER); + final OverlayInfo o1 = impl.getOverlayInfo(OVERLAY, USER); + assertNotNull(o1); + assertEquals(enabled, o1.isEnabled()); + assertEquals(mutable, o1.isMutable); + }; + + // Immutable/enabled -> mutable/enabled + setOverlay.accept(false /* mutable */, true /* enabled */); + setOverlay.accept(true /* mutable */, true /* enabled */); + + // Mutable/enabled -> immutable/enabled + setOverlay.accept(false /* mutable */, true /* enabled */); + + // Immutable/enabled -> mutable/disabled + setOverlay.accept(true /* mutable */, false /* enabled */); + + // Mutable/disabled -> immutable/enabled + setOverlay.accept(false /* mutable */, true /* enabled */); + + // Immutable/enabled -> immutable/disabled + setOverlay.accept(false /* mutable */, false /* enabled */); + + // Immutable/disabled -> mutable/enabled + setOverlay.accept(true /* mutable */, true /* enabled */); + + // Mutable/enabled -> immutable/disabled + setOverlay.accept(false /* mutable */, false /* enabled */); + + // Immutable/disabled -> mutable/disabled + setOverlay.accept(true /* mutable */, false /* enabled */); + + // Mutable/disabled -> immutable/disabled + setOverlay.accept(false /* mutable */, false /* enabled */); + } + + @Test + public void testMutablePriorityChange() { + final OverlayManagerServiceImpl impl = getImpl(); + installTargetPackage(TARGET, USER); + addOverlayPackage(OVERLAY, TARGET, USER, true, true, 0); + addOverlayPackage(OVERLAY2, TARGET, USER, true, true, 1); impl.updateOverlaysForUser(USER); + final OverlayInfo o1 = impl.getOverlayInfo(OVERLAY, USER); assertNotNull(o1); - assertTrue(o1.isEnabled()); - assertFalse(o1.isMutable); + assertEquals(0, o1.priority); - addOverlayPackage(OVERLAY, TARGET, USER, true, false, 0); - impl.updateOverlaysForUser(USER); - final OverlayInfo o2 = impl.getOverlayInfo(OVERLAY, USER); + final OverlayInfo o2 = impl.getOverlayInfo(OVERLAY2, USER); assertNotNull(o2); - assertFalse(o2.isEnabled()); - assertTrue(o2.isMutable); + assertEquals(1, o2.priority); - addOverlayPackage(OVERLAY, TARGET, USER, false, false, 0); + // Overlay priority changing between reboots should not affect enable state of mutable + // overlays + impl.setEnabled(OVERLAY, true, USER); + + // Reorder the overlays + addOverlayPackage(OVERLAY, TARGET, USER, true, true, 1); + addOverlayPackage(OVERLAY2, TARGET, USER, true, true, 0); impl.updateOverlaysForUser(USER); + final OverlayInfo o3 = impl.getOverlayInfo(OVERLAY, USER); assertNotNull(o3); - assertFalse(o3.isEnabled()); - assertFalse(o3.isMutable); + assertEquals(1, o3.priority); + + final OverlayInfo o4 = impl.getOverlayInfo(OVERLAY2, USER); + assertNotNull(o4); + assertEquals(0, o4.priority); + assertTrue(o1.isEnabled()); } @Test - public void testPriorityChange() { + public void testImmutablePriorityChange() { final OverlayManagerServiceImpl impl = getImpl(); installTargetPackage(TARGET, USER); - addOverlayPackage(OVERLAY, TARGET, USER, false, true, 0); addOverlayPackage(OVERLAY2, TARGET, USER, false, true, 1); impl.updateOverlaysForUser(USER); final OverlayInfo o1 = impl.getOverlayInfo(OVERLAY, USER); - final OverlayInfo o2 = impl.getOverlayInfo(OVERLAY2, USER); assertNotNull(o1); - assertNotNull(o2); assertEquals(0, o1.priority); + + final OverlayInfo o2 = impl.getOverlayInfo(OVERLAY2, USER); + assertNotNull(o2); assertEquals(1, o2.priority); + // Overlay priority changing between reboots should not affect enable state of mutable + // overlays + impl.setEnabled(OVERLAY, true, USER); + + // Reorder the overlays addOverlayPackage(OVERLAY, TARGET, USER, false, true, 1); addOverlayPackage(OVERLAY2, TARGET, USER, false, true, 0); impl.updateOverlaysForUser(USER); final OverlayInfo o3 = impl.getOverlayInfo(OVERLAY, USER); - final OverlayInfo o4 = impl.getOverlayInfo(OVERLAY2, USER); assertNotNull(o3); - assertNotNull(o4); assertEquals(1, o3.priority); + + final OverlayInfo o4 = impl.getOverlayInfo(OVERLAY2, USER); + assertNotNull(o4); assertEquals(0, o4.priority); + assertTrue(o1.isEnabled()); } } |