summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author MÃ¥rten Kongstad <marten.kongstad@sonymobile.com> 2016-06-02 09:35:31 +0200
committer Adam Lesinski <adamlesinski@google.com> 2017-02-23 14:01:38 -0800
commit2e0d0f311100d8e0bb40d7d60b8498237f011f0c (patch)
tree00377afd35d28d384d4ad735b250051481debe31
parent8716ef94194ad715ef596de4a38abb5b2a5c8186 (diff)
OMS: integrate OverlayManagerService into framework
Hand over ownership of overlays to OverlayManagerService. Changes to a package's overlays are propagated using the activity life cycle. Affected activities will be recreated as needed. This provides a well-defined point to modify an application's assets while the application is paused. Consolidate how overlays targeting the system and overlays targeting regular applications are handled. Previously, system overlays were handled as a special case. Now, everything is handled identically. As a side effect, the call to idmap --scan during Zygote boot has become obsolete and is removed. Information on what overlays to use is recorded in ApplicationInfo.resourceDirs. The PackageManagerService is responsible for the creation of ApplicationInfo objects. The OverlayManagerService is responsible for informing the PackageManagerService in advance about what resourceDirs to use. When launching an application, the ApplicationInfo is already populated with up-to-date information about overlays. When enabling or disabling an overlay for a running application, the OverlayManagerService first notifies the PackageManagerService about the updated resourceDirs. It then tells the ActivityManagerService to push the new ApplicationInfo object to the application's ActivityThread. Finally the application requests its ResourcesManager to create new ResourcesImpl objects based on the updated paths. Change-Id: Ib8afa05ccab4e2db558f89ce4423983c086bb61a Co-authored-by: Martin Wallgren <martin.wallgren@sonymobile.com> Signed-off-by: Zoran Jovanovic <zoran.jovanovic@sonymobile.com> Bug: 31052947 Test: run tests from 'OMS: tests for OverlayManagerService'
-rw-r--r--cmds/idmap/Android.mk2
-rw-r--r--cmds/idmap/idmap.cpp55
-rw-r--r--cmds/idmap/idmap.h6
-rw-r--r--cmds/idmap/scan.cpp239
-rw-r--r--core/java/android/content/pm/PackageParser.java13
-rw-r--r--core/java/android/content/pm/PackageUserState.java6
-rw-r--r--core/jni/android_util_AssetManager.cpp93
-rw-r--r--libs/androidfw/AssetManager.cpp104
-rw-r--r--libs/androidfw/include/androidfw/AssetManager.h15
-rw-r--r--packages/Shell/AndroidManifest.xml2
-rw-r--r--services/core/java/com/android/server/SystemServiceManager.java24
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java5
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java37
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java183
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java2
16 files changed, 161 insertions, 631 deletions
diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk
index 50ccb07a3826..eb6da18ea0ad 100644
--- a/cmds/idmap/Android.mk
+++ b/cmds/idmap/Android.mk
@@ -15,7 +15,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := idmap.cpp create.cpp scan.cpp inspect.cpp
+LOCAL_SRC_FILES := idmap.cpp create.cpp inspect.cpp
LOCAL_SHARED_LIBRARIES := liblog libutils libandroidfw
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index 3ab191553625..d388977e8e2f 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -13,8 +13,6 @@ SYNOPSIS \n\
idmap --help \n\
idmap --fd target overlay fd \n\
idmap --path target overlay idmap \n\
- idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\
- dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\
idmap --inspect idmap \n\
\n\
DESCRIPTION \n\
@@ -49,11 +47,6 @@ 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\
- '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\
--inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
debug-friendly format. \n\
\n\
@@ -97,16 +90,6 @@ EXAMPLES \n\
NOTES \n\
This tool and its expected invocation from installd is modelled on dexopt.";
- bool verify_directory_readable(const char *path)
- {
- return access(path, R_OK | X_OK) == 0;
- }
-
- bool verify_directory_writable(const char *path)
- {
- return access(path, W_OK) == 0;
- }
-
bool verify_file_readable(const char *path)
{
return access(path, R_OK) == 0;
@@ -167,36 +150,6 @@ NOTES \n\
return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
}
- int maybe_scan(const char *target_package_name, const char *target_apk_path,
- const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
- {
- if (!verify_root_or_system()) {
- fprintf(stderr, "error: permission denied: not user root or user system\n");
- return -1;
- }
-
- if (!verify_file_readable(target_apk_path)) {
- ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
- return -1;
- }
-
- if (!verify_directory_writable(idmap_dir)) {
- ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno));
- return -1;
- }
-
- const size_t N = overlay_dirs->size();
- for (size_t i = 0; i < N; i++) {
- const char *dir = overlay_dirs->itemAt(i);
- if (!verify_directory_readable(dir)) {
- ALOGD("error: no read access to %s: %s\n", dir, strerror(errno));
- return -1;
- }
- }
-
- return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs);
- }
-
int maybe_inspect(const char *idmap_path)
{
// anyone (not just root or system) may do --inspect
@@ -235,14 +188,6 @@ int main(int argc, char **argv)
return maybe_create_path(argv[2], argv[3], argv[4]);
}
- if (argc >= 6 && !strcmp(argv[1], "--scan")) {
- android::Vector<const char *> v;
- for (int i = 5; i < argc; i++) {
- v.push(argv[i]);
- }
- return maybe_scan(argv[2], argv[3], argv[4], &v);
- }
-
if (argc == 3 && !strcmp(argv[1], "--inspect")) {
return maybe_inspect(argv[2]);
}
diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h
index 8d4210bcb443..5914de96a99d 100644
--- a/cmds/idmap/idmap.h
+++ b/cmds/idmap/idmap.h
@@ -25,12 +25,6 @@ int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd);
-// Regarding target_package_name: the idmap_scan implementation should
-// be able to extract this from the manifest in target_apk_path,
-// simplifying the external API.
-int idmap_scan(const char *target_package_name, const char *target_apk_path,
- const char *idmap_dir, const android::Vector<const char *> *overlay_dirs);
-
int idmap_inspect(const char *idmap_path);
#endif // _IDMAP_H_
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
deleted file mode 100644
index ab6adfb9475f..000000000000
--- a/cmds/idmap/scan.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include <dirent.h>
-#include <inttypes.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include "idmap.h"
-
-#include <memory>
-#include <androidfw/ResourceTypes.h>
-#include <androidfw/StreamingZipInflater.h>
-#include <androidfw/ZipFileRO.h>
-#include <private/android_filesystem_config.h> // for AID_SYSTEM
-#include <utils/SortedVector.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-
-#define NO_OVERLAY_TAG (-1000)
-
-using namespace android;
-
-namespace {
- struct Overlay {
- Overlay() {}
- Overlay(const String8& a, const String8& i, int p) :
- apk_path(a), idmap_path(i), priority(p) {}
-
- bool operator<(Overlay const& rhs) const
- {
- return rhs.priority > priority;
- }
-
- String8 apk_path;
- String8 idmap_path;
- int priority;
- };
-
- bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
- {
- // the file is opened for appending so that it doesn't get truncated
- // before we can guarantee mutual exclusion via the flock
- FILE* fout = fopen(filename, "a");
- if (fout == NULL) {
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) {
- fclose(fout);
- return false;
- }
-
- if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) {
- TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
- fclose(fout);
- return false;
- }
-
- for (size_t i = 0; i < overlayVector.size(); ++i) {
- const Overlay& overlay = overlayVector[i];
- fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
- }
-
- TEMP_FAILURE_RETRY(fflush(fout));
- TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN));
- fclose(fout);
-
- // Make file world readable since Zygote (running as root) will read
- // it when creating the initial AssetManger object
- const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
- if (chmod(filename, mode) == -1) {
- unlink(filename);
- return false;
- }
-
- return true;
- }
-
- String8 flatten_path(const char *path)
- {
- String16 tmp(path);
- tmp.replaceAll('/', '@');
- return String8(tmp);
- }
-
- int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
- {
- const size_t N = parser.getAttributeCount();
- String16 target;
- int priority = -1;
- for (size_t i = 0; i < N; ++i) {
- size_t len;
- String16 key(parser.getAttributeName(i, &len));
- if (key == String16("targetPackage")) {
- const char16_t *p = parser.getAttributeStringValue(i, &len);
- if (p != NULL) {
- target = String16(p, len);
- }
- } else if (key == String16("priority")) {
- Res_value v;
- if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
- priority = v.data;
- if (priority < 0 || priority > 9999) {
- return -1;
- }
- }
- }
- }
- 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)
- {
- ResXMLTree parser;
- parser.setTo(data, size);
- if (parser.getError() != NO_ERROR) {
- ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
- return -1;
- }
-
- ResXMLParser::event_code_t type;
- 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);
- }
- }
- } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);
-
- return NO_OVERLAY_TAG;
- }
-
- int parse_apk(const char *path, const char *target_package_name)
- {
- std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path));
- if (zip.get() == NULL) {
- ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
- return -1;
- }
- ZipEntryRO entry;
- if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) {
- ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
- return -1;
- }
- uint32_t uncompLen = 0;
- uint16_t method;
- if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
- ALOGW("%s: failed to read entry info\n", __FUNCTION__);
- return -1;
- }
- if (method != ZipFileRO::kCompressDeflated) {
- ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method);
- return -1;
- }
- FileMap *dataMap = zip->createEntryFileMap(entry);
- if (dataMap == NULL) {
- ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
- return -1;
- }
- char *buf = new char[uncompLen];
- if (NULL == buf) {
- ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
- delete dataMap;
- return -1;
- }
- StreamingZipInflater inflater(dataMap, uncompLen);
- if (inflater.read(buf, uncompLen) < 0) {
- ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen);
- delete[] buf;
- delete dataMap;
- return -1;
- }
-
- int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name);
- delete[] buf;
- delete dataMap;
- return priority;
- }
-}
-
-int idmap_scan(const char *target_package_name, const char *target_apk_path,
- const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
-{
- String8 filename = String8(idmap_dir);
- filename.appendPath("overlays.list");
-
- SortedVector<Overlay> overlayVector;
- const size_t N = overlay_dirs->size();
- for (size_t i = 0; i < N; ++i) {
- const char *overlay_dir = overlay_dirs->itemAt(i);
- DIR *dir = opendir(overlay_dir);
- if (dir == NULL) {
- return EXIT_FAILURE;
- }
-
- struct dirent *dirent;
- while ((dirent = readdir(dir)) != NULL) {
- struct stat st;
- char overlay_apk_path[PATH_MAX + 1];
- snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
- if (stat(overlay_apk_path, &st) < 0) {
- continue;
- }
- if (!S_ISREG(st.st_mode)) {
- continue;
- }
-
- int priority = parse_apk(overlay_apk_path, target_package_name);
- if (priority < 0) {
- continue;
- }
-
- String8 idmap_path(idmap_dir);
- idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
- idmap_path.append("@idmap");
-
- if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
- ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
- target_apk_path, overlay_apk_path, idmap_path.string());
- continue;
- }
-
- Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
- overlayVector.add(overlay);
- }
-
- closedir(dir);
- }
-
- if (!writePackagesList(filename.string(), overlayVector)) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 56f1e0c4cb7b..f801e4547658 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2065,9 +2065,6 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifestResourceOverlay);
pkg.mOverlayTarget = sa.getString(
com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
- pkg.mOverlayPriority = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
- -1);
sa.recycle();
if (pkg.mOverlayTarget == null) {
@@ -2075,12 +2072,6 @@ 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;
- }
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals(TAG_KEY_SETS)) {
@@ -5518,7 +5509,6 @@ public class PackageParser {
public String mRequiredAccountType;
public String mOverlayTarget;
- public int mOverlayPriority;
public boolean mTrustedOverlay;
/**
@@ -5995,7 +5985,6 @@ public class PackageParser {
mRestrictedAccountType = dest.readString();
mRequiredAccountType = dest.readString();
mOverlayTarget = dest.readString();
- mOverlayPriority = dest.readInt();
mTrustedOverlay = (dest.readInt() == 1);
mSigningKeys = (ArraySet<PublicKey>) dest.readArraySet(boot);
mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot);
@@ -6111,7 +6100,6 @@ public class PackageParser {
dest.writeString(mRestrictedAccountType);
dest.writeString(mRequiredAccountType);
dest.writeString(mOverlayTarget);
- dest.writeInt(mOverlayPriority);
dest.writeInt(mTrustedOverlay ? 1 : 0);
dest.writeArraySet(mSigningKeys);
dest.writeArraySet(mUpgradeKeySets);
@@ -6560,6 +6548,7 @@ public class PackageParser {
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
+ ai.resourceDirs = state.resourceDirs;
}
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 24f116452f0b..ee56a18e71a5 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -31,6 +31,8 @@ import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
+import java.util.Arrays;
+
/**
* Per-user state information about a package.
* @hide
@@ -54,6 +56,8 @@ public class PackageUserState {
public ArraySet<String> disabledComponents;
public ArraySet<String> enabledComponents;
+ public String[] resourceDirs;
+
public PackageUserState() {
installed = true;
hidden = false;
@@ -81,6 +85,8 @@ public class PackageUserState {
installReason = o.installReason;
disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
enabledComponents = ArrayUtils.cloneOrNull(o.enabledComponents);
+ resourceDirs =
+ o.resourceDirs == null ? null : Arrays.copyOf(o.resourceDirs, o.resourceDirs.length);
}
/**
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 723dce6fcf1e..314595f73091 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -119,96 +119,6 @@ jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
return block;
}
-// This is called by zygote (running as user root) as part of preloadResources.
-static void verifySystemIdmaps()
-{
- pid_t pid;
- char system_id[10];
-
- snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
-
- switch (pid = fork()) {
- case -1:
- ALOGE("failed to fork for idmap: %s", strerror(errno));
- break;
- case 0: // child
- {
- struct __user_cap_header_struct capheader;
- struct __user_cap_data_struct capdata;
-
- memset(&capheader, 0, sizeof(capheader));
- memset(&capdata, 0, sizeof(capdata));
-
- capheader.version = _LINUX_CAPABILITY_VERSION;
- capheader.pid = 0;
-
- if (capget(&capheader, &capdata) != 0) {
- ALOGE("capget: %s\n", strerror(errno));
- exit(1);
- }
-
- capdata.effective = capdata.permitted;
- if (capset(&capheader, &capdata) != 0) {
- ALOGE("capset: %s\n", strerror(errno));
- exit(1);
- }
-
- if (setgid(AID_SYSTEM) != 0) {
- ALOGE("setgid: %s\n", strerror(errno));
- exit(1);
- }
-
- if (setuid(AID_SYSTEM) != 0) {
- ALOGE("setuid: %s\n", strerror(errno));
- exit(1);
- }
-
- // Generic idmap parameters
- const char* argv[8];
- int argc = 0;
- struct stat st;
-
- memset(argv, NULL, sizeof(argv));
- argv[argc++] = AssetManager::IDMAP_BIN;
- argv[argc++] = "--scan";
- argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
- argv[argc++] = AssetManager::TARGET_APK_PATH;
- argv[argc++] = AssetManager::IDMAP_DIR;
-
- // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
- // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
- char subdir[PROP_VALUE_MAX];
- int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY,
- subdir);
- if (len == 0) {
- len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
- }
- if (len > 0) {
- String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
- if (stat(overlayPath.string(), &st) == 0) {
- argv[argc++] = overlayPath.string();
- }
- }
- if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
- argv[argc++] = AssetManager::OVERLAY_DIR;
- }
-
- // Finally, invoke idmap (if any overlay directory exists)
- if (argc > 5) {
- execv(AssetManager::IDMAP_BIN, (char* const*)argv);
- ALOGE("failed to execv for idmap: %s", strerror(errno));
- exit(1); // should never get here
- } else {
- exit(0);
- }
- }
- break;
- default: // parent
- waitpid(pid, NULL, 0);
- break;
- }
-}
-
// ----------------------------------------------------------------------------
// this guy is exported to other jni routines
@@ -1597,9 +1507,6 @@ static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jo
static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
{
- if (isSystem) {
- verifySystemIdmaps();
- }
AssetManager* am = new AssetManager();
if (am == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", "");
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index acacd7654cf1..84111ae0d499 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -202,15 +202,6 @@ bool AssetManager::addAssetPath(
*cookie = static_cast<int32_t>(mAssetPaths.size());
}
-#ifdef __ANDROID__
- // Load overlays, if any
- asset_path oap;
- for (size_t idx = 0; mZipSet.getOverlay(ap.path, idx, &oap); idx++) {
- oap.isSystemAsset = isSystemAsset;
- mAssetPaths.add(oap);
- }
-#endif
-
if (mResources != NULL) {
appendPathToResTable(ap, appAsLib);
}
@@ -493,11 +484,6 @@ FileType AssetManager::getFileType(const char* fileName)
}
bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) const {
- // skip those ap's that correspond to system overlays
- if (ap.isSystemOverlay) {
- return true;
- }
-
Asset* ass = NULL;
ResTable* sharedRes = NULL;
bool shared = true;
@@ -539,14 +525,6 @@ bool AssetManager::appendPathToResTable(const asset_path& ap, bool appAsLib) con
ALOGV("Creating shared resources for %s", ap.path.string());
sharedRes = new ResTable();
sharedRes->add(ass, idmap, nextEntryIdx + 1, false);
-#ifdef __ANDROID__
- const char* data = getenv("ANDROID_DATA");
- LOG_ALWAYS_FATAL_IF(data == NULL, "ANDROID_DATA not set");
- String8 overlaysListPath(data);
- overlaysListPath.appendPath(kResourceCache);
- overlaysListPath.appendPath("overlays.list");
- addSystemOverlays(overlaysListPath.string(), ap.path, sharedRes, nextEntryIdx);
-#endif
sharedRes = const_cast<AssetManager*>(this)->
mZipSet.setZipResourceTable(ap.path, sharedRes);
}
@@ -655,58 +633,6 @@ Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const
return ass;
}
-void AssetManager::addSystemOverlays(const char* pathOverlaysList,
- const String8& targetPackagePath, ResTable* sharedRes, size_t offset) const
-{
- FILE* fin = fopen(pathOverlaysList, "r");
- if (fin == NULL) {
- return;
- }
-
-#ifndef _WIN32
- if (TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_SH)) != 0) {
- fclose(fin);
- return;
- }
-#endif
- char buf[1024];
- while (fgets(buf, sizeof(buf), fin)) {
- // format of each line:
- // <path to apk><space><path to idmap><newline>
- char* space = strchr(buf, ' ');
- char* newline = strchr(buf, '\n');
- asset_path oap;
-
- if (space == NULL || newline == NULL || newline < space) {
- continue;
- }
-
- oap.path = String8(buf, space - buf);
- oap.type = kFileTypeRegular;
- oap.idmap = String8(space + 1, newline - space - 1);
- oap.isSystemOverlay = true;
-
- Asset* oass = const_cast<AssetManager*>(this)->
- openNonAssetInPathLocked("resources.arsc",
- Asset::ACCESS_BUFFER,
- oap);
-
- if (oass != NULL) {
- Asset* oidmap = openIdmapLocked(oap);
- offset++;
- sharedRes->add(oass, oidmap, offset + 1, false);
- const_cast<AssetManager*>(this)->mAssetPaths.add(oap);
- const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
- delete oidmap;
- }
- }
-
-#ifndef _WIN32
- TEMP_FAILURE_RETRY(flock(fileno(fin), LOCK_UN));
-#endif
- fclose(fin);
-}
-
const ResTable& AssetManager::getResources(bool required) const
{
const ResTable* rt = getResTable(required);
@@ -1446,20 +1372,6 @@ bool AssetManager::SharedZip::isUpToDate()
return mModWhen == modWhen;
}
-void AssetManager::SharedZip::addOverlay(const asset_path& ap)
-{
- mOverlays.add(ap);
-}
-
-bool AssetManager::SharedZip::getOverlay(size_t idx, asset_path* out) const
-{
- if (idx >= mOverlays.size()) {
- return false;
- }
- *out = mOverlays[idx];
- return true;
-}
-
AssetManager::SharedZip::~SharedZip()
{
if (kIsDebug) {
@@ -1578,22 +1490,6 @@ bool AssetManager::ZipSet::isUpToDate()
return true;
}
-void AssetManager::ZipSet::addOverlay(const String8& path, const asset_path& overlay)
-{
- int idx = getIndex(path);
- sp<SharedZip> zip = mZipFile[idx];
- zip->addOverlay(overlay);
-}
-
-bool AssetManager::ZipSet::getOverlay(const String8& path, size_t idx, asset_path* out) const
-{
- sp<SharedZip> zip = SharedZip::get(path, false);
- if (zip == NULL) {
- return false;
- }
- return zip->getOverlay(idx, out);
-}
-
/*
* Compute the zip file's index.
*
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index becd307d114d..f1e8b9364915 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -202,12 +202,10 @@ public:
private:
struct asset_path
{
- asset_path() : path(""), type(kFileTypeRegular), idmap(""),
- isSystemOverlay(false), isSystemAsset(false) {}
+ asset_path() : path(""), type(kFileTypeRegular), idmap(""), isSystemAsset(false) {}
String8 path;
FileType type;
String8 idmap;
- bool isSystemOverlay;
bool isSystemAsset;
};
@@ -237,9 +235,6 @@ private:
Asset* openIdmapLocked(const struct asset_path& ap) const;
- void addSystemOverlays(const char* pathOverlaysList, const String8& targetPackagePath,
- ResTable* sharedRes, size_t offset) const;
-
class SharedZip : public RefBase {
public:
static sp<SharedZip> get(const String8& path, bool createIfNotPresent = true);
@@ -254,9 +249,6 @@ private:
bool isUpToDate();
- void addOverlay(const asset_path& ap);
- bool getOverlay(size_t idx, asset_path* out) const;
-
protected:
~SharedZip();
@@ -271,8 +263,6 @@ private:
Asset* mResourceTableAsset;
ResTable* mResourceTable;
- Vector<asset_path> mOverlays;
-
static Mutex gLock;
static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
};
@@ -306,9 +296,6 @@ private:
bool isUpToDate();
- void addOverlay(const String8& path, const asset_path& overlay);
- bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
-
private:
void closeZip(int idx);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 34164b16a557..5b4dd48354e6 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -118,6 +118,8 @@
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<!-- Permission needed to hold a wakelock in dumpstate.cpp (drop_root_user()) -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <!-- Permission needed to enable/disable overlays -->
+ <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 3f97d4fe436e..cb13a3d1dda2 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.annotation.NonNull;
import android.content.Context;
import android.os.Trace;
import android.util.Slog;
@@ -105,22 +106,25 @@ public class SystemServiceManager {
+ ": service constructor threw an exception", ex);
}
- // Register it.
- mServices.add(service);
-
- // Start it.
- try {
- service.onStart();
- } catch (RuntimeException ex) {
- throw new RuntimeException("Failed to start service " + name
- + ": onStart threw an exception", ex);
- }
+ startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
+ public void startService(@NonNull final SystemService service) {
+ // Register it.
+ mServices.add(service);
+ // Start it.
+ try {
+ service.onStart();
+ } catch (RuntimeException ex) {
+ throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ + ": onStart threw an exception", ex);
+ }
+ }
+
/**
* Starts the specified boot phase for all system services that have been started up to
* this point.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 30b267f5afe8..75243511f09b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -23165,10 +23165,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
+ final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
final boolean updateFrameworkRes = packagesToUpdate.contains("android");
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mLruProcesses.get(i);
- if (app.thread == null) {
+ if (app.thread == null || app.pid == Process.myPid()) {
continue;
}
@@ -23181,7 +23182,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final String packageName = app.pkgList.keyAt(j);
if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
try {
- final ApplicationInfo ai = mPackageManagerInt.getApplicationInfo(
+ final ApplicationInfo ai = packageManager.getApplicationInfo(
packageName, app.userId);
if (ai != null) {
app.thread.scheduleApplicationInfoChanged(ai);
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index cc709ce6f176..ba4d46aa360b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -26,7 +26,6 @@ import static android.content.pm.PackageManager.SIGNATURE_MATCH;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -42,7 +41,6 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
-import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -646,7 +644,7 @@ public final class OverlayManagerService extends SystemService {
Slog.d(TAG, String.format("send broadcast %s", intent));
}
try {
- ActivityManagerNative.getDefault().broadcastIntent(null, intent, null, null, 0,
+ ActivityManager.getService().broadcastIntent(null, intent, null, null, 0,
null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false,
userId);
} catch (RemoteException e) {
@@ -664,7 +662,38 @@ public final class OverlayManagerService extends SystemService {
}
private void updateAssets(final int userId, List<String> targetPackageNames) {
- // TODO: implement when we integrate OMS properly
+ final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
+ final boolean updateFrameworkRes = targetPackageNames.contains("android");
+ if (updateFrameworkRes) {
+ targetPackageNames = pm.getTargetPackageNames(userId);
+ }
+
+ final Map<String, List<String>> pendingChanges = new ArrayMap<>(targetPackageNames.size());
+ synchronized (mLock) {
+ final int N = targetPackageNames.size();
+ for (int i = 0; i < N; i++) {
+ final String targetPackageName = targetPackageNames.get(i);
+ pendingChanges.put(targetPackageName,
+ mImpl.getEnabledOverlayPackageNames(targetPackageName, userId));
+ }
+ }
+
+ final int N = targetPackageNames.size();
+ for (int i = 0; i < N; i++) {
+ final String targetPackageName = targetPackageNames.get(i);
+ if (!pm.setEnabledOverlayPackages(
+ userId, targetPackageName, pendingChanges.get(targetPackageName))) {
+ Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
+ targetPackageName, userId));
+ }
+ }
+
+ final IActivityManager am = ActivityManager.getService();
+ try {
+ am.scheduleApplicationInfoChanged(targetPackageNames, userId);
+ } catch (RemoteException e) {
+ // Intentionally left empty.
+ }
}
private void schedulePersistSettings() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 975ae0654626..b6884b80f1d1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -661,9 +661,12 @@ public class PackageManagerService extends IPackageManager.Stub {
final ArrayMap<String, Set<String>> mKnownCodebase =
new ArrayMap<String, Set<String>>();
- // Tracks available target package names -> overlay package paths.
- final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
- new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
+ // List of APK paths to load for each user and package. This data is never
+ // persisted by the package manager. Instead, the overlay manager will
+ // ensure the data is up-to-date in runtime.
+ @GuardedBy("mPackages")
+ final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
+ new SparseArray<ArrayMap<String, ArrayList<String>>>();
/**
* Tracks new system packages [received in an OTA] that we expect to
@@ -3734,6 +3737,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
ps.readUserState(userId), userId);
if (ai != null) {
+ rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
}
return ai;
@@ -3768,6 +3772,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ApplicationInfo ai = PackageParser.generateApplicationInfo(
p, flags, ps.readUserState(userId), userId);
if (ai != null) {
+ rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(p);
}
return ai;
@@ -3784,6 +3789,26 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
+ private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
+ List<String> paths = new ArrayList<>();
+ ArrayMap<String, ArrayList<String>> userSpecificOverlays =
+ mEnabledOverlayPaths.get(userId);
+ if (userSpecificOverlays != null) {
+ if (!"android".equals(ai.packageName)) {
+ ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
+ if (frameworkOverlays != null) {
+ paths.addAll(frameworkOverlays);
+ }
+ }
+
+ ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
+ if (appOverlays != null) {
+ paths.addAll(appOverlays);
+ }
+ }
+ ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
+ }
+
private String normalizePackageNameLPr(String packageName) {
String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
return normalizedPackageName != null ? normalizedPackageName : packageName;
@@ -7147,6 +7172,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
if (ai != null) {
+ rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
}
} else {
@@ -7170,6 +7196,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
+ rebaseEnabledOverlays(ai, userId);
ai.packageName = resolveExternalPackageNameLPr(p);
list.add(ai);
}
@@ -7313,6 +7340,7 @@ public class PackageManagerService extends IPackageManager.Stub {
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
+ rebaseEnabledOverlays(ai, userId);
finalList.add(ai);
}
}
@@ -7448,60 +7476,6 @@ public class PackageManagerService extends IPackageManager.Stub {
return finalList;
}
- private void createIdmapsForPackageLI(PackageParser.Package pkg) {
- ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
- if (overlays == null) {
- Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
- return;
- }
- for (PackageParser.Package opkg : overlays.values()) {
- // Not much to do if idmap fails: we already logged the error
- // and we certainly don't want to abort installation of pkg simply
- // because an overlay didn't fit properly. For these reasons,
- // ignore the return value of createIdmapForPackagePairLI.
- createIdmapForPackagePairLI(pkg, opkg);
- }
- }
-
- private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
- PackageParser.Package opkg) {
- if (!opkg.mTrustedOverlay) {
- Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
- opkg.baseCodePath + ": overlay not trusted");
- return false;
- }
- ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
- if (overlaySet == null) {
- Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
- opkg.baseCodePath + " but target package has no known overlays");
- return false;
- }
- final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
- // TODO: generate idmap for split APKs
- try {
- mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
- } catch (InstallerException e) {
- Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
- + opkg.baseCodePath);
- return false;
- }
- PackageParser.Package[] overlayArray =
- overlaySet.values().toArray(new PackageParser.Package[0]);
- Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
- public int compare(PackageParser.Package p1, PackageParser.Package p2) {
- return p1.mOverlayPriority - p2.mOverlayPriority;
- }
- };
- Arrays.sort(overlayArray, cmp);
-
- pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
- int i = 0;
- for (PackageParser.Package p : overlayArray) {
- pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
- }
- return true;
- }
-
private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
try {
@@ -9990,7 +9964,6 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
- boolean createIdmapFailed = false;
synchronized (mPackages) {
// We don't expect installation to fail beyond this point
@@ -10331,36 +10304,9 @@ public class PackageManagerService extends IPackageManager.Stub {
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
}
-
- // Create idmap files for pairs of (packages, overlay packages).
- // Note: "android", ie framework-res.apk, is handled by native layers.
- if (pkg.mOverlayTarget != null) {
- // This is an overlay package.
- if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
- if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
- mOverlays.put(pkg.mOverlayTarget,
- new ArrayMap<String, PackageParser.Package>());
- }
- ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
- map.put(pkg.packageName, pkg);
- PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
- if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
- createIdmapFailed = true;
- }
- }
- } else if (mOverlays.containsKey(pkg.packageName) &&
- !pkg.packageName.equals("android")) {
- // This is a regular package, with one or more known overlay packages.
- createIdmapsForPackageLI(pkg);
- }
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-
- if (createIdmapFailed) {
- throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
- "scanPackageLI failed to createIdmap");
- }
}
private static void maybeRenameForeignDexMarkers(PackageParser.Package existing,
@@ -20159,6 +20105,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
public static final int DUMP_FROZEN = 1 << 19;
public static final int DUMP_DEXOPT = 1 << 20;
public static final int DUMP_COMPILER_STATS = 1 << 21;
+ public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
public static final int OPTION_SHOW_FILTERS = 1 << 0;
@@ -20278,6 +20225,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
pw.println(" dexopt: dump dexopt state");
pw.println(" compiler-stats: dump compiler statistics");
+ pw.println(" enabled-overlays: dump list of enabled overlay packages");
pw.println(" <package.name>: info about given package");
return;
} else if ("--checkin".equals(opt)) {
@@ -20406,6 +20354,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
dumpState.setDump(DumpState.DUMP_DEXOPT);
} else if ("compiler-stats".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
+ } else if ("enabled-overlays".equals(cmd)) {
+ dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
} else if ("write".equals(cmd)) {
synchronized (mPackages) {
mSettings.writeLPr();
@@ -20776,6 +20726,11 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
dumpCompilerStatsLPr(pw, packageName);
}
+ if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
+ if (dumpState.onTitlePrinted()) pw.println();
+ dumpEnabledOverlaysLPr(pw);
+ }
+
if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
if (dumpState.onTitlePrinted()) pw.println();
mSettings.dumpReadMessagesLPr(pw, dumpState);
@@ -20872,6 +20827,23 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
}
+ private void dumpEnabledOverlaysLPr(PrintWriter pw) {
+ pw.println("Enabled overlay paths:");
+ final int N = mEnabledOverlayPaths.size();
+ for (int i = 0; i < N; i++) {
+ final int userId = mEnabledOverlayPaths.keyAt(i);
+ pw.println(String.format(" User %d:", userId));
+ final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
+ mEnabledOverlayPaths.valueAt(i);
+ final int M = userSpecificOverlays.size();
+ for (int j = 0; j < M; j++) {
+ final String targetPackageName = userSpecificOverlays.keyAt(j);
+ final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
+ pw.println(String.format(" %s: %s", targetPackageName, overlayPackagePaths));
+ }
+ }
+ }
+
private String dumpDomainString(String packageName) {
List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
.getList();
@@ -22975,10 +22947,43 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
@Override
- public boolean setEnabledOverlayPackages(int userId, String targetPackageName,
- List<String> overlayPackageNames) {
- // TODO: implement when we integrate OMS properly
- return false;
+ public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
+ @Nullable List<String> overlayPackageNames) {
+ synchronized (mPackages) {
+ if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
+ Slog.e(TAG, "failed to find package " + targetPackageName);
+ return false;
+ }
+
+ ArrayList<String> paths = null;
+ if (overlayPackageNames != null) {
+ final int N = overlayPackageNames.size();
+ paths = new ArrayList<String>(N);
+ for (int i = 0; i < N; i++) {
+ final String packageName = overlayPackageNames.get(i);
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ Slog.e(TAG, "failed to find package " + packageName);
+ return false;
+ }
+ paths.add(pkg.baseCodePath);
+ }
+ }
+
+ ArrayMap<String, ArrayList<String>> userSpecificOverlays =
+ mEnabledOverlayPaths.get(userId);
+ if (userSpecificOverlays == null) {
+ userSpecificOverlays = new ArrayMap<String, ArrayList<String>>();
+ mEnabledOverlayPaths.put(userId, userSpecificOverlays);
+ }
+
+ if (paths != null && paths.size() > 0) {
+ userSpecificOverlays.put(targetPackageName, paths);
+ } else {
+ userSpecificOverlays.remove(targetPackageName);
+ }
+ return true;
+ }
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a5f1945018a2..e586482af83e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -82,6 +82,7 @@ import com.android.server.media.projection.MediaProjectionManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
import com.android.server.notification.NotificationManagerService;
+import com.android.server.om.OverlayManagerService;
import com.android.server.os.DeviceIdentifiersPolicyService;
import com.android.server.os.SchedulingPolicyService;
import com.android.server.pm.Installer;
@@ -592,6 +593,11 @@ public final class SystemServer {
mActivityManagerService.setSystemProcess();
traceEnd();
+ // Manages Overlay packages
+ traceBeginAndSlog("StartOverlayManagerService");
+ mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
+ traceEnd();
+
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 384f49f54f41..28596f7b0ac2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -197,7 +197,6 @@ public class PackageParserTest {
assertEquals(a.installLocation, b.installLocation);
assertEquals(a.coreApp, b.coreApp);
assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
- assertEquals(a.mOverlayPriority, b.mOverlayPriority);
assertEquals(a.mTrustedOverlay, b.mTrustedOverlay);
assertEquals(a.use32bitAbi, b.use32bitAbi);
assertEquals(a.packageName, b.packageName);
@@ -433,7 +432,6 @@ public class PackageParserTest {
pkg.installLocation = 100;
pkg.coreApp = true;
pkg.mRequiredForAllUsers = true;
- pkg.mOverlayPriority = 100;
pkg.mTrustedOverlay = true;
pkg.use32bitAbi = true;
pkg.packageName = "foo";