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
This commit is contained in:
Jaekyun Seok
2017-03-02 15:24:19 +09:00
parent 58277fab89
commit 0434289c45
11 changed files with 90 additions and 13 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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\

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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);

View File

@@ -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

View File

@@ -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">

View File

@@ -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);
}