diff options
author | 2017-03-16 14:00:52 -0700 | |
---|---|---|
committer | 2017-04-13 19:33:11 -0700 | |
commit | d5566c6c47faa6b9dda282741e25ac78c9487d58 (patch) | |
tree | fc666ea0f61f1e82909cd5a4f90a0774b9de9c8c | |
parent | f9993a7b4490df05381a0a097100233f70adcdac (diff) |
OEM single-build/multi-SKU via dynamic RRO support
The purpose here is to provide support for selectively
enabling Runtime Resource Overlays (RROs) (specifically
those pertaining to a specific SKU, within a OEM's "single
build" covering multiple SKUs) at boot based on the value
of a pre-defined system property.
This mechanism is designed to be compatible with other,
recent changes to Runtime Resource Overlays - specifically:
- has no effect on 'isStatic'. Resource overlays must be
attributed as static in order to qualify for loading into
the system_server. The 'requiredSystemPropertyName/
requiredSystemPropertyValue' mechanism operates
independent of this and can be used on both static and
non static overlays. The effect of specifying a conditional
property on any overlay is that it will ONLY be enabled
in the event that the system reflects both the property
and the specified value (Note that in the ABSENCE of a
conditional property, overlays are assumed to be enabled).
- has no effect on OverlayManagerService (OMS) API. The
OMS provides the system with an interface through which
overlays can be enabled/disabled and even rearranged at
runtime. This provides the basis of support for various
user-level features (e.g. dynamic theme selection).
The 'requiredSystemPropertyName/requiredSystemPropertyValue'
mechanism operates independent of this -
with enablement being completely coupled to the available
system properties on the device and NOT subject to change
at runtime.
Note: as part of this change, original overlay tests have been
updated (fixed) and expanded to include tests to cover the
conditional property implementation.
Issue: http://b/35100249
Test: frameworks/base/core/tests/overlaytests/testrunner.py
Change-Id: I1990ce21a27a385db1e2f53294b69dd03988351e
-rw-r--r-- | api/system-current.txt | 2 | ||||
-rw-r--r-- | cmds/idmap/scan.cpp | 64 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 37 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 8 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 4 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFiltered/Android.mk | 12 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml | 9 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt | 1 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml | 4 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml | 2 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppFirst/Android.mk | 2 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayAppSecond/Android.mk | 2 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayTest/Android.mk | 2 | ||||
-rw-r--r-- | core/tests/overlaytests/OverlayTestOverlay/Android.mk | 2 | ||||
-rwxr-xr-x | core/tests/overlaytests/testrunner.py | 79 |
15 files changed, 185 insertions, 45 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 3924f6396426..8274e79fa662 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1195,6 +1195,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 diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index 67874a8b9c02..d69dd79555a1 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -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> @@ -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)); @@ -109,34 +124,32 @@ namespace { if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { *is_static_overlay = (v.data != 0); } - } - } - 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("requiredSystemPropertyName")) { const char16_t *p = parser.getAttributeStringValue(i, &len); if (p != NULL) { - package_name = String16(p, len); + propName = String16(p, len); + } + } else if (key == String16("requiredSystemPropertyValue")) { + const char16_t *p = parser.getAttributeStringValue(i, &len); + if (p != NULL) { + propValue = 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; + // 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; + } + } + + 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) @@ -149,7 +162,6 @@ namespace { } ResXMLParser::event_code_t type; - String16 package_name; bool is_static_overlay = false; int priority = NO_OVERLAY_TAG; do { @@ -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; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 11c658a1d4cf..cc0bf0db164a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -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; @@ -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) { @@ -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)) { @@ -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. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 569646820402..95ba94209343 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -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 diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index d6ed1786e760..675edd4f5326 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -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"> diff --git a/core/tests/overlaytests/OverlayAppFiltered/Android.mk b/core/tests/overlaytests/OverlayAppFiltered/Android.mk new file mode 100644 index 000000000000..8ba21df189f0 --- /dev/null +++ b/core/tests/overlaytests/OverlayAppFiltered/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_JAVA_LIBRARIES += legacy-test + +LOCAL_SDK_VERSION := system_current + +LOCAL_PACKAGE_NAME := com.android.overlaytest.filtered_app_overlay + +include $(BUILD_PACKAGE) diff --git a/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml b/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml new file mode 100644 index 000000000000..5b7950a25fbf --- /dev/null +++ b/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml @@ -0,0 +1,9 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.overlaytest.filtered_app_overlay" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="com.android.overlaytest" + android:requiredSystemPropertyName="persist.oem.overlay.test" + android:requiredSystemPropertyValue="foo" + android:priority="3"/> +</manifest> diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt b/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt new file mode 100644 index 000000000000..0954cedeb5d5 --- /dev/null +++ b/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt @@ -0,0 +1 @@ +Lorem ipsum: filtered overlays. diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml b/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml new file mode 100644 index 000000000000..60b94eec5994 --- /dev/null +++ b/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="str">filtered</string> +</resources> diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml b/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml new file mode 100644 index 000000000000..e2652b7e2915 --- /dev/null +++ b/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8"?> +<integer value="3"/> diff --git a/core/tests/overlaytests/OverlayAppFirst/Android.mk b/core/tests/overlaytests/OverlayAppFirst/Android.mk index ee991fcd919a..51f4487fb25f 100644 --- a/core/tests/overlaytests/OverlayAppFirst/Android.mk +++ b/core/tests/overlaytests/OverlayAppFirst/Android.mk @@ -3,7 +3,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_JAVA_LIBRARIES += legacy-test LOCAL_SDK_VERSION := current diff --git a/core/tests/overlaytests/OverlayAppSecond/Android.mk b/core/tests/overlaytests/OverlayAppSecond/Android.mk index 87402c43dd9a..b3cfd1817cbf 100644 --- a/core/tests/overlaytests/OverlayAppSecond/Android.mk +++ b/core/tests/overlaytests/OverlayAppSecond/Android.mk @@ -3,7 +3,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_JAVA_LIBRARIES += legacy-test LOCAL_SDK_VERSION := current diff --git a/core/tests/overlaytests/OverlayTest/Android.mk b/core/tests/overlaytests/OverlayTest/Android.mk index 4767e52c0816..964348fab881 100644 --- a/core/tests/overlaytests/OverlayTest/Android.mk +++ b/core/tests/overlaytests/OverlayTest/Android.mk @@ -7,6 +7,8 @@ LOCAL_PACKAGE_NAME := OverlayTest LOCAL_DEX_PREOPT := false +LOCAL_JAVA_LIBRARIES += legacy-test + LOCAL_MODULE_PATH := $(TARGET_OUT)/app LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk index b1327f713ae7..5265d9169f7f 100644 --- a/core/tests/overlaytests/OverlayTestOverlay/Android.mk +++ b/core/tests/overlaytests/OverlayTestOverlay/Android.mk @@ -3,7 +3,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_JAVA_LIBRARIES += legacy-test LOCAL_SDK_VERSION := current diff --git a/core/tests/overlaytests/testrunner.py b/core/tests/overlaytests/testrunner.py index 2aa25adeda5d..e88805e8cbf1 100755 --- a/core/tests/overlaytests/testrunner.py +++ b/core/tests/overlaytests/testrunner.py @@ -13,6 +13,7 @@ TASK_COMPILATION = 'compile' TASK_DISABLE_OVERLAYS = 'disable overlays' TASK_ENABLE_MULTIPLE_OVERLAYS = 'enable multiple overlays' TASK_ENABLE_SINGLE_OVERLAY = 'enable single overlay' +TASK_ENABLE_FILTERED_OVERLAYS = 'enable filtered overlays' TASK_FILE_EXISTS_TEST = 'test (file exists)' TASK_GREP_IDMAP_TEST = 'test (grep idmap)' TASK_MD5_TEST = 'test (md5)' @@ -25,6 +26,7 @@ TASK_PUSH = 'push' TASK_ROOT = 'root' TASK_REMOUNT = 'remount' TASK_RM = 'rm' +TASK_SETPROP = 'setprop' TASK_SETUP_IDMAP_PATH = 'setup idmap --path' TASK_SETUP_IDMAP_SCAN = 'setup idmap --scan' TASK_START = 'start' @@ -188,7 +190,10 @@ class PushTask: return "%s -> %s" % (self.src, self.dest) def execute(self): - src = os.getenv('OUT') + "/" + self.src + src = os.getenv('OUT') + if (src is None): + return 1, "", "Unable to proceed - $OUT environment var not set\n" + src += "/" + self.src argv = shlex.split(adb + ' push %s %s' % (src, self.dest)) proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = proc.communicate() @@ -219,10 +224,24 @@ class RmTask: def execute(self): returncode, stdout, stderr = _adb_shell('ls %s' % self.path) - if returncode != 0 and stdout.endswith(': No such file or directory\n'): + if returncode != 0 and stderr.endswith(': No such file or directory\n'): return 0, "", "" return _adb_shell('rm -r %s' % self.path) +class SetPropTask: + def __init__(self, prop, value): + self.prop = prop + self.value = value + + def get_type(self): + return TASK_SETPROP + + def get_name(self): + return self.prop + + def execute(self): + return _adb_shell('setprop %s %s' % (self.prop, self.value)) + class IdmapPathTask: def __init__(self, path_target_apk, path_overlay_apk, path_idmap): self.path_target_apk = path_target_apk @@ -236,7 +255,7 @@ class IdmapPathTask: return self.path_idmap def execute(self): - return _adb_shell('su system idmap --path "%s" "%s" "%s"' % (self.path_target_apk, self.path_overlay_apk, self.path_idmap)) + return _adb_shell('su system idmap --scan "%s" "%s" "%s" "%s"' % (self.target_pkg_name, self.target_pkg, self.idmap_dir, self.overlay_dir)) class IdmapScanTask: def __init__(self, overlay_dir, target_pkg_name, target_pkg, idmap_dir, symlink_dir): @@ -411,8 +430,12 @@ def _create_disable_overlays_task(): RmTask("/data/resource-cache/vendor@overlay@framework_b.apk@idmap"), RmTask("/vendor/overlay/app_a.apk"), RmTask("/vendor/overlay/app_b.apk"), + RmTask("/vendor/overlay/app_c.apk"), RmTask("/data/resource-cache/vendor@overlay@app_a.apk@idmap"), RmTask("/data/resource-cache/vendor@overlay@app_b.apk@idmap"), + RmTask("/data/resource-cache/vendor@overlay@app_c.apk@idmap"), + SetPropTask('persist.oem.overlay.test', '""'), + RmTask("/data/property/persist.oem.overlay.test"), ] return CompoundTask(TASK_DISABLE_OVERLAYS, tasks) @@ -435,9 +458,23 @@ def _create_enable_multiple_overlays_task(): PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'), PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'), PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'), + PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'), ] return CompoundTask(TASK_ENABLE_MULTIPLE_OVERLAYS, tasks) +def _create_enable_filtered_overlays_task(): + tasks = [ + _create_disable_overlays_task(), + SetPropTask('persist.oem.overlay.test', 'foo'), + MkdirTask('/system/vendor'), + MkdirTask('/vendor/overlay'), + PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'), + PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'), + PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'), + PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'), + ] + return CompoundTask(TASK_ENABLE_FILTERED_OVERLAYS, tasks) + def _create_setup_idmap_path_task(idmaps, symlinks): tasks = [ _create_enable_single_overlay_task(), @@ -450,12 +487,11 @@ def _create_setup_idmap_path_task(idmaps, symlinks): def _create_setup_idmap_scan_task(idmaps, symlinks): tasks = [ - _create_enable_single_overlay_task(), + _create_enable_filtered_overlays_task(), RmTask(symlinks), RmTask(idmaps), MkdirTask(idmaps), MkdirTask(symlinks), - _create_enable_multiple_overlays_task(), ] return CompoundTask(TASK_SETUP_IDMAP_SCAN, tasks) @@ -538,7 +574,7 @@ def _create_opt_parser(): help='do not rebuild test projects') parser.add_option('-i', '--test-idmap', action='store_true', dest='test_idmap', default=False, - help='run tests for single overlay') + help='run tests for idmap') parser.add_option('-0', '--test-no-overlay', action='store_true', dest='test_no_overlay', default=False, help='run tests without any overlay') @@ -548,16 +584,21 @@ def _create_opt_parser(): parser.add_option('-2', '--test-multiple-overlays', action='store_true', dest='test_multiple_overlays', default=False, help='run tests for multiple overlays') + parser.add_option('-3', '--test-filtered-overlays', action='store_true', + dest='test_filtered_overlays', default=False, + help='run tests for filtered (sys prop) overlays') return parser if __name__ == '__main__': opt_parser = _create_opt_parser() opts, args = opt_parser.parse_args(sys.argv[1:]) - if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays: + if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays and not opts.test_filtered_overlays: opts.test_idmap = True opts.test_no_overlay = True opts.test_single_overlay = True opts.test_multiple_overlays = True + opts.test_filtered_overlays = True + if len(args) > 0: opt_parser.error("unexpected arguments: %s" % " ".join(args)) # will never reach this: opt_parser.error will call sys.exit @@ -580,6 +621,7 @@ if __name__ == '__main__': tasks.append(CompilationTask('OverlayTestOverlay/Android.mk')) tasks.append(CompilationTask('OverlayAppFirst/Android.mk')) tasks.append(CompilationTask('OverlayAppSecond/Android.mk')) + tasks.append(CompilationTask('OverlayAppFiltered/Android.mk')) # remount filesystem, install test project tasks.append(RootTask()) @@ -600,13 +642,13 @@ if __name__ == '__main__': tasks.append(GrepIdmapTest(idmaps + '/a.idmap', 'bool/config_annoy_dianne', 1)) # idmap --scan - idmap = idmaps + '/vendor@overlay@framework_b.apk@idmap' tasks.append(StopTask()) tasks.append(_create_setup_idmap_scan_task(idmaps, symlinks)) tasks.append(StartTask()) tasks.append(IdmapScanTask('/vendor/overlay', 'android', '/system/framework/framework-res.apk', idmaps, symlinks)) - tasks.append(FileExistsTest(idmap)) - tasks.append(GrepIdmapTest(idmap, 'bool/config_annoy_dianne', 1)) + tasks.append(FileExistsTest(idmaps + '/vendor@overlay@framework_b.apk@idmap')) + tasks.append(GrepIdmapTest(idmaps + '/vendor@overlay@framework_b.apk@idmap', 'bool/config_annoy_dianne', 1)) + # overlays.list overlays_list_path = idmaps + '/overlays.list' @@ -620,27 +662,38 @@ if __name__ == '__main__': tasks.append(RmTask(symlinks)) tasks.append(RmTask(idmaps)) - # test no overlay + # test no overlay: all overlays cleared if opts.test_no_overlay: tasks.append(StopTask()) tasks.append(_create_disable_overlays_task()) tasks.append(StartTask()) tasks.append(InstrumentationTask('com.android.overlaytest.WithoutOverlayTest')) - # test single overlay + # test single overlay: one overlay (a) if opts.test_single_overlay: tasks.append(StopTask()) tasks.append(_create_enable_single_overlay_task()) tasks.append(StartTask()) tasks.append(InstrumentationTask('com.android.overlaytest.WithOverlayTest')) - # test multiple overlays + # test multiple overlays: all overlays - including 'disabled' filtered + # overlay (system property unset) so expect 'b[p=2]' overrides 'a[p=1]' but + # 'c[p=3]' should be ignored if opts.test_multiple_overlays: tasks.append(StopTask()) tasks.append(_create_enable_multiple_overlays_task()) tasks.append(StartTask()) tasks.append(InstrumentationTask('com.android.overlaytest.WithMultipleOverlaysTest')) + # test filtered overlays: all overlays - including 'enabled' filtered + # overlay (system property set/matched) so expect c[p=3] to override both a + # & b where applicable + if opts.test_filtered_overlays: + tasks.append(StopTask()) + tasks.append(_create_enable_filtered_overlays_task()) + tasks.append(StartTask()) + tasks.append(InstrumentationTask('com.android.overlaytest.WithFilteredOverlaysTest')) + ignored_errors = 0 for t in tasks: type = t.get_type() |