Apply static RRO
Static RRO package is designed to support resource overlay for system
server and they shouldn't be disabled or changed by a user.
The design details are in go/treble-static-rro.
Selection method for static RROs will be applied later when its design
is determined.
Test: building succeeded and tested on sailfish.
Bug: 35742444
Change-Id: I8cbf2fd37a73a24bf6ad291e2c5cf75a0fc757fc
diff --git a/api/current.txt b/api/current.txt
index 4981c43..dd36388 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -751,6 +751,7 @@
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 @@
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 fbfee83..63cd0f2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -864,6 +864,7 @@
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 @@
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 3be7f67..ad5672c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -751,6 +751,7 @@
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 @@
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 50ccb07..aeb8a0c 100644
--- a/cmds/idmap/Android.mk
+++ b/cmds/idmap/Android.mk
@@ -17,7 +17,7 @@
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 3ab1915..3a237ff 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -49,8 +49,8 @@
--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 8122395..67874a8 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 @@
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 @@
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 @@
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 @@
}
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 5d5696b..8ff2f35 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -271,6 +271,9 @@
*/
public String overlayTarget;
+ /** @hide */
+ public boolean isStaticOverlay;
+
public PackageInfo() {
}
@@ -323,6 +326,7 @@
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 @@
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 a1c325a..e15a0e2 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -603,6 +603,7 @@
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 @@
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 @@
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 String mRequiredAccountType;
public String mOverlayTarget;
+ public boolean mIsStaticOverlay;
public boolean mTrustedOverlay;
/**
@@ -6056,6 +6064,7 @@
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 @@
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 bfe666e..67050f7 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 bb3f1c3..59432cd 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 b085179..6af1c3b 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 @@
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 @@
}
}
+ 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 @@
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);
}