diff options
4 files changed, 67 insertions, 9 deletions
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 8ff2f352a362..7f1198541668 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -272,6 +272,9 @@ public class PackageInfo implements Parcelable { public String overlayTarget; /** @hide */ + public int overlayPriority; + + /** @hide */ public boolean isStaticOverlay; public PackageInfo() { @@ -327,6 +330,7 @@ public class PackageInfo implements Parcelable { dest.writeString(requiredAccountType); dest.writeString(overlayTarget); dest.writeInt(isStaticOverlay ? 1 : 0); + dest.writeInt(overlayPriority); } public static final Parcelable.Creator<PackageInfo> CREATOR @@ -377,6 +381,7 @@ public class PackageInfo implements Parcelable { requiredAccountType = source.readString(); overlayTarget = source.readString(); isStaticOverlay = source.readInt() != 0; + overlayPriority = source.readInt(); // The component lists were flattened with the redundant ApplicationInfo // instances omitted. Distribute the canonical one here as appropriate. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index d44d0dcf00f2..e64b2a56a277 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -629,6 +629,7 @@ public class PackageParser { pi.restrictedAccountType = p.mRestrictedAccountType; pi.requiredAccountType = p.mRequiredAccountType; pi.overlayTarget = p.mOverlayTarget; + pi.overlayPriority = p.mOverlayPriority; pi.isStaticOverlay = p.mIsStaticOverlay; pi.firstInstallTime = firstInstallTime; pi.lastUpdateTime = lastUpdateTime; @@ -2104,6 +2105,9 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestResourceOverlay); pkg.mOverlayTarget = sa.getString( com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage); + pkg.mOverlayPriority = sa.getInt( + com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority, + 0); pkg.mIsStaticOverlay = sa.getBoolean( com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic, false); @@ -2114,6 +2118,12 @@ public class PackageParser { mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; return null; } + if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) { + outError[0] = "<overlay> priority must be between 0 and 9999"; + mParseError = + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; + return null; + } if (pkg.mIsStaticOverlay) { // TODO(b/35742444): Need to support selection method based on a package name. } @@ -5681,6 +5691,7 @@ public class PackageParser { public String mRequiredAccountType; public String mOverlayTarget; + public int mOverlayPriority; public boolean mIsStaticOverlay; public boolean mTrustedOverlay; @@ -6163,6 +6174,7 @@ public class PackageParser { mRestrictedAccountType = dest.readString(); mRequiredAccountType = dest.readString(); mOverlayTarget = dest.readString(); + mOverlayPriority = dest.readInt(); mIsStaticOverlay = (dest.readInt() == 1); mTrustedOverlay = (dest.readInt() == 1); mSigningKeys = (ArraySet<PublicKey>) dest.readArraySet(boot); @@ -6280,6 +6292,7 @@ public class PackageParser { dest.writeString(mRestrictedAccountType); dest.writeString(mRequiredAccountType); dest.writeString(mOverlayTarget); + dest.writeInt(mOverlayPriority); dest.writeInt(mIsStaticOverlay ? 1 : 0); dest.writeInt(mTrustedOverlay ? 1 : 0); dest.writeArraySet(mSigningKeys); diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index c536278d1499..b2036741efcb 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -101,7 +101,8 @@ final class OverlayManagerServiceImpl { // Update the overlay if it didn't exist or had the wrong target package. mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, - overlayPackage.applicationInfo.getBaseCodePath()); + overlayPackage.applicationInfo.getBaseCodePath(), + overlayPackage.isStaticOverlay, overlayPackage.overlayPriority); if (oi == null) { // This overlay does not exist in our settings. @@ -243,7 +244,8 @@ final class OverlayManagerServiceImpl { mPackageManager.getPackageInfo(overlayPackage.overlayTarget, userId); mSettings.init(packageName, userId, overlayPackage.overlayTarget, - overlayPackage.applicationInfo.getBaseCodePath()); + overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlay, + overlayPackage.overlayPriority); try { if (updateState(targetPackage, overlayPackage, userId)) { mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId); diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index 2cafa39aff6e..72979f69a47d 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -60,11 +60,29 @@ final class OverlayManagerSettings { private final ArrayList<SettingsItem> mItems = new ArrayList<>(); void init(@NonNull final String packageName, final int userId, - @NonNull final String targetPackageName, @NonNull final String baseCodePath) { + @NonNull final String targetPackageName, @NonNull final String baseCodePath, + boolean isStatic, int priority) { remove(packageName, userId); final SettingsItem item = - new SettingsItem(packageName, userId, targetPackageName, baseCodePath); - mItems.add(item); + new SettingsItem(packageName, userId, targetPackageName, baseCodePath, + isStatic, priority); + if (isStatic) { + int i; + for (i = mItems.size() - 1; i >= 0; i--) { + SettingsItem parentItem = mItems.get(i); + if (parentItem.mIsStatic && parentItem.mPriority <= priority) { + break; + } + } + int pos = i + 1; + if (pos == mItems.size()) { + mItems.add(item); + } else { + mItems.add(pos, item); + } + } else { + mItems.add(item); + } } /** @@ -286,6 +304,8 @@ final class OverlayManagerSettings { private static final String ATTR_PACKAGE_NAME = "packageName"; private static final String ATTR_STATE = "state"; private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName"; + private static final String ATTR_IS_STATIC = "isStatic"; + private static final String ATTR_PRIORITY = "priority"; private static final String ATTR_USER_ID = "userId"; private static final String ATTR_VERSION = "version"; @@ -337,9 +357,11 @@ final class OverlayManagerSettings { final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH); final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE); final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED); + final boolean isStatic = XmlUtils.readBooleanAttribute(parser, ATTR_IS_STATIC); + final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY); return new SettingsItem(packageName, userId, targetPackageName, baseCodePath, state, - isEnabled); + isEnabled, isStatic, priority); } public static void persist(@NonNull final ArrayList<SettingsItem> table, @@ -369,6 +391,8 @@ final class OverlayManagerSettings { XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.mBaseCodePath); XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.mState); XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled); + XmlUtils.writeBooleanAttribute(xml, ATTR_IS_STATIC, item.mIsStatic); + XmlUtils.writeIntAttribute(xml, ATTR_PRIORITY, item.mPriority); xml.endTag(null, TAG_ITEM); } } @@ -381,10 +405,13 @@ final class OverlayManagerSettings { private int mState; private boolean mIsEnabled; private OverlayInfo mCache; + private boolean mIsStatic; + private int mPriority; SettingsItem(@NonNull final String packageName, final int userId, @NonNull final String targetPackageName, @NonNull final String baseCodePath, - final int state, final boolean isEnabled) { + final int state, final boolean isEnabled, final boolean isStatic, + final int priority) { mPackageName = packageName; mUserId = userId; mTargetPackageName = targetPackageName; @@ -392,12 +419,15 @@ final class OverlayManagerSettings { mState = state; mIsEnabled = isEnabled; mCache = null; + mIsStatic = isStatic; + mPriority = priority; } SettingsItem(@NonNull final String packageName, final int userId, - @NonNull final String targetPackageName, @NonNull final String baseCodePath) { + @NonNull final String targetPackageName, @NonNull final String baseCodePath, + final boolean isStatic, final int priority) { this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN, - false); + false, isStatic, priority); } private String getTargetPackageName() { @@ -458,6 +488,14 @@ final class OverlayManagerSettings { private void invalidateCache() { mCache = null; } + + private boolean isStatic() { + return mIsStatic; + } + + private int getPriority() { + return mPriority; + } } private int select(@NonNull final String packageName, final int userId) { |