Loading api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -1197,6 +1197,8 @@ package android { field public static final int requiredFeature = 16844119; // 0x1010557 field public static final int requiredForAllUsers = 16843728; // 0x10103d0 field public static final int requiredNotFeature = 16844120; // 0x1010558 field public static final int requiredSystemPropertyName = 16844136; // 0x1010568 field public static final int requiredSystemPropertyValue = 16844137; // 0x1010569 field public static final int requiresFadingEdge = 16843685; // 0x10103a5 field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364 field public static final int resizeClip = 16843983; // 0x10104cf cmds/idmap/scan.cpp +37 −27 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <androidfw/StreamingZipInflater.h> #include <androidfw/ZipFileRO.h> #include <cutils/jstring.h> #include <cutils/properties.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM #include <utils/SortedVector.h> #include <utils/String16.h> Loading Loading @@ -82,12 +83,26 @@ namespace { return String8(tmp); } bool check_property(String16 property, String16 value) { const char *prop; const char *val; prop = strndup16to8(property.string(), property.size()); char propBuf[PROPERTY_VALUE_MAX]; property_get(prop, propBuf, NULL); val = strndup16to8(value.string(), value.size()); return (strcmp(propBuf, val) == 0); } int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name, bool* is_static_overlay) { const size_t N = parser.getAttributeCount(); String16 target; int priority = -1; String16 propName = String16(); String16 propValue = String16(); for (size_t i = 0; i < N; ++i) { size_t len; String16 key(parser.getAttributeName(i, &len)); Loading @@ -109,34 +124,32 @@ namespace { if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { *is_static_overlay = (v.data != 0); } } else if (key == String16("requiredSystemPropertyName")) { const char16_t *p = parser.getAttributeStringValue(i, &len); if (p != NULL) { propName = String16(p, len); } } if (target == String16(target_package_name)) { return priority; } 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")) { } else if (key == String16("requiredSystemPropertyValue")) { const char16_t *p = parser.getAttributeStringValue(i, &len); if (p != NULL) { package_name = String16(p, len); propValue = String16(p, len); } } } // Note that conditional property enablement/exclusion only applies if // the attribute is present. In its absence, all overlays are presumed enabled. if (propName.size() > 0 && propValue.size() > 0) { // if property set & equal to value, then include overlay - otherwise skip if (!check_property(propName, propValue)) { return NO_OVERLAY_TAG; } 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; if (target == String16(target_package_name)) { return priority; } return NO_OVERLAY_TAG; } int parse_manifest(const void *data, size_t size, const char *target_package_name) Loading @@ -149,7 +162,6 @@ namespace { } ResXMLParser::event_code_t type; String16 package_name; bool is_static_overlay = false; int priority = NO_OVERLAY_TAG; do { Loading @@ -157,16 +169,14 @@ namespace { if (type == ResXMLParser::START_TAG) { size_t len; String16 tag(parser.getElementName(&len)); if (tag == String16("manifest")) { package_name = parse_package_name(parser); } else if (tag == String16("overlay")) { 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)) { if (is_static_overlay) { return priority; } return NO_OVERLAY_TAG; Loading core/java/android/content/pm/PackageParser.java +35 −2 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.os.FileUtils; import android.os.Parcel; import android.os.Parcelable; import android.os.PatternMatcher; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.system.ErrnoException; Loading Loading @@ -2111,6 +2112,12 @@ public class PackageParser { pkg.mIsStaticOverlay = sa.getBoolean( com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic, false); final String propName = sa.getString( com.android.internal.R.styleable .AndroidManifestResourceOverlay_requiredSystemPropertyName); final String propValue = sa.getString( com.android.internal.R.styleable .AndroidManifestResourceOverlay_requiredSystemPropertyValue); sa.recycle(); if (pkg.mOverlayTarget == null) { Loading @@ -2118,15 +2125,22 @@ 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. // check to see if overlay should be excluded based on system property condition if (!checkOverlayRequiredSystemProperty(propName, propValue)) { Slog.i(TAG, "Skipping target and overlay pair " + pkg.mOverlayTarget + " and " + pkg.baseCodePath+ ": overlay ignored due to required system property: " + propName + " with value: " + propValue); return null; } XmlUtils.skipCurrentTag(parser); } else if (tagName.equals(TAG_KEY_SETS)) { Loading Loading @@ -2531,6 +2545,25 @@ public class PackageParser { return pkg; } private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) { if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) { if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) { // malformed condition - incomplete Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName + "=" + propValue + "' - require both requiredSystemPropertyName" + " AND requiredSystemPropertyValue to be specified."); return false; } // no valid condition set - so no exclusion criteria, overlay will be included. return true; } // check property value - make sure it is both set and equal to expected value final String currValue = SystemProperties.get(propName); return (currValue != null && currValue.equals(propValue)); } /** * This is a pre-density application which will get scaled - instead of being pixel perfect. * This type of application is not resizable. Loading core/res/res/values/attrs_manifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -2439,6 +2439,14 @@ <!-- Whether the given RRO is static or not. --> <attr name="isStatic" format="boolean" /> <!-- Required property name/value pair used to enable this overlay. e.g. name=ro.oem.sku value=MKT210. Overlay will be ignored unless system property exists and is set to specified value --> <!-- @hide @SystemApi This shouldn't be public. --> <attr name="requiredSystemPropertyName" format="string" /> <!-- @hide @SystemApi This shouldn't be public. --> <attr name="requiredSystemPropertyValue" format="string" /> </declare-styleable> <!-- Declaration of an {@link android.content.Intent} object in XML. May Loading core/res/res/values/public.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2817,6 +2817,10 @@ <public name="defaultFocusHighlightEnabled" /> <public name="persistentFeature"/> <public name="windowSplashscreenContent" /> <!-- @hide @SystemApi --> <public name="requiredSystemPropertyName" /> <!-- @hide @SystemApi --> <public name="requiredSystemPropertyValue" /> </public-group> <public-group type="style" first-id="0x010302e0"> Loading Loading
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -1197,6 +1197,8 @@ package android { field public static final int requiredFeature = 16844119; // 0x1010557 field public static final int requiredForAllUsers = 16843728; // 0x10103d0 field public static final int requiredNotFeature = 16844120; // 0x1010558 field public static final int requiredSystemPropertyName = 16844136; // 0x1010568 field public static final int requiredSystemPropertyValue = 16844137; // 0x1010569 field public static final int requiresFadingEdge = 16843685; // 0x10103a5 field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364 field public static final int resizeClip = 16843983; // 0x10104cf
cmds/idmap/scan.cpp +37 −27 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <androidfw/StreamingZipInflater.h> #include <androidfw/ZipFileRO.h> #include <cutils/jstring.h> #include <cutils/properties.h> #include <private/android_filesystem_config.h> // for AID_SYSTEM #include <utils/SortedVector.h> #include <utils/String16.h> Loading Loading @@ -82,12 +83,26 @@ namespace { return String8(tmp); } bool check_property(String16 property, String16 value) { const char *prop; const char *val; prop = strndup16to8(property.string(), property.size()); char propBuf[PROPERTY_VALUE_MAX]; property_get(prop, propBuf, NULL); val = strndup16to8(value.string(), value.size()); return (strcmp(propBuf, val) == 0); } int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name, bool* is_static_overlay) { const size_t N = parser.getAttributeCount(); String16 target; int priority = -1; String16 propName = String16(); String16 propValue = String16(); for (size_t i = 0; i < N; ++i) { size_t len; String16 key(parser.getAttributeName(i, &len)); Loading @@ -109,34 +124,32 @@ namespace { if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { *is_static_overlay = (v.data != 0); } } else if (key == String16("requiredSystemPropertyName")) { const char16_t *p = parser.getAttributeStringValue(i, &len); if (p != NULL) { propName = String16(p, len); } } if (target == String16(target_package_name)) { return priority; } 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")) { } else if (key == String16("requiredSystemPropertyValue")) { const char16_t *p = parser.getAttributeStringValue(i, &len); if (p != NULL) { package_name = String16(p, len); propValue = String16(p, len); } } } // Note that conditional property enablement/exclusion only applies if // the attribute is present. In its absence, all overlays are presumed enabled. if (propName.size() > 0 && propValue.size() > 0) { // if property set & equal to value, then include overlay - otherwise skip if (!check_property(propName, propValue)) { return NO_OVERLAY_TAG; } 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; if (target == String16(target_package_name)) { return priority; } return NO_OVERLAY_TAG; } int parse_manifest(const void *data, size_t size, const char *target_package_name) Loading @@ -149,7 +162,6 @@ namespace { } ResXMLParser::event_code_t type; String16 package_name; bool is_static_overlay = false; int priority = NO_OVERLAY_TAG; do { Loading @@ -157,16 +169,14 @@ namespace { if (type == ResXMLParser::START_TAG) { size_t len; String16 tag(parser.getElementName(&len)); if (tag == String16("manifest")) { package_name = parse_package_name(parser); } else if (tag == String16("overlay")) { 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)) { if (is_static_overlay) { return priority; } return NO_OVERLAY_TAG; Loading
core/java/android/content/pm/PackageParser.java +35 −2 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.os.FileUtils; import android.os.Parcel; import android.os.Parcelable; import android.os.PatternMatcher; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.system.ErrnoException; Loading Loading @@ -2111,6 +2112,12 @@ public class PackageParser { pkg.mIsStaticOverlay = sa.getBoolean( com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic, false); final String propName = sa.getString( com.android.internal.R.styleable .AndroidManifestResourceOverlay_requiredSystemPropertyName); final String propValue = sa.getString( com.android.internal.R.styleable .AndroidManifestResourceOverlay_requiredSystemPropertyValue); sa.recycle(); if (pkg.mOverlayTarget == null) { Loading @@ -2118,15 +2125,22 @@ 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. // check to see if overlay should be excluded based on system property condition if (!checkOverlayRequiredSystemProperty(propName, propValue)) { Slog.i(TAG, "Skipping target and overlay pair " + pkg.mOverlayTarget + " and " + pkg.baseCodePath+ ": overlay ignored due to required system property: " + propName + " with value: " + propValue); return null; } XmlUtils.skipCurrentTag(parser); } else if (tagName.equals(TAG_KEY_SETS)) { Loading Loading @@ -2531,6 +2545,25 @@ public class PackageParser { return pkg; } private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) { if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) { if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) { // malformed condition - incomplete Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName + "=" + propValue + "' - require both requiredSystemPropertyName" + " AND requiredSystemPropertyValue to be specified."); return false; } // no valid condition set - so no exclusion criteria, overlay will be included. return true; } // check property value - make sure it is both set and equal to expected value final String currValue = SystemProperties.get(propName); return (currValue != null && currValue.equals(propValue)); } /** * This is a pre-density application which will get scaled - instead of being pixel perfect. * This type of application is not resizable. Loading
core/res/res/values/attrs_manifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -2439,6 +2439,14 @@ <!-- Whether the given RRO is static or not. --> <attr name="isStatic" format="boolean" /> <!-- Required property name/value pair used to enable this overlay. e.g. name=ro.oem.sku value=MKT210. Overlay will be ignored unless system property exists and is set to specified value --> <!-- @hide @SystemApi This shouldn't be public. --> <attr name="requiredSystemPropertyName" format="string" /> <!-- @hide @SystemApi This shouldn't be public. --> <attr name="requiredSystemPropertyValue" format="string" /> </declare-styleable> <!-- Declaration of an {@link android.content.Intent} object in XML. May Loading
core/res/res/values/public.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2817,6 +2817,10 @@ <public name="defaultFocusHighlightEnabled" /> <public name="persistentFeature"/> <public name="windowSplashscreenContent" /> <!-- @hide @SystemApi --> <public name="requiredSystemPropertyName" /> <!-- @hide @SystemApi --> <public name="requiredSystemPropertyValue" /> </public-group> <public-group type="style" first-id="0x010302e0"> Loading