diff options
-rw-r--r-- | api/current.txt | 3 | ||||
-rw-r--r-- | api/system-current.txt | 3 | ||||
-rw-r--r-- | api/test-current.txt | 3 | ||||
-rw-r--r-- | cmds/idmap/Android.mk | 2 | ||||
-rw-r--r-- | cmds/idmap/idmap.cpp | 4 | ||||
-rw-r--r-- | cmds/idmap/scan.cpp | 44 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageInfo.java | 5 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 10 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 3 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/om/OverlayManagerServiceImpl.java | 25 |
11 files changed, 90 insertions, 13 deletions
diff --git a/api/current.txt b/api/current.txt index 4981c432efc8..dd36388488f9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -751,6 +751,7 @@ package android { field public static final int isModifier = 16843334; // 0x1010246 field public static final int isRepeatable = 16843336; // 0x1010248 field public static final int isScrollContainer = 16843342; // 0x101024e + field public static final int isStatic = 16844125; // 0x101055d field public static final int isSticky = 16843335; // 0x1010247 field public static final int isolatedProcess = 16843689; // 0x10103a9 field public static final int isolatedSplits = 16844109; // 0x101054d @@ -25193,8 +25194,8 @@ package android.net { method public void reportNetworkConnectivity(android.net.Network, boolean); method public boolean requestBandwidthUpdate(android.net.Network); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); - method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); + method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); method public deprecated void setNetworkPreference(int); diff --git a/api/system-current.txt b/api/system-current.txt index fbfee83e67cd..63cd0f221a98 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -864,6 +864,7 @@ package android { field public static final int isModifier = 16843334; // 0x1010246 field public static final int isRepeatable = 16843336; // 0x1010248 field public static final int isScrollContainer = 16843342; // 0x101024e + field public static final int isStatic = 16844125; // 0x101055d field public static final int isSticky = 16843335; // 0x1010247 field public static final int isolatedProcess = 16843689; // 0x10103a9 field public static final int isolatedSplits = 16844109; // 0x101054d @@ -27312,8 +27313,8 @@ package android.net { method public void reportNetworkConnectivity(android.net.Network, boolean); method public boolean requestBandwidthUpdate(android.net.Network); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); - method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); + method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); method public deprecated void setNetworkPreference(int); diff --git a/api/test-current.txt b/api/test-current.txt index 3be7f6793001..ad5672c2ddf9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -751,6 +751,7 @@ package android { field public static final int isModifier = 16843334; // 0x1010246 field public static final int isRepeatable = 16843336; // 0x1010248 field public static final int isScrollContainer = 16843342; // 0x101024e + field public static final int isStatic = 16844125; // 0x101055d field public static final int isSticky = 16843335; // 0x1010247 field public static final int isolatedProcess = 16843689; // 0x10103a9 field public static final int isolatedSplits = 16844109; // 0x101054d @@ -25294,8 +25295,8 @@ package android.net { method public void reportNetworkConnectivity(android.net.Network, boolean); method public boolean requestBandwidthUpdate(android.net.Network); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); - method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); + method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); method public deprecated void setNetworkPreference(int); diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk index 50ccb07a3826..aeb8a0c001ec 100644 --- a/cmds/idmap/Android.mk +++ b/cmds/idmap/Android.mk @@ -17,7 +17,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := idmap.cpp create.cpp scan.cpp inspect.cpp -LOCAL_SHARED_LIBRARIES := liblog libutils libandroidfw +LOCAL_SHARED_LIBRARIES := liblog libutils libandroidfw libcutils LOCAL_MODULE := idmap diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp index 3ab191553625..3a237ffda775 100644 --- a/cmds/idmap/idmap.cpp +++ b/cmds/idmap/idmap.cpp @@ -49,8 +49,8 @@ OPTIONS \n\ --path: create idmap for target package 'target' (path to apk) and overlay package \n\ 'overlay' (path to apk); write results to 'idmap' (path). \n\ \n\ - --scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\ - target package 'target-package-name-to-look-for' (package name) present at\n\ + --scan: non-recursively search directory 'dir-to-scan' (path) for static overlay packages \n\ + with target package 'target-package-name-to-look-for' (package name) present at\n\ 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\ idmap file in 'dir-to-hold-idmaps' (path). \n\ \n\ diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index 8122395d8061..67874a8b9c02 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -9,6 +9,7 @@ #include <androidfw/ResourceTypes.h> #include <androidfw/StreamingZipInflater.h> #include <androidfw/ZipFileRO.h> +#include <cutils/jstring.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM #include <utils/SortedVector.h> #include <utils/String16.h> @@ -81,7 +82,8 @@ namespace { return String8(tmp); } - int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name) + int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name, + bool* is_static_overlay) { const size_t N = parser.getAttributeCount(); String16 target; @@ -102,6 +104,11 @@ namespace { return -1; } } + } else if (key == String16("isStatic")) { + Res_value v; + if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { + *is_static_overlay = (v.data != 0); + } } } if (target == String16(target_package_name)) { @@ -110,6 +117,28 @@ namespace { return NO_OVERLAY_TAG; } + String16 parse_package_name(const ResXMLTree& parser) + { + const size_t N = parser.getAttributeCount(); + String16 package_name; + for (size_t i = 0; i < N; ++i) { + size_t len; + String16 key(parser.getAttributeName(i, &len)); + if (key == String16("package")) { + const char16_t *p = parser.getAttributeStringValue(i, &len); + if (p != NULL) { + package_name = String16(p, len); + } + } + } + return package_name; + } + + bool isValidStaticOverlayPackage(const String16& package_name) { + // TODO(b/35742444): Need to support selection method based on a package name. + return package_name.size() > 0; + } + int parse_manifest(const void *data, size_t size, const char *target_package_name) { ResXMLTree parser; @@ -120,17 +149,26 @@ namespace { } ResXMLParser::event_code_t type; + String16 package_name; + bool is_static_overlay = false; + int priority = NO_OVERLAY_TAG; do { type = parser.next(); if (type == ResXMLParser::START_TAG) { size_t len; String16 tag(parser.getElementName(&len)); - if (tag == String16("overlay")) { - return parse_overlay_tag(parser, target_package_name); + if (tag == String16("manifest")) { + package_name = parse_package_name(parser); + } else if (tag == String16("overlay")) { + priority = parse_overlay_tag(parser, target_package_name, &is_static_overlay); + break; } } } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT); + if (is_static_overlay && isValidStaticOverlayPackage(package_name)) { + return priority; + } return NO_OVERLAY_TAG; } diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 5d5696b5a54e..8ff2f352a362 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -271,6 +271,9 @@ public class PackageInfo implements Parcelable { */ public String overlayTarget; + /** @hide */ + public boolean isStaticOverlay; + public PackageInfo() { } @@ -323,6 +326,7 @@ public class PackageInfo implements Parcelable { dest.writeString(restrictedAccountType); dest.writeString(requiredAccountType); dest.writeString(overlayTarget); + dest.writeInt(isStaticOverlay ? 1 : 0); } public static final Parcelable.Creator<PackageInfo> CREATOR @@ -372,6 +376,7 @@ public class PackageInfo implements Parcelable { restrictedAccountType = source.readString(); requiredAccountType = source.readString(); overlayTarget = source.readString(); + isStaticOverlay = source.readInt() != 0; // 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 a1c325ac26ea..e15a0e240711 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -603,6 +603,7 @@ public class PackageParser { pi.restrictedAccountType = p.mRestrictedAccountType; pi.requiredAccountType = p.mRequiredAccountType; pi.overlayTarget = p.mOverlayTarget; + pi.isStaticOverlay = p.mIsStaticOverlay; pi.firstInstallTime = firstInstallTime; pi.lastUpdateTime = lastUpdateTime; if ((flags&PackageManager.GET_GIDS) != 0) { @@ -2097,6 +2098,9 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestResourceOverlay); pkg.mOverlayTarget = sa.getString( com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage); + pkg.mIsStaticOverlay = sa.getBoolean( + com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic, + false); sa.recycle(); if (pkg.mOverlayTarget == null) { @@ -2104,6 +2108,9 @@ public class PackageParser { 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. + } XmlUtils.skipCurrentTag(parser); } else if (tagName.equals(TAG_KEY_SETS)) { @@ -5580,6 +5587,7 @@ public class PackageParser { public String mRequiredAccountType; public String mOverlayTarget; + public boolean mIsStaticOverlay; public boolean mTrustedOverlay; /** @@ -6056,6 +6064,7 @@ public class PackageParser { mRestrictedAccountType = dest.readString(); mRequiredAccountType = dest.readString(); mOverlayTarget = dest.readString(); + mIsStaticOverlay = (dest.readInt() == 1); mTrustedOverlay = (dest.readInt() == 1); mSigningKeys = (ArraySet<PublicKey>) dest.readArraySet(boot); mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot); @@ -6171,6 +6180,7 @@ public class PackageParser { dest.writeString(mRestrictedAccountType); dest.writeString(mRequiredAccountType); dest.writeString(mOverlayTarget); + dest.writeInt(mIsStaticOverlay ? 1 : 0); dest.writeInt(mTrustedOverlay ? 1 : 0); dest.writeArraySet(mSigningKeys); dest.writeArraySet(mUpgradeKeySets); diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index bfe666eed6e9..67050f751f5e 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2401,6 +2401,9 @@ <!-- Load order of overlay package. --> <attr name="priority" /> + <!-- Whether the given RRO is static or not. --> + <attr name="isStatic" format="boolean" /> + </declare-styleable> <!-- Declaration of an {@link android.content.Intent} object in XML. May diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index bb3f1c3b8c58..59432cd6e434 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2806,6 +2806,7 @@ <public name="fontProviderPackage" /> <public name="importantForAutofill" /> <public name="recycleEnabled"/> + <public name="isStatic" /> </public-group> <public-group type="style" first-id="0x010302e0"> diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index b085179c7fc5..6af1c3b20df2 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -288,6 +288,10 @@ final class OverlayManagerServiceImpl { if (overlayPackage == null) { return false; } + // Static overlay is always being enabled. + if (!enable && overlayPackage.isStaticOverlay) { + return false; + } try { final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId); @@ -333,17 +337,28 @@ final class OverlayManagerServiceImpl { } } + boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) { + final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId); + if (overlayPackage == null || overlayPackage.isStaticOverlay) { + return false; + } + return true; + } + boolean setPriority(@NonNull final String packageName, @NonNull final String newParentPackageName, final int userId) { - return mSettings.setPriority(packageName, newParentPackageName, userId); + return isPackageUpdatableOverlay(packageName, userId) && + mSettings.setPriority(packageName, newParentPackageName, userId); } boolean setHighestPriority(@NonNull final String packageName, final int userId) { - return mSettings.setHighestPriority(packageName, userId); + return isPackageUpdatableOverlay(packageName, userId) && + mSettings.setHighestPriority(packageName, userId); } boolean setLowestPriority(@NonNull final String packageName, final int userId) { - return mSettings.setLowestPriority(packageName, userId); + return isPackageUpdatableOverlay(packageName, userId) && + mSettings.setLowestPriority(packageName, userId); } void onDump(@NonNull final PrintWriter pw) { @@ -368,7 +383,9 @@ final class OverlayManagerServiceImpl { private void updateState(@Nullable final PackageInfo targetPackage, @NonNull final PackageInfo overlayPackage, final int userId) throws OverlayManagerSettings.BadKeyException { - if (targetPackage != null) { + // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers. + if (targetPackage != null && + !("android".equals(targetPackage.packageName) && overlayPackage.isStaticOverlay)) { mIdmapManager.createIdmap(targetPackage, overlayPackage, userId); } |