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.

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'
Change-Id: Idc96dae6fc075d5373aa055bbf50e919136d7353
diff --git a/cmds/idmap/Android.mk b/cmds/idmap/Android.mk
index 50ccb07..eb6da18 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 3ab1915..d388977 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -13,8 +13,6 @@
       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 @@
       --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 @@
 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 @@
         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 @@
         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 8d4210b..5914de9 100644
--- a/cmds/idmap/idmap.h
+++ b/cmds/idmap/idmap.h
@@ -25,12 +25,6 @@
 
 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 ab6adfb..0000000
--- 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 56f1e0c..f801e45 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2065,9 +2065,6 @@
                         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 @@
                     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 String mRequiredAccountType;
 
         public String mOverlayTarget;
-        public int mOverlayPriority;
         public boolean mTrustedOverlay;
 
         /**
@@ -5995,7 +5985,6 @@
             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 @@
             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 @@
             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 24f1164..ee56a18 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -31,6 +31,8 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.Arrays;
+
 /**
  * Per-user state information about a package.
  * @hide
@@ -54,6 +56,8 @@
     public ArraySet<String> disabledComponents;
     public ArraySet<String> enabledComponents;
 
+    public String[] resourceDirs;
+
     public PackageUserState() {
         installed = true;
         hidden = false;
@@ -81,6 +85,8 @@
         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 723dce6..314595f 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -119,96 +119,6 @@
     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 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 acacd76..84111ae 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -202,15 +202,6 @@
         *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 @@
 }
 
 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 @@
                 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 @@
     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 @@
     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 @@
     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 becd307..f1e8b93 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -202,12 +202,10 @@
 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 @@
 
     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 @@
 
         bool isUpToDate();
 
-        void addOverlay(const asset_path& ap);
-        bool getOverlay(size_t idx, asset_path* out) const;
-
     protected:
         ~SharedZip();
 
@@ -271,8 +263,6 @@
         Asset* mResourceTableAsset;
         ResTable* mResourceTable;
 
-        Vector<asset_path> mOverlays;
-
         static Mutex gLock;
         static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
     };
@@ -306,9 +296,6 @@
 
         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 34164b16..5b4dd48 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 3f97d4f..cb13a3d 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 @@
                         + ": 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/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index cc709ce..88e8ce6 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -664,7 +664,38 @@
     }
 
     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 = ActivityManagerNative.getDefault();
+        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 f95ee8f..8797ec4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -658,9 +658,12 @@
     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
@@ -3705,6 +3708,7 @@
             ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
                     ps.readUserState(userId), userId);
             if (ai != null) {
+                rebaseEnabledOverlays(ai, userId);
                 ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
             }
             return ai;
@@ -3739,6 +3743,7 @@
                 ApplicationInfo ai = PackageParser.generateApplicationInfo(
                         p, flags, ps.readUserState(userId), userId);
                 if (ai != null) {
+                    rebaseEnabledOverlays(ai, userId);
                     ai.packageName = resolveExternalPackageNameLPr(p);
                 }
                 return ai;
@@ -3755,6 +3760,26 @@
         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;
@@ -7089,6 +7114,7 @@
                         ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
                                 ps.readUserState(userId), userId);
                         if (ai != null) {
+                            rebaseEnabledOverlays(ai, userId);
                             ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
                         }
                     } else {
@@ -7112,6 +7138,7 @@
                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
                                 ps.readUserState(userId), userId);
                         if (ai != null) {
+                            rebaseEnabledOverlays(ai, userId);
                             ai.packageName = resolveExternalPackageNameLPr(p);
                             list.add(ai);
                         }
@@ -7255,6 +7282,7 @@
                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
                                 ps.readUserState(userId), userId);
                         if (ai != null) {
+                            rebaseEnabledOverlays(ai, userId);
                             finalList.add(ai);
                         }
                     }
@@ -7390,60 +7418,6 @@
         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 {
@@ -9932,7 +9906,6 @@
         // writer
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
 
-        boolean createIdmapFailed = false;
         synchronized (mPackages) {
             // We don't expect installation to fail beyond this point
 
@@ -10273,36 +10246,9 @@
                     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,
@@ -20185,6 +20131,7 @@
         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;
 
@@ -20304,6 +20251,7 @@
                 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)) {
@@ -20432,6 +20380,8 @@
                 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();
@@ -20802,6 +20752,11 @@
                 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);
@@ -20898,6 +20853,23 @@
         }
     }
 
+    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();
@@ -22984,10 +22956,43 @@
 
 
         @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 7917644..d49fcda 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.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;
@@ -594,6 +595,11 @@
         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 384f49f..28596f7 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 @@
         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 @@
         pkg.installLocation = 100;
         pkg.coreApp = true;
         pkg.mRequiredForAllUsers = true;
-        pkg.mOverlayPriority = 100;
         pkg.mTrustedOverlay = true;
         pkg.use32bitAbi = true;
         pkg.packageName = "foo";