diff --git a/Android.mk b/Android.mk
index 63ad83f..d0d0d7e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -148,6 +148,7 @@
 	core/java/android/content/ISyncContext.aidl \
 	core/java/android/content/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
+	core/java/android/content/om/IOverlayManager.aidl \
 	core/java/android/content/pm/ILauncherApps.aidl \
 	core/java/android/content/pm/IOnAppsChangedListener.aidl \
 	core/java/android/content/pm/IOnPermissionsChangeListener.aidl \
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c7c680f..f610a29 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3754,6 +3754,16 @@
     public static final String INCIDENT_SERVICE = "incident";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a {@link
+     * android.content.om.OverlayManager} for managing overlay packages.
+     *
+     * @see #getSystemService
+     * @see android.content.om.OverlayManager
+     * @hide
+     */
+    public static final String OVERLAY_SERVICE = "overlay";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 249001b..111b4d6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3133,6 +3133,40 @@
             "android.intent.action.MEDIA_RESOURCE_GRANTED";
 
     /**
+     * Broadcast Action: An overlay package has been installed. The data
+     * contains the name of the added overlay package.
+     * @hide
+     */
+    public static final String ACTION_OVERLAY_ADDED = "android.intent.action.OVERLAY_ADDED";
+
+    /**
+     * Broadcast Action: An overlay package has changed. The data contains the
+     * name of the overlay package which has changed. This is broadcast on all
+     * changes to the OverlayInfo returned by {@link
+     * android.content.om.IOverlayManager#getOverlayInfo(String, int)}. The
+     * most common change is a state change that will change whether the
+     * overlay is enabled or not.
+     * @hide
+     */
+    public static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+
+    /**
+     * Broadcast Action: An overlay package has been removed. The data contains
+     * the name of the overlay package which has been removed.
+     * @hide
+     */
+    public static final String ACTION_OVERLAY_REMOVED = "android.intent.action.OVERLAY_REMOVED";
+
+    /**
+     * Broadcast Action: The order of a package's list of overlay packages has
+     * changed. The data contains the package name of the overlay package that
+     * had its position in the list adjusted.
+     * @hide
+     */
+    public static final String
+            ACTION_OVERLAY_PRIORITY_CHANGED = "android.intent.action.OVERLAY_PRIORITY_CHANGED";
+
+    /**
      * Activity Action: Allow the user to select and return one or more existing
      * documents. When invoked, the system will display the various
      * {@link DocumentsProvider} instances installed on the device, letting the
diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl
new file mode 100644
index 0000000..4f5d960
--- /dev/null
+++ b/core/java/android/content/om/IOverlayManager.aidl
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+import android.content.om.OverlayInfo;
+
+/**
+ * Api for getting information about overlay packages.
+ *
+ * {@hide}
+ */
+interface IOverlayManager {
+    /**
+     * Returns information about all installed overlay packages for the
+     * specified user. If there are no installed overlay packages for this user,
+     * an empty map is returned (i.e. null is never returned). The returned map is a
+     * mapping of target package names to lists of overlays. Each list for a
+     * given target package is sorted in priority order, with the overlay with
+     * the highest priority at the end of the list.
+     *
+     * @param userId The user to get the OverlayInfos for.
+     * @return A Map<String, List<OverlayInfo>> with target package names
+     *         mapped to lists of overlays; if no overlays exist for the
+     *         requested user, an empty map is returned.
+     */
+    Map getAllOverlays(in int userId);
+
+    /**
+     * Returns information about all overlays for the given target package for
+     * the specified user. The returned list is ordered according to the
+     * overlay priority with the highest priority at the end of the list.
+     *
+     * @param targetPackageName The name of the target package.
+     * @param userId The user to get the OverlayInfos for.
+     * @return A list of OverlayInfo objects; if no overlays exist for the
+     *         requested package, an empty list is returned.
+     */
+    List getOverlayInfosForTarget(in String targetPackageName, in int userId);
+
+    /**
+     * Returns information about the overlay with the given package name for the
+     * specified user.
+     *
+     * @param packageName The name of the overlay package.
+     * @param userId The user to get the OverlayInfo for.
+     * @return The OverlayInfo for the overlay package; or null if no such
+     *         overlay package exists.
+     */
+    OverlayInfo getOverlayInfo(in String packageName, in int userId);
+
+    /**
+     * Request that an overlay package be enabled or disabled when possible to
+     * do so.
+     *
+     * It is always possible to disable an overlay, but due to technical and
+     * security reasons it may not always be possible to enable an overlay. An
+     * example of the latter is when the related target package is not
+     * installed. If the technical obstacle is later overcome, the overlay is
+     * automatically enabled at that point in time.
+     *
+     * An enabled overlay is a part of target package's resources, i.e. it will
+     * be part of any lookups performed via {@link android.content.res.Resources}
+     * and {@link android.content.res.AssetManager}. A disabled overlay will no
+     * longer affect the resources of the target package. If the target is
+     * currently running, its outdated resources will be replaced by new ones.
+     * This happens the same way as when an application enters or exits split
+     * window mode.
+     *
+     * @param packageName The name of the overlay package.
+     * @param enable true to enable the overlay, false to disable it.
+     * @param userId The user for which to change the overlay.
+     * @return true if the system successfully registered the request, false
+     *         otherwise.
+     */
+    boolean setEnabled(in String packageName, in boolean enable, in int userId);
+
+    /**
+     * Change the priority of the given overlay to be just higher than the
+     * overlay with package name newParentPackageName. Both overlay packages
+     * must have the same target and user.
+     *
+     * @see getOverlayInfosForTarget
+     *
+     * @param packageName The name of the overlay package whose priority should
+     *        be adjusted.
+     * @param newParentPackageName The name of the overlay package the newly
+     *        adjusted overlay package should just outrank.
+     * @param userId The user for which to change the overlay.
+     */
+    boolean setPriority(in String packageName, in String newParentPackageName, in int userId);
+
+    /**
+     * Change the priority of the given overlay to the highest priority relative to
+     * the other overlays with the same target and user.
+     *
+     * @see getOverlayInfosForTarget
+     *
+     * @param packageName The name of the overlay package whose priority should
+     *        be adjusted.
+     * @param userId The user for which to change the overlay.
+     */
+    boolean setHighestPriority(in String packageName, in int userId);
+
+    /**
+     * Change the priority of the overlay to the lowest priority relative to
+     * the other overlays for the same target and user.
+     *
+     * @see getOverlayInfosForTarget
+     *
+     * @param packageName The name of the overlay package whose priority should
+     *        be adjusted.
+     * @param userId The user for which to change the overlay.
+     */
+    boolean setLowestPriority(in String packageName, in int userId);
+}
diff --git a/core/java/android/content/om/OverlayInfo.aidl b/core/java/android/content/om/OverlayInfo.aidl
new file mode 100644
index 0000000..e7d413d
--- /dev/null
+++ b/core/java/android/content/om/OverlayInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+parcelable OverlayInfo;
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
new file mode 100644
index 0000000..1a207ba
--- /dev/null
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.om;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Immutable overlay information about a package. All PackageInfos that
+ * represent an overlay package will have a corresponding OverlayInfo.
+ *
+ * @hide
+ */
+public final class OverlayInfo implements Parcelable {
+    /**
+     * An internal state used as the initial state of an overlay. OverlayInfo
+     * objects exposed outside the {@link
+     * com.android.server.om.OverlayManagerService} should never have this
+     * state.
+     */
+    public static final int STATE_UNKNOWN = -1;
+
+    /**
+     * The target package of the overlay is not installed. The overlay cannot be enabled.
+     */
+    public static final int STATE_MISSING_TARGET = 0;
+
+    /**
+     * Creation of idmap file failed (e.g. no matching resources). The overlay
+     * cannot be enabled.
+     */
+    public static final int STATE_NO_IDMAP = 1;
+
+    /**
+     * The overlay is currently disabled. It can be enabled.
+     *
+     * @see IOverlayManager.setEnabled
+     */
+    public static final int STATE_DISABLED = 2;
+
+    /**
+     * The overlay is currently enabled. It can be disabled.
+     *
+     * @see IOverlayManager.setEnabled
+     */
+    public static final int STATE_ENABLED = 3;
+
+    /**
+     * Package name of the overlay package
+     */
+    public final String packageName;
+
+    /**
+     * Package name of the target package
+     */
+    public final String targetPackageName;
+
+    /**
+     * Full path to the base APK for this overlay package
+     */
+    public final String baseCodePath;
+
+    /**
+     * The state of this OverlayInfo as defined by the STATE_* constants in this class.
+     *
+     * @see #STATE_MISSING_TARGET
+     * @see #STATE_NO_IDMAP
+     * @see #STATE_DISABLED
+     * @see #STATE_ENABLED
+     */
+    public final int state;
+
+    /**
+     * User handle for which this overlay applies
+     */
+    public final int userId;
+
+    /**
+     * Create a new OverlayInfo based on source with an updated state.
+     *
+     * @param source the source OverlayInfo to base the new instance on
+     * @param state the new state for the source OverlayInfo
+     */
+    public OverlayInfo(@NonNull OverlayInfo source, int state) {
+        this(source.packageName, source.targetPackageName, source.baseCodePath, state,
+                source.userId);
+    }
+
+    public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
+            @NonNull String baseCodePath, int state, int userId) {
+        this.packageName = packageName;
+        this.targetPackageName = targetPackageName;
+        this.baseCodePath = baseCodePath;
+        this.state = state;
+        this.userId = userId;
+        ensureValidState();
+    }
+
+    public OverlayInfo(Parcel source) {
+        packageName = source.readString();
+        targetPackageName = source.readString();
+        baseCodePath = source.readString();
+        state = source.readInt();
+        userId = source.readInt();
+        ensureValidState();
+    }
+
+    private void ensureValidState() {
+        if (packageName == null) {
+            throw new IllegalArgumentException("packageName must not be null");
+        }
+        if (targetPackageName == null) {
+            throw new IllegalArgumentException("targetPackageName must not be null");
+        }
+        if (baseCodePath == null) {
+            throw new IllegalArgumentException("baseCodePath must not be null");
+        }
+        switch (state) {
+            case STATE_UNKNOWN:
+            case STATE_MISSING_TARGET:
+            case STATE_NO_IDMAP:
+            case STATE_DISABLED:
+            case STATE_ENABLED:
+                break;
+            default:
+                throw new IllegalArgumentException("State " + state + " is not a valid state");
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(packageName);
+        dest.writeString(targetPackageName);
+        dest.writeString(baseCodePath);
+        dest.writeInt(state);
+        dest.writeInt(userId);
+    }
+
+    public static final Parcelable.Creator<OverlayInfo> CREATOR = new Parcelable.Creator<OverlayInfo>() {
+        @Override
+        public OverlayInfo createFromParcel(Parcel source) {
+            return new OverlayInfo(source);
+        }
+
+        @Override
+        public OverlayInfo[] newArray(int size) {
+            return new OverlayInfo[size];
+        }
+    };
+
+    /**
+     * Return true if this overlay is enabled, i.e. should be used to overlay
+     * the resources in the target package.
+     *
+     * Disabled overlay packages are installed but are currently not in use.
+     *
+     * @return true if the overlay is enabled, else false.
+     */
+    public boolean isEnabled() {
+        switch (state) {
+            case STATE_ENABLED:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Translate a state to a human readable string. Only intended for
+     * debugging purposes.
+     *
+     * @see #STATE_MISSING_TARGET
+     * @see #STATE_NO_IDMAP
+     * @see #STATE_DISABLED
+     * @see #STATE_ENABLED
+     *
+     * @return a human readable String representing the state.
+     */
+    public static String stateToString(int state) {
+        switch (state) {
+            case STATE_UNKNOWN:
+                return "STATE_UNKNOWN";
+            case STATE_MISSING_TARGET:
+                return "STATE_MISSING_TARGET";
+            case STATE_NO_IDMAP:
+                return "STATE_NO_IDMAP";
+            case STATE_DISABLED:
+                return "STATE_DISABLED";
+            case STATE_ENABLED:
+                return "STATE_ENABLED";
+            default:
+                return "<unknown state>";
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + userId;
+        result = prime * result + state;
+        result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
+        result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
+        result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        OverlayInfo other = (OverlayInfo) obj;
+        if (userId != other.userId) {
+            return false;
+        }
+        if (state != other.state) {
+            return false;
+        }
+        if (!packageName.equals(other.packageName)) {
+            return false;
+        }
+        if (!targetPackageName.equals(other.targetPackageName)) {
+            return false;
+        }
+        if (!baseCodePath.equals(other.baseCodePath)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
+                + state + " (" + stateToString(state) + "), userId=" + userId + " }";
+    }
+}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index a90b18a..e3e02b1f 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -267,4 +267,33 @@
     }
 
     public abstract void setExternalSourcesPolicy(ExternalSourcesPolicy policy);
+
+    /**
+     * Get all overlay packages for a user.
+     * @param userId The user for which to get the overlays.
+     * @return A list of overlay packages. An empty list is returned if the
+     *         user has no installed overlay packages.
+     */
+    public abstract List<PackageInfo> getOverlayPackages(int userId);
+
+    /**
+     * Get the names of all target packages for a user.
+     * @param userId The user for which to get the package names.
+     * @return A list of target package names. This list includes the "android" package.
+     */
+    public abstract List<String> getTargetPackageNames(int userId);
+
+    /**
+     * Set which overlay to use for a package.
+     * @param userId The user for which to update the overlays.
+     * @param targetPackageName The package name of the package for which to update the overlays.
+     * @param overlayPackageNames The complete list of overlay packages that should be enabled for
+     *                            the target. Previously enabled overlays not specified in the list
+     *                            will be disabled. Pass in null or an empty list to disable
+     *                            all overlays. The order of the items is significant if several
+     *                            overlays modify the same resource.
+     * @return true if all packages names were known by the package manager, false otherwise
+     */
+    public abstract boolean setEnabledOverlayPackages(int userId, String targetPackageName,
+            List<String> overlayPackageNames);
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2b6c0ba..540f924 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -82,6 +82,10 @@
     <protected-broadcast android:name="android.intent.action.USER_SWITCHED" />
     <protected-broadcast android:name="android.intent.action.USER_INITIALIZE" />
     <protected-broadcast android:name="android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION" />
+    <protected-broadcast android:name="android.intent.action.OVERLAY_ADDED" />
+    <protected-broadcast android:name="android.intent.action.OVERLAY_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.OVERLAY_REMOVED" />
+    <protected-broadcast android:name="android.intent.action.OVERLAY_PRIORITY_CHANGED" />
 
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
@@ -2107,6 +2111,12 @@
         android:protectionLevel="signature" />
     <uses-permission android:name="android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE"/>
 
+    <!-- Allows an application to enable, disable and change priority of
+         runtime resource overlays.
+         @hide -->
+    <permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES"
+        android:protectionLevel="signature|privileged|development" />
+
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
new file mode 100644
index 0000000..04d91f8
--- /dev/null
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
+import android.annotation.NonNull;
+import android.content.om.OverlayInfo;
+import android.content.pm.PackageInfo;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.Installer;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Handle the creation and deletion of idmap files.
+ *
+ * The actual work is performed by the idmap binary, launched through Installer
+ * and installd.
+ *
+ * Note: this class is subclassed in the OMS unit tests, and hence not marked as final.
+ */
+class IdmapManager {
+    private final Installer mInstaller;
+
+    IdmapManager(final Installer installer) {
+        mInstaller = installer;
+    }
+
+    boolean createIdmap(@NonNull final PackageInfo targetPackage,
+            @NonNull final PackageInfo overlayPackage, int userId) {
+        // unused userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
+        if (DEBUG) {
+            Slog.d(TAG, "create idmap for " + targetPackage.packageName + " and "
+                    + overlayPackage.packageName);
+        }
+        final int sharedGid = UserHandle.getSharedAppGid(targetPackage.applicationInfo.uid);
+        final String targetPath = targetPackage.applicationInfo.getBaseCodePath();
+        final String overlayPath = overlayPackage.applicationInfo.getBaseCodePath();
+        try {
+            mInstaller.idmap(targetPath, overlayPath, sharedGid);
+        } catch (InstallerException e) {
+            Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
+                    + overlayPath + ": " + e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    boolean removeIdmap(@NonNull final OverlayInfo oi, final int userId) {
+        // unused userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
+        if (DEBUG) {
+            Slog.d(TAG, "remove idmap for " + oi.baseCodePath);
+        }
+        try {
+            mInstaller.removeIdmap(oi.baseCodePath);
+        } catch (InstallerException e) {
+            Slog.w(TAG, "failed to remove idmap for " + oi.baseCodePath + ": " + e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    boolean idmapExists(@NonNull final OverlayInfo oi) {
+        // unused OverlayInfo.userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
+        return new File(getIdmapPath(oi.baseCodePath)).isFile();
+    }
+
+    boolean idmapExists(@NonNull final PackageInfo overlayPackage, final int userId) {
+        // unused userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
+        return new File(getIdmapPath(overlayPackage.applicationInfo.getBaseCodePath())).isFile();
+    }
+
+    boolean isDangerous(@NonNull final PackageInfo overlayPackage, final int userId) {
+        // unused userId: see comment in OverlayManagerServiceImpl.removeIdmapIfPossible
+        return isDangerous(getIdmapPath(overlayPackage.applicationInfo.getBaseCodePath()));
+    }
+
+    private String getIdmapPath(@NonNull final String baseCodePath) {
+        final StringBuilder sb = new StringBuilder("/data/resource-cache/");
+        sb.append(baseCodePath.substring(1).replace('/', '@'));
+        sb.append("@idmap");
+        return sb.toString();
+    }
+
+    private boolean isDangerous(@NonNull final String idmapPath) {
+        try (DataInputStream dis = new DataInputStream(new FileInputStream(idmapPath))) {
+            final int magic = dis.readInt();
+            final int version = dis.readInt();
+            final int dangerous = dis.readInt();
+            return dangerous != 0;
+        } catch (IOException e) {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
new file mode 100644
index 0000000..cc709ce
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -0,0 +1,850 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static android.app.AppGlobals.getPackageManager;
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+import static android.content.Intent.ACTION_USER_REMOVED;
+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;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserInfo;
+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;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.server.FgThread;
+import com.android.server.IoThread;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.pm.Installer;
+import com.android.server.pm.UserManagerService;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Service to manage asset overlays.
+ *
+ * <p>Asset overlays are additional resources that come from apks loaded
+ * alongside the system and app apks. This service, the OverlayManagerService
+ * (OMS), tracks which installed overlays to use and provides methods to change
+ * this. Changes propagate to running applications as part of the Activity
+ * lifecycle. This allows Activities to reread their resources at a well
+ * defined point.</p>
+ *
+ * <p>By itself, the OMS will not change what overlays should be active.
+ * Instead, it is only responsible for making sure that overlays *can* be used
+ * from a technical and security point of view and to activate overlays in
+ * response to external requests. The responsibility to toggle overlays on and
+ * off lies within components that implement different use-cases such as themes
+ * or dynamic customization.</p>
+ *
+ * <p>The OMS receives input from three sources:</p>
+ *
+ * <ul>
+ *     <li>Callbacks from the SystemService class, specifically when the
+ *     Android framework is booting and when the end user switches Android
+ *     users.</li>
+ *
+ *     <li>Intents from the PackageManagerService (PMS). Overlays are regular
+ *     apks, and whenever a package is installed (or removed, or has a
+ *     component enabled or disabled), the PMS broadcasts this as an intent.
+ *     When the OMS receives one of these intents, it updates its internal
+ *     representation of the available overlays and, if there was a visible
+ *     change, triggers an asset refresh in the affected apps.</li>
+ *
+ *     <li>External requests via the {@link IOverlayManager AIDL interface}.
+ *     The interface allows clients to read information about the currently
+ *     available overlays, change whether an overlay should be used or not, and
+ *     change the relative order in which overlay packages are loaded.
+ *     Read-access is granted if the request targets the same Android user as
+ *     the caller runs as, or if the caller holds the
+ *     INTERACT_ACROSS_USERS_FULL permission. Write-access is granted if the
+ *     caller is granted read-access and additionaly holds the
+ *     CHANGE_OVERLAY_PACKAGES permission.</li>
+ * </ul>
+ *
+ * <p>The AIDL interface works with String package names, int user IDs, and
+ * {@link OverlayInfo} objects. OverlayInfo instances are used to track a
+ * specific pair of target and overlay packages and include information such as
+ * the current state of the overlay. OverlayInfo objects are immutable.</p>
+ *
+ * <p>Internally, OverlayInfo objects are maintained by the
+ * OverlayManagerSettings class. The OMS and its helper classes are notified of
+ * changes to the settings by the OverlayManagerSettings.ChangeListener
+ * callback interface. The file /data/system/overlays.xml is used to persist
+ * the settings.</p>
+ *
+ * <p>Creation and deletion of idmap files are handled by the IdmapManager
+ * class.</p>
+ *
+ * <p>The following is an overview of OMS and its related classes. Note how box
+ * (2) does the heavy lifting, box (1) interacts with the Android framework,
+ * and box (3) replaces box (1) during unit testing.</p>
+ *
+ * <pre>
+ *         Android framework
+ *            |         ^
+ *      . . . | . . . . | . . . .
+ *     .      |         |       .
+ *     .    AIDL,   broadcasts  .
+ *     .   intents      |       .
+ *     .      |         |       . . . . . . . . . . . .
+ *     .      v         |       .                     .
+ *     .  OverlayManagerService . OverlayManagerTests .
+ *     .                  \     .     /               .
+ *     . (1)               \    .    /            (3) .
+ *      . . . . . . . . . . \ . . . / . . . . . . . . .
+ *     .                     \     /              .
+ *     . (2)                  \   /               .
+ *     .           OverlayManagerServiceImpl      .
+ *     .                  |            |          .
+ *     .                  |            |          .
+ *     . OverlayManagerSettings     IdmapManager  .
+ *     .                                          .
+ *     . . . .  . . . . . . . . . . . . . . . . . .
+ * </pre>
+ *
+ * <p>Finally, here is a list of keywords used in the OMS context.</p>
+ *
+ * <ul>
+ *     <li><b>target [package]</b> -- A regular apk that may have its resource
+ *     pool extended  by zero or more overlay packages.</li>
+ *
+ *     <li><b>overlay [package]</b> -- An apk that provides additional
+ *     resources to another apk.</li>
+ *
+ *     <li><b>OMS</b> -- The OverlayManagerService, i.e. this class.</li>
+ *
+ *     <li><b>approved</b> -- An overlay is approved if the OMS has verified
+ *     that it can be used technically speaking (its target package is
+ *     installed, at least one resource name in both packages match, the
+ *     idmap was created, etc) and that it is secure to do so. External
+ *     clients can not change this state.</li>
+ *
+ *     <li><b>not approved</b> -- The opposite of approved.</li>
+ *
+ *     <li><b>enabled</b> -- An overlay currently in active use and thus part
+ *     of resource lookups. This requires the overlay to be approved. Only
+ *     external clients can change this state.</li>
+ *
+ *     <li><b>disabled</b> -- The opposite of enabled.</li>
+ *
+ *     <li><b>idmap</b> -- A mapping of resource IDs between target and overlay
+ *     used during resource lookup. Also the name of the binary that creates
+ *     the mapping.</li>
+ * </ul>
+ */
+public final class OverlayManagerService extends SystemService {
+
+    static final String TAG = "OverlayManager";
+
+    static final boolean DEBUG = false;
+
+    static final String PERMISSION_DENIED = "Operation not permitted for user shell";
+
+    private final Object mLock = new Object();
+
+    private final AtomicFile mSettingsFile;
+
+    private final PackageManagerHelper mPackageManager;
+
+    private final UserManagerService mUserManager;
+
+    private final OverlayManagerSettings mSettings;
+
+    private final OverlayManagerServiceImpl mImpl;
+
+    private final AtomicBoolean mPersistSettingsScheduled = new AtomicBoolean(false);
+
+    public OverlayManagerService(@NonNull final Context context,
+            @NonNull final Installer installer) {
+        super(context);
+        mSettingsFile =
+            new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml"));
+        mPackageManager = new PackageManagerHelper();
+        mUserManager = UserManagerService.getInstance();
+        IdmapManager im = new IdmapManager(installer);
+        mSettings = new OverlayManagerSettings();
+        mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings);
+
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(ACTION_PACKAGE_REMOVED);
+        packageFilter.addDataScheme("package");
+        getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
+                packageFilter, null, null);
+
+        final IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(ACTION_USER_REMOVED);
+        getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
+                userFilter, null, null);
+
+        restoreSettings();
+        onSwitchUser(UserHandle.USER_SYSTEM);
+        schedulePersistSettings();
+
+        mSettings.addChangeListener(new OverlayChangeListener());
+
+        publishBinderService(Context.OVERLAY_SERVICE, mService);
+        publishLocalService(OverlayManagerService.class, this);
+    }
+
+    @Override
+    public void onStart() {
+        // Intentionally left empty.
+    }
+
+    @Override
+    public void onSwitchUser(final int newUserId) {
+        // ensure overlays in the settings are up-to-date, and propagate
+        // any asset changes to the rest of the system
+        final List<String> targets;
+        synchronized (mLock) {
+            targets = mImpl.onSwitchUser(newUserId);
+        }
+        updateAssets(newUserId, targets);
+    }
+
+    private final class PackageReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
+            final Uri data = intent.getData();
+            if (data == null) {
+                Slog.e(TAG, "Cannot handle package broadcast with null data");
+                return;
+            }
+            final String packageName = data.getSchemeSpecificPart();
+
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+            final int[] userIds;
+            final int extraUid = intent.getIntExtra(Intent.EXTRA_UID, UserHandle.USER_NULL);
+            if (extraUid == UserHandle.USER_NULL) {
+                userIds = mUserManager.getUserIds();
+            } else {
+                userIds = new int[] { UserHandle.getUserId(extraUid) };
+            }
+
+            switch (intent.getAction()) {
+                case ACTION_PACKAGE_ADDED:
+                    if (replacing) {
+                        onPackageUpgraded(packageName, userIds);
+                    } else {
+                        onPackageAdded(packageName, userIds);
+                    }
+                    break;
+                case ACTION_PACKAGE_CHANGED:
+                    onPackageChanged(packageName, userIds);
+                    break;
+                case ACTION_PACKAGE_REMOVED:
+                    if (replacing) {
+                        onPackageUpgrading(packageName, userIds);
+                    } else {
+                        onPackageRemoved(packageName, userIds);
+                    }
+                    break;
+                default:
+                    // do nothing
+                    break;
+            }
+        }
+
+        private void onPackageAdded(@NonNull final String packageName,
+                @NonNull final int[] userIds) {
+            for (final int userId : userIds) {
+                synchronized (mLock) {
+                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
+                    if (pi != null) {
+                        mPackageManager.cachePackageInfo(packageName, userId, pi);
+                        if (!isOverlayPackage(pi)) {
+                            mImpl.onTargetPackageAdded(packageName, userId);
+                        } else {
+                            mImpl.onOverlayPackageAdded(packageName, userId);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void onPackageChanged(@NonNull final String packageName,
+                @NonNull final int[] userIds) {
+            for (int userId : userIds) {
+                synchronized (mLock) {
+                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
+                    if (pi != null) {
+                        mPackageManager.cachePackageInfo(packageName, userId, pi);
+                        if (!isOverlayPackage(pi)) {
+                            mImpl.onTargetPackageChanged(packageName, userId);
+                        } else {
+                            mImpl.onOverlayPackageChanged(packageName, userId);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void onPackageUpgrading(@NonNull final String packageName,
+                @NonNull final int[] userIds) {
+            for (int userId : userIds) {
+                synchronized (mLock) {
+                    mPackageManager.forgetPackageInfo(packageName, userId);
+                    final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId);
+                    if (oi == null) {
+                        mImpl.onTargetPackageUpgrading(packageName, userId);
+                    } else {
+                        mImpl.onOverlayPackageUpgrading(packageName, userId);
+                    }
+                }
+            }
+        }
+
+        private void onPackageUpgraded(@NonNull final String packageName,
+                @NonNull final int[] userIds) {
+            for (int userId : userIds) {
+                synchronized (mLock) {
+                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
+                    if (pi != null) {
+                        mPackageManager.cachePackageInfo(packageName, userId, pi);
+                        if (!isOverlayPackage(pi)) {
+                            mImpl.onTargetPackageUpgraded(packageName, userId);
+                        } else {
+                            mImpl.onOverlayPackageUpgraded(packageName, userId);
+                        }
+                    }
+                }
+            }
+        }
+
+        private void onPackageRemoved(@NonNull final String packageName,
+                @NonNull final int[] userIds) {
+            for (int userId : userIds) {
+                synchronized (mLock) {
+                    mPackageManager.forgetPackageInfo(packageName, userId);
+                    final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId);
+                    if (oi == null) {
+                        mImpl.onTargetPackageRemoved(packageName, userId);
+                    } else {
+                        mImpl.onOverlayPackageRemoved(packageName, userId);
+                    }
+                }
+            }
+        }
+    }
+
+    private final class UserReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
+            switch (intent.getAction()) {
+                case ACTION_USER_REMOVED:
+                    final int userId =
+                            intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+                    if (userId != UserHandle.USER_NULL) {
+                        synchronized (mLock) {
+                            mImpl.onUserRemoved(userId);
+                            mPackageManager.forgetAllPackageInfos(userId);
+                        }
+                    }
+                    break;
+                default:
+                    // do nothing
+                    break;
+            }
+        }
+    }
+
+    private final IBinder mService = new IOverlayManager.Stub() {
+        @Override
+        public Map<String, List<OverlayInfo>> getAllOverlays(int userId)
+                throws RemoteException {
+            userId = handleIncomingUser(userId, "getAllOverlays");
+
+            synchronized (mLock) {
+                return mImpl.getOverlaysForUser(userId);
+            }
+        }
+
+        @Override
+        public List<OverlayInfo> getOverlayInfosForTarget(@Nullable final String targetPackageName,
+                int userId) throws RemoteException {
+            userId = handleIncomingUser(userId, "getOverlayInfosForTarget");
+            if (targetPackageName == null) {
+                return Collections.emptyList();
+            }
+
+            synchronized (mLock) {
+                return mImpl.getOverlayInfosForTarget(targetPackageName, userId);
+            }
+        }
+
+        @Override
+        public OverlayInfo getOverlayInfo(@Nullable final String packageName,
+                int userId) throws RemoteException {
+            userId = handleIncomingUser(userId, "getOverlayInfo");
+            if (packageName == null) {
+                return null;
+            }
+
+            synchronized (mLock) {
+                return mImpl.getOverlayInfo(packageName, userId);
+            }
+        }
+
+        @Override
+        public boolean setEnabled(@Nullable final String packageName, final boolean enable,
+                int userId) throws RemoteException {
+            enforceChangeOverlayPackagesPermission("setEnabled");
+            userId = handleIncomingUser(userId, "setEnabled");
+            if (packageName == null) {
+                return false;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    return mImpl.setEnabled(packageName, enable, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public boolean setPriority(@Nullable final String packageName,
+                @Nullable final String parentPackageName, int userId) throws RemoteException {
+            enforceChangeOverlayPackagesPermission("setPriority");
+            userId = handleIncomingUser(userId, "setPriority");
+            if (packageName == null || parentPackageName == null) {
+                return false;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    return mImpl.setPriority(packageName, parentPackageName, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public boolean setHighestPriority(@Nullable final String packageName, int userId)
+                throws RemoteException {
+            enforceChangeOverlayPackagesPermission("setHighestPriority");
+            userId = handleIncomingUser(userId, "setHighestPriority");
+            if (packageName == null) {
+                return false;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    return mImpl.setHighestPriority(packageName, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public boolean setLowestPriority(@Nullable final String packageName, int userId)
+                throws RemoteException {
+            enforceChangeOverlayPackagesPermission("setLowestPriority");
+            userId = handleIncomingUser(userId, "setLowestPriority");
+            if (packageName == null) {
+                return false;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    return mImpl.setLowestPriority(packageName, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
+        public void onShellCommand(@NonNull final FileDescriptor in,
+                @NonNull final FileDescriptor out, @NonNull final FileDescriptor err,
+                @NonNull final String[] args, @NonNull final ShellCallback callback,
+                @NonNull final ResultReceiver resultReceiver) {
+            (new OverlayManagerShellCommand(this)).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
+
+        @Override
+        protected void dump(@NonNull final FileDescriptor fd, @NonNull final PrintWriter pw,
+                @NonNull final String[] argv) {
+            enforceDumpPermission("dump");
+
+            final boolean verbose = argv.length > 0 && "--verbose".equals(argv[0]);
+
+            synchronized (mLock) {
+                mImpl.onDump(pw);
+                mPackageManager.dump(pw, verbose);
+            }
+        }
+
+        /**
+         * Ensure that the caller has permission to interact with the given userId.
+         * If the calling user is not the same as the provided user, the caller needs
+         * to hold the INTERACT_ACROSS_USERS_FULL permission (or be system uid or
+         * root).
+         *
+         * @param userId the user to interact with
+         * @param message message for any SecurityException
+         */
+        private int handleIncomingUser(final int userId, @NonNull final String message) {
+            return ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+                    Binder.getCallingUid(), userId, false, true, message, null);
+        }
+
+        /**
+         * Enforce that the caller holds the CHANGE_OVERLAY_PACKAGES permission (or is
+         * system or root).
+         *
+         * @param message used as message if SecurityException is thrown
+         * @throws SecurityException if the permission check fails
+         */
+        private void enforceChangeOverlayPackagesPermission(@NonNull final String message) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.CHANGE_OVERLAY_PACKAGES, message);
+        }
+
+        /**
+         * Enforce that the caller holds the DUMP permission (or is system or root).
+         *
+         * @param message used as message if SecurityException is thrown
+         * @throws SecurityException if the permission check fails
+         */
+        private void enforceDumpPermission(@NonNull final String message) {
+            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
+                    message);
+        }
+    };
+
+    private boolean isOverlayPackage(@NonNull final PackageInfo pi) {
+        return pi != null && pi.overlayTarget != null;
+    }
+
+    private final class OverlayChangeListener implements OverlayManagerSettings.ChangeListener {
+        @Override
+        public void onSettingsChanged() {
+            schedulePersistSettings();
+        }
+
+        @Override
+        public void onOverlayAdded(@NonNull final OverlayInfo oi) {
+            scheduleBroadcast(Intent.ACTION_OVERLAY_ADDED, oi, oi.isEnabled());
+        }
+
+        @Override
+        public void onOverlayRemoved(@NonNull final OverlayInfo oi) {
+            scheduleBroadcast(Intent.ACTION_OVERLAY_REMOVED, oi, oi.isEnabled());
+        }
+
+        @Override
+        public void onOverlayChanged(@NonNull final OverlayInfo oi,
+                @NonNull final OverlayInfo oldOi) {
+            scheduleBroadcast(Intent.ACTION_OVERLAY_CHANGED, oi, oi.isEnabled() != oldOi.isEnabled());
+        }
+
+        @Override
+        public void onOverlayPriorityChanged(@NonNull final OverlayInfo oi) {
+            scheduleBroadcast(Intent.ACTION_OVERLAY_PRIORITY_CHANGED, oi, oi.isEnabled());
+        }
+
+        private void scheduleBroadcast(@NonNull final String action, @NonNull final OverlayInfo oi,
+                final boolean doUpdate) {
+            FgThread.getHandler().post(new BroadcastRunnable(action, oi, doUpdate));
+        }
+
+        private final class BroadcastRunnable implements Runnable {
+            private final String mAction;
+            private final OverlayInfo mOverlayInfo;
+            private final boolean mDoUpdate;
+
+            BroadcastRunnable(@NonNull final String action, @NonNull final OverlayInfo oi,
+                    final boolean doUpdate) {
+                mAction = action;
+                mOverlayInfo = oi;
+                mDoUpdate = doUpdate;
+            }
+
+            @Override
+            public void run() {
+                if (mDoUpdate) {
+                    updateAssets(mOverlayInfo.userId, mOverlayInfo.targetPackageName);
+                }
+                sendBroadcast(mAction, mOverlayInfo.targetPackageName, mOverlayInfo.packageName,
+                        mOverlayInfo.userId);
+            }
+
+            private void sendBroadcast(@NonNull final String action,
+                    @NonNull final String targetPackageName, @NonNull final String packageName,
+                    final int userId) {
+                final Intent intent = new Intent(action, Uri.fromParts("package",
+                            String.format("%s/%s", targetPackageName, packageName), null));
+                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                if (DEBUG) {
+                    Slog.d(TAG, String.format("send broadcast %s", intent));
+                }
+                try {
+                    ActivityManagerNative.getDefault().broadcastIntent(null, intent, null, null, 0,
+                            null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false,
+                            userId);
+                } catch (RemoteException e) {
+                    // Intentionally left empty.
+                }
+            }
+
+        }
+    }
+
+    private void updateAssets(final int userId, final String targetPackageName) {
+        final List<String> list = new ArrayList<>();
+        list.add(targetPackageName);
+        updateAssets(userId, list);
+    }
+
+    private void updateAssets(final int userId, List<String> targetPackageNames) {
+        // TODO: implement when we integrate OMS properly
+    }
+
+    private void schedulePersistSettings() {
+        if (mPersistSettingsScheduled.getAndSet(true)) {
+            return;
+        }
+        IoThread.getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                mPersistSettingsScheduled.set(false);
+                synchronized (mLock) {
+                    FileOutputStream stream = null;
+                    try {
+                        stream = mSettingsFile.startWrite();
+                        mSettings.persist(stream);
+                        mSettingsFile.finishWrite(stream);
+                    } catch (IOException | XmlPullParserException e) {
+                        mSettingsFile.failWrite(stream);
+                        Slog.e(TAG, "failed to persist overlay state", e);
+                    }
+                }
+            }
+        });
+    }
+
+    private void restoreSettings() {
+        synchronized (mLock) {
+            if (!mSettingsFile.getBaseFile().exists()) {
+                return;
+            }
+            try (final FileInputStream stream = mSettingsFile.openRead()) {
+                mSettings.restore(stream);
+
+                // We might have data for dying users if the device was
+                // restarted before we received USER_REMOVED. Remove data for
+                // users that will not exist after the system is ready.
+
+                final List<UserInfo> deadUsers = getDeadUsers();
+                final int N = deadUsers.size();
+                for (int i = 0; i < N; i++) {
+                    final UserInfo deadUser = deadUsers.get(i);
+                    final int userId = deadUser.getUserHandle().getIdentifier();
+                    mSettings.removeUser(userId);
+                }
+            } catch (IOException | XmlPullParserException e) {
+                Slog.e(TAG, "failed to restore overlay state", e);
+            }
+        }
+    }
+
+    private List<UserInfo> getDeadUsers() {
+        final List<UserInfo> users = mUserManager.getUsers(false);
+        final List<UserInfo> onlyLiveUsers = mUserManager.getUsers(true);
+        users.removeAll(onlyLiveUsers);
+        return users;
+    }
+
+    private static final class PackageManagerHelper implements
+            OverlayManagerServiceImpl.PackageManagerHelper {
+
+        private final IPackageManager mPackageManager;
+        private final PackageManagerInternal mPackageManagerInternal;
+
+        // Use a cache for performance and for consistency within OMS: because
+        // additional PACKAGE_* intents may be delivered while we process an
+        // intent, querying the PackageManagerService for the actual current
+        // state may lead to contradictions within OMS. Better then to lag
+        // behind until all pending intents have been processed.
+        private final SparseArray<HashMap<String, PackageInfo>> mCache = new SparseArray<>();
+
+        PackageManagerHelper() {
+            mPackageManager = getPackageManager();
+            mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+        }
+
+        public PackageInfo getPackageInfo(@NonNull final String packageName, final int userId,
+                final boolean useCache) {
+            if (useCache) {
+                final PackageInfo cachedPi = getCachedPackageInfo(packageName, userId);
+                if (cachedPi != null) {
+                    return cachedPi;
+                }
+            }
+            try {
+                final PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0, userId);
+                if (useCache && pi != null) {
+                    cachePackageInfo(packageName, userId, pi);
+                }
+                return pi;
+            } catch (RemoteException e) {
+                // Intentionally left empty.
+            }
+            return null;
+        }
+
+        @Override
+        public PackageInfo getPackageInfo(@NonNull final String packageName, final int userId) {
+            return getPackageInfo(packageName, userId, true);
+        }
+
+        @Override
+        public boolean signaturesMatching(@NonNull final String packageName1,
+                @NonNull final String packageName2, final int userId) {
+            // The package manager does not support different versions of packages
+            // to be installed for different users: ignore userId for now.
+            try {
+                return mPackageManager.checkSignatures(packageName1, packageName2) == SIGNATURE_MATCH;
+            } catch (RemoteException e) {
+                // Intentionally left blank
+            }
+            return false;
+        }
+
+        @Override
+        public List<PackageInfo> getOverlayPackages(final int userId) {
+            return mPackageManagerInternal.getOverlayPackages(userId);
+        }
+
+        public PackageInfo getCachedPackageInfo(@NonNull final String packageName,
+                final int userId) {
+            final HashMap<String, PackageInfo> map = mCache.get(userId);
+            return map == null ? null : map.get(packageName);
+        }
+
+        public void cachePackageInfo(@NonNull final String packageName, final int userId,
+                @NonNull final PackageInfo pi) {
+            HashMap<String, PackageInfo> map = mCache.get(userId);
+            if (map == null) {
+                map = new HashMap<>();
+                mCache.put(userId, map);
+            }
+            map.put(packageName, pi);
+        }
+
+        public void forgetPackageInfo(@NonNull final String packageName, final int userId) {
+            final HashMap<String, PackageInfo> map = mCache.get(userId);
+            if (map == null) {
+                return;
+            }
+            map.remove(packageName);
+            if (map.isEmpty()) {
+                mCache.delete(userId);
+            }
+        }
+
+        public void forgetAllPackageInfos(final int userId) {
+            mCache.delete(userId);
+        }
+
+        private static final String TAB1 = "    ";
+        private static final String TAB2 = TAB1 + TAB1;
+
+        public void dump(@NonNull final PrintWriter pw, final boolean verbose) {
+            pw.println("PackageInfo cache");
+
+            if (!verbose) {
+                int count = 0;
+                final int N = mCache.size();
+                for (int i = 0; i < N; i++) {
+                    final int userId = mCache.keyAt(i);
+                    count += mCache.get(userId).size();
+                }
+                pw.println(TAB1 + count + " package(s)");
+                return;
+            }
+
+            if (mCache.size() == 0) {
+                pw.println(TAB1 + "<empty>");
+                return;
+            }
+
+            final int N = mCache.size();
+            for (int i = 0; i < N; i++) {
+                final int userId = mCache.keyAt(i);
+                pw.println(TAB1 + "User " + userId);
+                final HashMap<String, PackageInfo> map = mCache.get(userId);
+                for (Map.Entry<String, PackageInfo> entry : map.entrySet()) {
+                    pw.println(TAB2 + entry.getKey() + ": " + entry.getValue());
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
new file mode 100644
index 0000000..0e33409
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static android.content.om.OverlayInfo.STATE_DISABLED;
+import static android.content.om.OverlayInfo.STATE_ENABLED;
+import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
+import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
+
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Internal implementation of OverlayManagerService.
+ *
+ * Methods in this class should only be called by the OverlayManagerService.
+ * This class is not thread-safe; the caller is expected to ensure the
+ * necessary thread synchronization.
+ *
+ * @see OverlayManagerService
+ */
+final class OverlayManagerServiceImpl {
+    private final PackageManagerHelper mPackageManager;
+    private final IdmapManager mIdmapManager;
+    private final OverlayManagerSettings mSettings;
+
+    OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
+            @NonNull final IdmapManager idmapManager,
+            @NonNull final OverlayManagerSettings settings) {
+        mPackageManager = packageManager;
+        mIdmapManager = idmapManager;
+        mSettings = settings;
+    }
+
+    /*
+     * Call this when switching to a new Android user. Will return a list of
+     * target packages that must refresh their overlays. This list is the union
+     * of two sets: the set of targets with currently active overlays, and the
+     * set of targets that had, but no longer have, active overlays.
+     */
+    List<String> onSwitchUser(final int newUserId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onSwitchUser newUserId=" + newUserId);
+        }
+
+        final Set<String> packagesToUpdateAssets = new ArraySet<>();
+        final ArrayMap<String, List<OverlayInfo>> tmp = mSettings.getOverlaysForUser(newUserId);
+        final int tmpSize = tmp.size();
+        final ArrayMap<String, OverlayInfo> storedOverlayInfos = new ArrayMap<>(tmpSize);
+        for (int i = 0; i < tmpSize; i++) {
+            final List<OverlayInfo> chunk = tmp.valueAt(i);
+            final int chunkSize = chunk.size();
+            for (int j = 0; j < chunkSize; j++) {
+                final OverlayInfo oi = chunk.get(j);
+                storedOverlayInfos.put(oi.packageName, oi);
+            }
+        }
+
+        List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId);
+        final int overlayPackagesSize = overlayPackages.size();
+        for (int i = 0; i < overlayPackagesSize; i++) {
+            final PackageInfo overlayPackage = overlayPackages.get(i);
+            final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
+            if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
+                if (oi != null) {
+                    packagesToUpdateAssets.add(oi.targetPackageName);
+                }
+                mSettings.init(overlayPackage.packageName, newUserId,
+                        overlayPackage.overlayTarget,
+                        overlayPackage.applicationInfo.getBaseCodePath());
+            }
+
+            try {
+                final PackageInfo targetPackage =
+                        mPackageManager.getPackageInfo(overlayPackage.overlayTarget, newUserId);
+                updateState(targetPackage, overlayPackage, newUserId);
+            } catch (OverlayManagerSettings.BadKeyException e) {
+                Slog.e(TAG, "failed to update settings", e);
+                mSettings.remove(overlayPackage.packageName, newUserId);
+            }
+
+            packagesToUpdateAssets.add(overlayPackage.overlayTarget);
+            storedOverlayInfos.remove(overlayPackage.packageName);
+        }
+
+        // any OverlayInfo left in storedOverlayInfos is no longer
+        // installed and should be removed
+        final int storedOverlayInfosSize = storedOverlayInfos.size();
+        for (int i = 0; i < storedOverlayInfosSize; i++) {
+            final OverlayInfo oi = storedOverlayInfos.get(i);
+            mSettings.remove(oi.packageName, oi.userId);
+            removeIdmapIfPossible(oi);
+            packagesToUpdateAssets.add(oi.targetPackageName);
+        }
+
+        // remove target packages that are not installed
+        final Iterator<String> iter = packagesToUpdateAssets.iterator();
+        while (iter.hasNext()) {
+            String targetPackageName = iter.next();
+            if (mPackageManager.getPackageInfo(targetPackageName, newUserId) == null) {
+                iter.remove();
+            }
+        }
+
+        return new ArrayList<String>(packagesToUpdateAssets);
+    }
+
+    void onUserRemoved(final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onUserRemoved userId=" + userId);
+        }
+        mSettings.removeUser(userId);
+    }
+
+    void onTargetPackageAdded(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
+        }
+
+        final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId);
+        updateAllOverlaysForTarget(packageName, userId, targetPackage);
+    }
+
+    void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
+        }
+
+        final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId);
+        updateAllOverlaysForTarget(packageName, userId, targetPackage);
+    }
+
+    void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId=" + userId);
+        }
+
+        updateAllOverlaysForTarget(packageName, userId, null);
+    }
+
+    void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
+        }
+
+        final PackageInfo targetPackage = mPackageManager.getPackageInfo(packageName, userId);
+        updateAllOverlaysForTarget(packageName, userId, targetPackage);
+    }
+
+    void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
+        }
+
+        updateAllOverlaysForTarget(packageName, userId, null);
+    }
+
+    private void updateAllOverlaysForTarget(@NonNull final String packageName, final int userId,
+            @Nullable final PackageInfo targetPackage) {
+        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId);
+        final int N = ois.size();
+        for (int i = 0; i < N; i++) {
+            final OverlayInfo oi = ois.get(i);
+            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId);
+            if (overlayPackage == null) {
+                mSettings.remove(oi.packageName, oi.userId);
+                removeIdmapIfPossible(oi);
+            } else {
+                try {
+                    updateState(targetPackage, overlayPackage, userId);
+                } catch (OverlayManagerSettings.BadKeyException e) {
+                    Slog.e(TAG, "failed to update settings", e);
+                    mSettings.remove(oi.packageName, userId);
+                }
+            }
+        }
+    }
+
+    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, "onOverlayPackageAdded packageName=" + packageName + " userId=" + userId);
+        }
+
+        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
+        if (overlayPackage == null) {
+            Slog.w(TAG, "overlay package " + packageName + " was added, but couldn't be found");
+            onOverlayPackageRemoved(packageName, userId);
+            return;
+        }
+
+        final PackageInfo targetPackage =
+                mPackageManager.getPackageInfo(overlayPackage.overlayTarget, userId);
+
+        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
+                overlayPackage.applicationInfo.getBaseCodePath());
+        try {
+            updateState(targetPackage, overlayPackage, userId);
+        } catch (OverlayManagerSettings.BadKeyException e) {
+            Slog.e(TAG, "failed to update settings", e);
+            mSettings.remove(packageName, userId);
+        }
+    }
+
+    void onOverlayPackageChanged(@NonNull final String packageName, final int userId) {
+        Slog.wtf(TAG, "onOverlayPackageChanged called, but only pre-installed overlays supported");
+    }
+
+    void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) {
+        Slog.wtf(TAG, "onOverlayPackageUpgrading called, but only pre-installed overlays supported");
+    }
+
+    void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) {
+        Slog.wtf(TAG, "onOverlayPackageUpgraded called, but only pre-installed overlays supported");
+    }
+
+    void onOverlayPackageRemoved(@NonNull final String packageName, final int userId) {
+        Slog.wtf(TAG, "onOverlayPackageRemoved called, but only pre-installed overlays supported");
+    }
+
+    OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId) {
+        try {
+            return mSettings.getOverlayInfo(packageName, userId);
+        } catch (OverlayManagerSettings.BadKeyException e) {
+            return null;
+        }
+    }
+
+    List<OverlayInfo> getOverlayInfosForTarget(@NonNull final String targetPackageName,
+            final int userId) {
+        return mSettings.getOverlaysForTarget(targetPackageName, userId);
+    }
+
+    Map<String, List<OverlayInfo>> getOverlaysForUser(final int userId) {
+        return mSettings.getOverlaysForUser(userId);
+    }
+
+    boolean setEnabled(@NonNull final String packageName, final boolean enable,
+            final int userId) {
+        if (DEBUG) {
+            Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
+                        packageName, enable, userId));
+        }
+
+        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
+        if (overlayPackage == null) {
+            return false;
+        }
+
+        try {
+            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
+            final PackageInfo targetPackage =
+                    mPackageManager.getPackageInfo(oi.targetPackageName, userId);
+            mSettings.setEnabled(packageName, userId, enable);
+            updateState(targetPackage, overlayPackage, userId);
+            return true;
+        } catch (OverlayManagerSettings.BadKeyException e) {
+            return false;
+        }
+    }
+
+    boolean setPriority(@NonNull final String packageName,
+            @NonNull final String newParentPackageName, final int userId) {
+        return mSettings.setPriority(packageName, newParentPackageName, userId);
+    }
+
+    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
+        return mSettings.setHighestPriority(packageName, userId);
+    }
+
+    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
+        return mSettings.setLowestPriority(packageName, userId);
+    }
+
+    void onDump(@NonNull final PrintWriter pw) {
+        mSettings.dump(pw);
+    }
+
+    List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
+            final int userId) {
+        final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, userId);
+        final List<String> paths = new ArrayList<>(overlays.size());
+        final int N = overlays.size();
+        for (int i = 0; i < N; i++) {
+            final OverlayInfo oi = overlays.get(i);
+            if (oi.isEnabled()) {
+                paths.add(oi.packageName);
+            }
+        }
+        return paths;
+    }
+
+    private void updateState(@Nullable final PackageInfo targetPackage,
+            @NonNull final PackageInfo overlayPackage, final int userId)
+        throws OverlayManagerSettings.BadKeyException {
+        if (targetPackage != null) {
+            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
+        }
+
+        mSettings.setBaseCodePath(overlayPackage.packageName, userId,
+                overlayPackage.applicationInfo.getBaseCodePath());
+
+        final int currentState = mSettings.getState(overlayPackage.packageName, userId);
+        final int newState = calculateNewState(targetPackage, overlayPackage, userId);
+        if (currentState != newState) {
+            if (DEBUG) {
+                Slog.d(TAG, String.format("%s:%d: %s -> %s",
+                            overlayPackage.packageName, userId,
+                            OverlayInfo.stateToString(currentState),
+                            OverlayInfo.stateToString(newState)));
+            }
+            mSettings.setState(overlayPackage.packageName, userId, newState);
+        }
+    }
+
+    private int calculateNewState(@Nullable final PackageInfo targetPackage,
+            @NonNull final PackageInfo overlayPackage, final int userId)
+        throws OverlayManagerSettings.BadKeyException {
+        if (targetPackage == null) {
+            return STATE_MISSING_TARGET;
+        }
+
+        if (!mIdmapManager.idmapExists(overlayPackage, userId)) {
+            return STATE_NO_IDMAP;
+        }
+
+        final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId);
+        return enabled ? STATE_ENABLED : STATE_DISABLED;
+    }
+
+    private void removeIdmapIfPossible(@NonNull final OverlayInfo oi) {
+        // For a given package, all Android users share the same idmap file.
+        // This works because Android currently does not support users to
+        // install different versions of the same package. It also means we
+        // cannot remove an idmap file if any user still needs it.
+        //
+        // When/if the Android framework allows different versions of the same
+        // package to be installed for different users, idmap file handling
+        // should be revised:
+        //
+        // - an idmap file should be unique for each {user, package} pair
+        //
+        // - the path to the idmap file should be passed to the native Asset
+        //   Manager layers, just like the path to the apk is passed today
+        //
+        // As part of that change, calls to this method should be replaced by
+        // direct calls to IdmapManager.removeIdmap, without looping over all
+        // users.
+
+        if (!mIdmapManager.idmapExists(oi)) {
+            return;
+        }
+        final List<Integer> userIds = mSettings.getUsers();
+        final int N = userIds.size();
+        for (int i = 0; i < N; i++) {
+            final int userId = userIds.get(i);
+            try {
+                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
+                if (tmp != null && tmp.isEnabled()) {
+                    // someone is still using the idmap file -> we cannot remove it
+                    return;
+                }
+            } catch (OverlayManagerSettings.BadKeyException e) {
+                // intentionally left empty
+            }
+        }
+        mIdmapManager.removeIdmap(oi, oi.userId);
+    }
+
+    interface PackageManagerHelper {
+        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
+        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
+                                   int userId);
+        List<PackageInfo> getOverlayPackages(int userId);
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
new file mode 100644
index 0000000..44908a7
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import static android.content.om.OverlayInfo.STATE_UNKNOWN;
+
+import static com.android.server.om.OverlayManagerService.DEBUG;
+import static com.android.server.om.OverlayManagerService.TAG;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.OverlayInfo;
+import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+/**
+ * Data structure representing the current state of all overlay packages in the
+ * system.
+ *
+ * Modifications to the data are exposed through the ChangeListener interface.
+ *
+ * @see ChangeListener
+ * @see OverlayManagerService
+ */
+final class OverlayManagerSettings {
+    private final List<ChangeListener> mListeners = new ArrayList<>();
+
+    private final ArrayList<SettingsItem> mItems = new ArrayList<>();
+
+    void init(@NonNull final String packageName, final int userId,
+            @NonNull final String targetPackageName, @NonNull final String baseCodePath) {
+        remove(packageName, userId);
+        final SettingsItem item =
+                new SettingsItem(packageName, userId, targetPackageName, baseCodePath);
+        mItems.add(item);
+    }
+
+    void remove(@NonNull final String packageName, final int userId) {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            return;
+        }
+        final OverlayInfo oi = item.getOverlayInfo();
+        mItems.remove(item);
+        if (oi != null) {
+            notifyOverlayRemoved(oi);
+        }
+    }
+
+    boolean contains(@NonNull final String packageName, final int userId) {
+        return select(packageName, userId) != null;
+    }
+
+    OverlayInfo getOverlayInfo(@NonNull final String packageName, final int userId)
+            throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return item.getOverlayInfo();
+    }
+
+    String getTargetPackageName(@NonNull final String packageName, final int userId)
+            throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return item.getTargetPackageName();
+    }
+
+    void setBaseCodePath(@NonNull final String packageName, final int userId,
+            @NonNull final String path) throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        item.setBaseCodePath(path);
+        notifySettingsChanged();
+    }
+
+    boolean getEnabled(@NonNull final String packageName, final int userId) throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return item.isEnabled();
+    }
+
+    void setEnabled(@NonNull final String packageName, final int userId, final boolean enable)
+            throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        if (enable == item.isEnabled()) {
+            return; // nothing to do
+        }
+
+        item.setEnabled(enable);
+        notifySettingsChanged();
+    }
+
+    int getState(@NonNull final String packageName, final int userId) throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        return item.getState();
+    }
+
+    void setState(@NonNull final String packageName, final int userId, final int state)
+            throws BadKeyException {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            throw new BadKeyException(packageName, userId);
+        }
+        final OverlayInfo previous = item.getOverlayInfo();
+        item.setState(state);
+        final OverlayInfo current = item.getOverlayInfo();
+        if (previous.state == STATE_UNKNOWN) {
+            notifyOverlayAdded(current);
+            notifySettingsChanged();
+        } else if (current.state != previous.state) {
+            notifyOverlayChanged(current, previous);
+            notifySettingsChanged();
+        }
+    }
+
+    List<OverlayInfo> getOverlaysForTarget(@NonNull final String targetPackageName,
+            final int userId) {
+        final List<SettingsItem> items = selectWhereTarget(targetPackageName, userId);
+        if (items.isEmpty()) {
+            return Collections.emptyList();
+        }
+        final List<OverlayInfo> out = new ArrayList<>(items.size());
+        final int N = items.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = items.get(i);
+            out.add(item.getOverlayInfo());
+        }
+        return out;
+    }
+
+    ArrayMap<String, List<OverlayInfo>> getOverlaysForUser(final int userId) {
+        final List<SettingsItem> items = selectWhereUser(userId);
+        if (items.isEmpty()) {
+            return ArrayMap.EMPTY;
+        }
+        final ArrayMap<String, List<OverlayInfo>> out = new ArrayMap<>(items.size());
+        final int N = items.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = items.get(i);
+            final String targetPackageName = item.getTargetPackageName();
+            if (!out.containsKey(targetPackageName)) {
+                out.put(targetPackageName, new ArrayList<OverlayInfo>());
+            }
+            final List<OverlayInfo> overlays = out.get(targetPackageName);
+            overlays.add(item.getOverlayInfo());
+        }
+        return out;
+    }
+
+    List<String> getTargetPackageNamesForUser(final int userId) {
+        final List<SettingsItem> items = selectWhereUser(userId);
+        if (items.isEmpty()) {
+            return Collections.emptyList();
+        }
+        final List<String> out = new ArrayList<>();
+        final int N = items.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = items.get(i);
+            final String targetPackageName = item.getTargetPackageName();
+            if (!out.contains(targetPackageName)) {
+                out.add(targetPackageName);
+            }
+        }
+        return out;
+    }
+
+    List<Integer> getUsers() {
+        final ArrayList<Integer> users = new ArrayList<>();
+        final int N = mItems.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = mItems.get(i);
+            if (!users.contains(item.userId)) {
+                users.add(item.userId);
+            }
+        }
+        return users;
+    }
+
+    void removeUser(final int userId) {
+        final Iterator<SettingsItem> iter = mItems.iterator();
+        while (iter.hasNext()) {
+            final SettingsItem item = iter.next();
+            if (item.userId == userId) {
+                iter.remove();
+            }
+        }
+    }
+
+    boolean setPriority(@NonNull final String packageName,
+            @NonNull final String newParentPackageName, final int userId) {
+        if (packageName.equals(newParentPackageName)) {
+            return false;
+        }
+        final SettingsItem rowToMove = select(packageName, userId);
+        if (rowToMove == null) {
+            return false;
+        }
+        final SettingsItem newParentRow = select(newParentPackageName, userId);
+        if (newParentRow == null) {
+            return false;
+        }
+        if (!rowToMove.getTargetPackageName().equals(newParentRow.getTargetPackageName())) {
+            return false;
+        }
+
+        mItems.remove(rowToMove);
+        final ListIterator<SettingsItem> iter = mItems.listIterator();
+        while (iter.hasNext()) {
+            final SettingsItem item = iter.next();
+            if (item.userId == userId && item.packageName.equals(newParentPackageName)) {
+                iter.add(rowToMove);
+                notifyOverlayPriorityChanged(rowToMove.getOverlayInfo());
+                notifySettingsChanged();
+                return true;
+            }
+        }
+
+        Slog.wtf(TAG, "failed to find the parent item a second time");
+        return false;
+    }
+
+    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            return false;
+        }
+        mItems.remove(item);
+        mItems.add(0, item);
+        notifyOverlayPriorityChanged(item.getOverlayInfo());
+        notifySettingsChanged();
+        return true;
+    }
+
+    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
+        final SettingsItem item = select(packageName, userId);
+        if (item == null) {
+            return false;
+        }
+        mItems.remove(item);
+        mItems.add(item);
+        notifyOverlayPriorityChanged(item.getOverlayInfo());
+        notifySettingsChanged();
+        return true;
+    }
+
+    private static final String TAB1 = "    ";
+    private static final String TAB2 = TAB1 + TAB1;
+    private static final String TAB3 = TAB2 + TAB1;
+
+    void dump(@NonNull final PrintWriter pw) {
+        pw.println("Settings");
+        dumpItems(pw);
+        dumpListeners(pw);
+    }
+
+    private void dumpItems(@NonNull final PrintWriter pw) {
+        pw.println(TAB1 + "Items");
+
+        if (mItems.isEmpty()) {
+            pw.println(TAB2 + "<none>");
+            return;
+        }
+
+        final int N = mItems.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = mItems.get(i);
+            final StringBuilder sb = new StringBuilder();
+            sb.append(TAB2 + item.packageName + ":" + item.userId + " {\n");
+            sb.append(TAB3 + "packageName.......: " + item.packageName + "\n");
+            sb.append(TAB3 + "userId............: " + item.userId + "\n");
+            sb.append(TAB3 + "targetPackageName.: " + item.getTargetPackageName() + "\n");
+            sb.append(TAB3 + "baseCodePath......: " + item.getBaseCodePath() + "\n");
+            sb.append(TAB3 + "state.............: " + OverlayInfo.stateToString(item.getState()) + "\n");
+            sb.append(TAB3 + "isEnabled.........: " + item.isEnabled() + "\n");
+            sb.append(TAB2 + "}");
+            pw.println(sb.toString());
+        }
+    }
+
+    private void dumpListeners(@NonNull final PrintWriter pw) {
+        pw.println(TAB1 + "Change listeners");
+
+        if (mListeners.isEmpty()) {
+            pw.println(TAB2 + "<none>");
+            return;
+        }
+
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener ch = mListeners.get(i);
+            pw.println(TAB2 + ch);
+        }
+
+    }
+
+    void restore(@NonNull final InputStream is) throws IOException, XmlPullParserException {
+        Serializer.restore(mItems, is);
+    }
+
+    void persist(@NonNull final OutputStream os) throws IOException, XmlPullParserException {
+        Serializer.persist(mItems, os);
+    }
+
+    private static final class Serializer {
+        private static final String TAG_OVERLAYS = "overlays";
+        private static final String TAG_ITEM = "item";
+
+        private static final String ATTR_BASE_CODE_PATH = "baseCodePath";
+        private static final String ATTR_IS_ENABLED = "isEnabled";
+        private static final String ATTR_PACKAGE_NAME = "packageName";
+        private static final String ATTR_STATE = "state";
+        private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName";
+        private static final String ATTR_USER_ID = "userId";
+        private static final String ATTR_VERSION = "version";
+
+        private static final int CURRENT_VERSION = 1;
+
+        public static void restore(@NonNull final ArrayList<SettingsItem> table,
+                @NonNull final InputStream is) throws IOException, XmlPullParserException {
+
+            try (InputStreamReader reader = new InputStreamReader(is)) {
+                table.clear();
+                final XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(reader);
+                XmlUtils.beginDocument(parser, TAG_OVERLAYS);
+                int version = XmlUtils.readIntAttribute(parser, ATTR_VERSION);
+                if (version != CURRENT_VERSION) {
+                    throw new XmlPullParserException("unrecognized version " + version);
+                }
+                int depth = parser.getDepth();
+
+                while (XmlUtils.nextElementWithin(parser, depth)) {
+                    switch (parser.getName()) {
+                        case TAG_ITEM:
+                            final SettingsItem item = restoreRow(parser, depth + 1);
+                            table.add(item);
+                            break;
+                    }
+                }
+            }
+        }
+
+        private static SettingsItem restoreRow(@NonNull final XmlPullParser parser, final int depth)
+                throws IOException {
+            final String packageName = XmlUtils.readStringAttribute(parser, ATTR_PACKAGE_NAME);
+            final int userId = XmlUtils.readIntAttribute(parser, ATTR_USER_ID);
+            final String targetPackageName = XmlUtils.readStringAttribute(parser,
+                    ATTR_TARGET_PACKAGE_NAME);
+            final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH);
+            final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE);
+            final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED);
+
+            return new SettingsItem(packageName, userId, targetPackageName, baseCodePath, state,
+                    isEnabled);
+        }
+
+        public static void persist(@NonNull final ArrayList<SettingsItem> table,
+                @NonNull final OutputStream os) throws IOException, XmlPullParserException {
+            final FastXmlSerializer xml = new FastXmlSerializer();
+            xml.setOutput(os, "utf-8");
+            xml.startDocument(null, true);
+            xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            xml.startTag(null, TAG_OVERLAYS);
+            XmlUtils.writeIntAttribute(xml, ATTR_VERSION, CURRENT_VERSION);
+
+            final int N = table.size();
+            for (int i = 0; i < N; i++) {
+                final SettingsItem item = table.get(i);
+                persistRow(xml, item);
+            }
+            xml.endTag(null, TAG_OVERLAYS);
+            xml.endDocument();
+        }
+
+        private static void persistRow(@NonNull final FastXmlSerializer xml,
+                @NonNull final SettingsItem item) throws IOException {
+            xml.startTag(null, TAG_ITEM);
+            XmlUtils.writeStringAttribute(xml, ATTR_PACKAGE_NAME, item.packageName);
+            XmlUtils.writeIntAttribute(xml, ATTR_USER_ID, item.userId);
+            XmlUtils.writeStringAttribute(xml, ATTR_TARGET_PACKAGE_NAME, item.targetPackageName);
+            XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.baseCodePath);
+            XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.state);
+            XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.isEnabled);
+            xml.endTag(null, TAG_ITEM);
+        }
+    }
+
+    private static final class SettingsItem {
+        private final int userId;
+        private final String packageName;
+        private final String targetPackageName;
+        private String baseCodePath;
+        private int state;
+        private boolean isEnabled;
+        private OverlayInfo cache;
+
+        SettingsItem(@NonNull final String packageName, final int userId,
+                @NonNull final String targetPackageName, @NonNull final String baseCodePath,
+                final int state, final boolean isEnabled) {
+            this.packageName = packageName;
+            this.userId = userId;
+            this.targetPackageName = targetPackageName;
+            this.baseCodePath = baseCodePath;
+            this.state = state;
+            this.isEnabled = isEnabled;
+            cache = null;
+        }
+
+        SettingsItem(@NonNull final String packageName, final int userId,
+                @NonNull final String targetPackageName, @NonNull final String baseCodePath) {
+            this(packageName, userId, targetPackageName, baseCodePath, STATE_UNKNOWN,
+                    false);
+        }
+
+        private String getTargetPackageName() {
+            return targetPackageName;
+        }
+
+        private String getBaseCodePath() {
+            return baseCodePath;
+        }
+
+        private void setBaseCodePath(@NonNull final String path) {
+            if (!baseCodePath.equals(path)) {
+                baseCodePath = path;
+                invalidateCache();
+            }
+        }
+
+        private int getState() {
+            return state;
+        }
+
+        private void setState(final int state) {
+            if (this.state != state) {
+                this.state = state;
+                invalidateCache();
+            }
+        }
+
+        private boolean isEnabled() {
+            return isEnabled;
+        }
+
+        private void setEnabled(final boolean enable) {
+            if (isEnabled != enable) {
+                isEnabled = enable;
+                invalidateCache();
+            }
+        }
+
+        private OverlayInfo getOverlayInfo() {
+            if (cache == null) {
+                cache = new OverlayInfo(packageName, targetPackageName, baseCodePath,
+                        state, userId);
+            }
+            return cache;
+        }
+
+        private void invalidateCache() {
+            cache = null;
+        }
+    }
+
+    private SettingsItem select(@NonNull final String packageName, final int userId) {
+        final int N = mItems.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = mItems.get(i);
+            if (item.userId == userId && item.packageName.equals(packageName)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    private List<SettingsItem> selectWhereUser(final int userId) {
+        final ArrayList<SettingsItem> items = new ArrayList<>();
+        final int N = mItems.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = mItems.get(i);
+            if (item.userId == userId) {
+                items.add(item);
+            }
+        }
+        return items;
+    }
+
+    private List<SettingsItem> selectWhereTarget(@NonNull final String targetPackageName,
+            final int userId) {
+        final ArrayList<SettingsItem> items = new ArrayList<>();
+        final int N = mItems.size();
+        for (int i = 0; i < N; i++) {
+            final SettingsItem item = mItems.get(i);
+            if (item.userId == userId && item.getTargetPackageName().equals(targetPackageName)) {
+                items.add(item);
+            }
+        }
+        return items;
+    }
+
+    private void assertNotNull(@Nullable final Object o) {
+        if (o == null) {
+            throw new AndroidRuntimeException("object must not be null");
+        }
+    }
+
+    void addChangeListener(@NonNull final ChangeListener listener) {
+        mListeners.add(listener);
+    }
+
+    void removeChangeListener(@NonNull final ChangeListener listener) {
+        mListeners.remove(listener);
+    }
+
+    private void notifySettingsChanged() {
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener listener = mListeners.get(i);
+            listener.onSettingsChanged();
+        }
+    }
+
+    private void notifyOverlayAdded(@NonNull final OverlayInfo oi) {
+        if (DEBUG) {
+            assertNotNull(oi);
+        }
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener listener = mListeners.get(i);
+            listener.onOverlayAdded(oi);
+        }
+    }
+
+    private void notifyOverlayRemoved(@NonNull final OverlayInfo oi) {
+        if (DEBUG) {
+            assertNotNull(oi);
+        }
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener listener = mListeners.get(i);
+            listener.onOverlayRemoved(oi);
+        }
+    }
+
+    private void notifyOverlayChanged(@NonNull final OverlayInfo oi,
+            @NonNull final OverlayInfo oldOi) {
+        if (DEBUG) {
+            assertNotNull(oi);
+            assertNotNull(oldOi);
+        }
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener listener = mListeners.get(i);
+            listener.onOverlayChanged(oi, oldOi);
+        }
+    }
+
+    private void notifyOverlayPriorityChanged(@NonNull final OverlayInfo oi) {
+        if (DEBUG) {
+            assertNotNull(oi);
+        }
+        final int N = mListeners.size();
+        for (int i = 0; i < N; i++) {
+            final ChangeListener listener = mListeners.get(i);
+            listener.onOverlayPriorityChanged(oi);
+        }
+    }
+
+    interface ChangeListener {
+        void onSettingsChanged();
+        void onOverlayAdded(@NonNull OverlayInfo oi);
+        void onOverlayRemoved(@NonNull OverlayInfo oi);
+        void onOverlayChanged(@NonNull OverlayInfo oi, @NonNull OverlayInfo oldOi);
+        void onOverlayPriorityChanged(@NonNull OverlayInfo oi);
+    }
+
+    static final class BadKeyException extends RuntimeException {
+        BadKeyException(@NonNull final String packageName, final int userId) {
+            super("Bad key packageName=" + packageName + " userId=" + userId);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
new file mode 100644
index 0000000..29ddaf4
--- /dev/null
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.om;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of 'cmd overlay' commands.
+ *
+ * This class provides an interface to the OverlayManagerService via adb.
+ * Intended only for manual debugging. Execute 'adb exec-out cmd overlay help'
+ * for a list of available commands.
+ */
+final class OverlayManagerShellCommand extends ShellCommand {
+    private final IOverlayManager mInterface;
+
+    OverlayManagerShellCommand(@NonNull final IOverlayManager iom) {
+        mInterface = iom;
+    }
+
+    @Override
+    public int onCommand(@Nullable final String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        final PrintWriter err = getErrPrintWriter();
+        try {
+            switch (cmd) {
+                case "list":
+                    return runList();
+                case "enable":
+                    return runEnableDisable(true);
+                case "disable":
+                    return runEnableDisable(false);
+                case "set-priority":
+                    return runSetPriority();
+                default:
+                    return handleDefaultCommands(cmd);
+            }
+        } catch (IllegalArgumentException e) {
+            err.println("Error: " + e.getMessage());
+        } catch (RemoteException e) {
+            err.println("Remote exception: " + e);
+        }
+        return -1;
+    }
+
+    @Override
+    public void onHelp() {
+        final PrintWriter out = getOutPrintWriter();
+        out.println("Overlay manager (overlay) commands:");
+        out.println("  help");
+        out.println("    Print this help text.");
+        out.println("  dump [--verbose] [--user USER_ID] [PACKAGE [PACKAGE [...]]]");
+        out.println("    Print debugging information about the overlay manager.");
+        out.println("  list [--user USER_ID] [PACKAGE [PACKAGE [...]]]");
+        out.println("    Print information about target and overlay packages.");
+        out.println("    Overlay packages are printed in priority order. With optional");
+        out.println("    parameters PACKAGEs, limit output to the specified packages");
+        out.println("    but include more information about each package.");
+        out.println("  enable [--user USER_ID] PACKAGE");
+        out.println("    Enable overlay package PACKAGE.");
+        out.println("  disable [--user USER_ID] PACKAGE");
+        out.println("    Disable overlay package PACKAGE.");
+        out.println("  set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest");
+        out.println("    Change the priority of the overlay PACKAGE to be just higher than");
+        out.println("    the priority of PACKAGE_PARENT If PARENT is the special keyword");
+        out.println("    'lowest', change priority of PACKAGE to the lowest priority.");
+        out.println("    If PARENT is the special keyword 'highest', change priority of");
+        out.println("    PACKAGE to the highest priority.");
+    }
+
+    private int runList() throws RemoteException {
+        final PrintWriter out = getOutPrintWriter();
+        final PrintWriter err = getErrPrintWriter();
+
+        int userId = UserHandle.USER_SYSTEM;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                default:
+                    err.println("Error: Unknown option: " + opt);
+                    return 1;
+            }
+        }
+
+        final Map<String, List<OverlayInfo>> allOverlays = mInterface.getAllOverlays(userId);
+        for (final String targetPackageName : allOverlays.keySet()) {
+            out.println(targetPackageName);
+            List<OverlayInfo> overlaysForTarget = allOverlays.get(targetPackageName);
+            final int N = overlaysForTarget.size();
+            for (int i = 0; i < N; i++) {
+                final OverlayInfo oi = overlaysForTarget.get(i);
+                String status;
+                switch (oi.state) {
+                    case OverlayInfo.STATE_ENABLED:
+                        status = "[x]";
+                        break;
+                    case OverlayInfo.STATE_DISABLED:
+                        status = "[ ]";
+                        break;
+                    default:
+                        status = "---";
+                        break;
+                }
+                out.println(String.format("%s %s", status, oi.packageName));
+            }
+            out.println();
+        }
+        return 0;
+    }
+
+    private int runEnableDisable(final boolean enable) throws RemoteException {
+        final PrintWriter err = getErrPrintWriter();
+
+        int userId = UserHandle.USER_SYSTEM;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                default:
+                    err.println("Error: Unknown option: " + opt);
+                    return 1;
+            }
+        }
+
+        final String packageName = getNextArgRequired();
+        return mInterface.setEnabled(packageName, enable, userId) ? 0 : 1;
+    }
+
+    private int runSetPriority() throws RemoteException {
+        final PrintWriter err = getErrPrintWriter();
+
+        int userId = UserHandle.USER_SYSTEM;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--user":
+                    userId = UserHandle.parseUserArg(getNextArgRequired());
+                    break;
+                default:
+                    err.println("Error: Unknown option: " + opt);
+                    return 1;
+            }
+        }
+
+        final String packageName = getNextArgRequired();
+        final String newParentPackageName = getNextArgRequired();
+
+        if ("highest".equals(newParentPackageName)) {
+            return mInterface.setHighestPriority(packageName, userId) ? 0 : 1;
+        } else if ("lowest".equals(newParentPackageName)) {
+            return mInterface.setLowestPriority(packageName, userId) ? 0 : 1;
+        } else {
+            return mInterface.setPriority(packageName, newParentPackageName, userId) ? 0 : 1;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index abf3526..2e4e303 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -22863,6 +22863,43 @@
                 mExternalSourcesPolicy = policy;
             }
         }
+
+        @Override
+        public List<PackageInfo> getOverlayPackages(int userId) {
+            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
+            synchronized (mPackages) {
+                for (PackageParser.Package p : mPackages.values()) {
+                    if (p.mOverlayTarget != null) {
+                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
+                        if (pkg != null) {
+                            overlayPackages.add(pkg);
+                        }
+                    }
+                }
+            }
+            return overlayPackages;
+        }
+
+        @Override
+        public List<String> getTargetPackageNames(int userId) {
+            List<String> targetPackages = new ArrayList<>();
+            synchronized (mPackages) {
+                for (PackageParser.Package p : mPackages.values()) {
+                    if (p.mOverlayTarget == null) {
+                        targetPackages.add(p.packageName);
+                    }
+                }
+            }
+            return targetPackages;
+        }
+
+
+        @Override
+        public boolean setEnabledOverlayPackages(int userId, String targetPackageName,
+                List<String> overlayPackageNames) {
+            // TODO: implement when we integrate OMS properly
+            return false;
+        }
     }
 
     @Override
