summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/content/om/OverlayConfig.java29
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java11
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerSettings.java56
-rw-r--r--services/tests/servicestests/src/com/android/server/om/OverlayManagerServiceImplRebootTests.java95
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());
}
}