Merge "Remove transaction ids in IApplicationThread."
diff --git a/Android.mk b/Android.mk
index cd738e7..552103d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -245,9 +245,9 @@
 	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
-	core/java/android/os/storage/IMountService.aidl \
-	core/java/android/os/storage/IMountServiceListener.aidl \
-	core/java/android/os/storage/IMountShutdownObserver.aidl \
+	core/java/android/os/storage/IStorageManager.aidl \
+	core/java/android/os/storage/IStorageEventListener.aidl \
+	core/java/android/os/storage/IStorageShutdownObserver.aidl \
 	core/java/android/os/storage/IObbActionListener.aidl \
 	core/java/android/security/IKeystoreService.aidl \
 	core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index cee8fdb..71e6af7 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -241,6 +241,7 @@
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit1_intermediates/src/com/android/test/split/feature/R.java)
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit2_intermediates/src/com/android/test/split/feature/R.java)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
 
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
index 88cb8e6..f56c763 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTest.java
@@ -16,7 +16,6 @@
 package android.multiuser;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
 import android.app.UserSwitchObserver;
@@ -86,7 +85,7 @@
         final Context context = InstrumentationRegistry.getContext();
         mUm = UserManager.get(context);
         mAm = context.getSystemService(ActivityManager.class);
-        mIam = ActivityManagerNative.getDefault();
+        mIam = ActivityManager.getService();
         mState = mPerfStatusReporter.getBenchmarkState();
         mUsersToRemove = new ArrayList<>();
     }
@@ -249,7 +248,7 @@
 
     private void registerUserSwitchObserver(final CountDownLatch switchLatch,
             final CountDownLatch bootCompleteLatch, final int userId) throws Exception {
-        ActivityManagerNative.getDefault().registerUserSwitchObserver(
+        ActivityManager.getService().registerUserSwitchObserver(
                 new UserSwitchObserver() {
                     @Override
                     public void onUserSwitchComplete(int newUserId) throws RemoteException {
diff --git a/api/current.txt b/api/current.txt
index fede9cf..3bf4954 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3892,6 +3892,7 @@
 
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
+    method public int getLaunchDisplayId();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -3902,6 +3903,7 @@
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
+    method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -7906,6 +7908,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8039,6 +8042,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -32192,6 +32196,7 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -63352,7 +63357,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -63361,7 +63369,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -63432,6 +63443,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/api/system-current.txt b/api/system-current.txt
index b5b7441..d32359cd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4024,6 +4024,7 @@
 
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
+    method public int getLaunchDisplayId();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4034,6 +4035,7 @@
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
+    method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
     field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
@@ -8238,6 +8240,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8371,6 +8374,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -34880,6 +34884,7 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -66878,7 +66883,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -66887,7 +66895,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -66958,6 +66969,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/api/test-current.txt b/api/test-current.txt
index 918400e..2999043 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3901,6 +3901,7 @@
 
   public class ActivityOptions {
     method public android.graphics.Rect getLaunchBounds();
+    method public int getLaunchDisplayId();
     method public static android.app.ActivityOptions makeBasic();
     method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -3911,6 +3912,7 @@
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public void requestUsageTimeReport(android.app.PendingIntent);
     method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
+    method public android.app.ActivityOptions setLaunchDisplayId(int);
     method public void setLaunchStackId(int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
@@ -7922,6 +7924,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8056,6 +8059,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -32278,6 +32282,7 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -63613,7 +63618,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -63622,7 +63630,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -63693,6 +63704,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 470a0fa..f003061 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -23,7 +23,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackInfo;
-import android.app.ActivityManagerNative;
 import android.app.IActivityContainer;
 import android.app.IActivityController;
 import android.app.IActivityManager;
@@ -108,7 +107,7 @@
     @Override
     public void onRun() throws Exception {
 
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         if (mAm == null) {
             System.err.println(NO_SYSTEM_ERROR_CODE);
             throw new AndroidException("Can't connect to activity manager; is the system running?");
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 132a4f8..63641a8 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -16,7 +16,7 @@
 
 package com.android.commands.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
 import android.content.ContentValues;
@@ -433,7 +433,7 @@
         public final void execute() {
             String providerName = mUri.getAuthority();
             try {
-                IActivityManager activityManager = ActivityManagerNative.getDefault();
+                IActivityManager activityManager = ActivityManager.getService();
                 IContentProvider provider = null;
                 IBinder token = new Binder();
                 try {
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 31c7421..3ac70d6 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -16,7 +16,7 @@
 
 package com.android.commands.dpm;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
@@ -117,7 +117,7 @@
                     mUserId = parseInt(arg);
                 }
                 if (mUserId == UserHandle.USER_CURRENT) {
-                    IActivityManager activityManager = ActivityManagerNative.getDefault();
+                    IActivityManager activityManager = ActivityManager.getService();
                     try {
                         mUserId = activityManager.getCurrentUser().id;
                     } catch (RemoteException e) {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 718f141..50f46f4 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -24,7 +24,6 @@
 
 import android.accounts.IAccountManager;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1191,7 +1190,7 @@
 
         ClearDataObserver obs = new ClearDataObserver();
         try {
-            ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId);
+            ActivityManager.getService().clearApplicationUserData(pkg, obs, userId);
             synchronized (obs) {
                 while (!obs.finished) {
                     try {
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index d527ad7..4291c77 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -20,7 +20,7 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.storage.DiskInfo;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.util.Log;
@@ -28,7 +28,7 @@
 public final class Sm {
     private static final String TAG = "Sm";
 
-    IMountService mSm;
+    IStorageManager mSm;
 
     private String[] mArgs;
     private int mNextArg;
@@ -55,7 +55,7 @@
             throw new IllegalArgumentException();
         }
 
-        mSm = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        mSm = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
         if (mSm == null) {
             throw new RemoteException("Failed to find running mount service");
         }
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index 8681166..32b4595 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -16,7 +16,7 @@
 
 package com.android.uiautomator.core;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
@@ -56,7 +56,7 @@
         try {
             IContentProvider provider = null;
             Cursor cursor = null;
-            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            IActivityManager activityManager = ActivityManager.getService();
             String providerName = Settings.Secure.CONTENT_URI.getAuthority();
             IBinder token = new Binder();
             try {
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
index ddeb8e7..d98b4ff 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -2,7 +2,6 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityController;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
@@ -44,7 +43,7 @@
      * @see {@link ActivityManager#isUserAMonkey()}
      */
     public void setRunAsMonkey(boolean isSet) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (am == null) {
             throw new RuntimeException("Can't manage monkey status; is the system running?");
         }
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 33e3e04..f09bad9 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -174,9 +174,6 @@
 android.app.ActivityManager$TaskThumbnailInfo$1
 android.app.ActivityManagerInternal
 android.app.ActivityManagerInternal$SleepToken
-android.app.ActivityManagerNative
-android.app.ActivityManagerNative$1
-android.app.ActivityManagerProxy
 android.app.ActivityOptions
 android.app.ActivityOptions$OnAnimationFinishedListener
 android.app.ActivityOptions$OnAnimationStartedListener
@@ -3226,17 +3223,17 @@
 android.os.health.SystemHealthManager
 android.os.storage.DiskInfo
 android.os.storage.DiskInfo$1
-android.os.storage.IMountService
-android.os.storage.IMountService$Stub
-android.os.storage.IMountService$Stub$Proxy
-android.os.storage.IMountServiceListener
-android.os.storage.IMountServiceListener$Stub
-android.os.storage.IMountServiceListener$Stub$Proxy
-android.os.storage.IMountShutdownObserver
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.IStorageEventListener
+android.os.storage.IStorageEventListener$Stub
+android.os.storage.IStorageEventListener$Stub$Proxy
+android.os.storage.IStorageShutdownObserver
 android.os.storage.IObbActionListener
 android.os.storage.IObbActionListener$Stub
-android.os.storage.MountServiceInternal
-android.os.storage.MountServiceInternal$ExternalStorageMountPolicy
+android.os.storage.StorageManagerInternal
+android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
 android.os.storage.StorageEventListener
 android.os.storage.StorageManager
 android.os.storage.StorageManager$ObbActionListener
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index aed7a36..8c71f50 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -18,7 +18,7 @@
 import com.google.android.collect.Sets;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -141,8 +141,8 @@
 
         try {
             IBinder activityToken = getActivityToken();
-            mCallingUid = ActivityManagerNative.getDefault().getLaunchedFromUid(activityToken);
-            mCallingPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+            mCallingUid = ActivityManager.getService().getLaunchedFromUid(activityToken);
+            mCallingPackage = ActivityManager.getService().getLaunchedFromPackage(
                     activityToken);
             if (mCallingUid != 0 && mCallingPackage != null) {
                 Bundle restrictions = UserManager.get(this)
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6f53f13..64e5dfc 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1313,7 +1313,7 @@
     public boolean isVoiceInteractionRoot() {
         try {
             return mVoiceInteractor != null
-                    && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken);
+                    && ActivityManager.getService().isRootVoiceInteraction(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1336,7 +1336,7 @@
      */
     public boolean isLocalVoiceInteractionSupported() {
         try {
-            return ActivityManagerNative.getDefault().supportsLocalVoiceInteraction();
+            return ActivityManager.getService().supportsLocalVoiceInteraction();
         } catch (RemoteException re) {
         }
         return false;
@@ -1350,7 +1350,7 @@
      */
     public void startLocalVoiceInteraction(Bundle privateOptions) {
         try {
-            ActivityManagerNative.getDefault().startLocalVoiceInteraction(mToken, privateOptions);
+            ActivityManager.getService().startLocalVoiceInteraction(mToken, privateOptions);
         } catch (RemoteException re) {
         }
     }
@@ -1379,7 +1379,7 @@
      */
     public void stopLocalVoiceInteraction() {
         try {
-            ActivityManagerNative.getDefault().stopLocalVoiceInteraction(mToken);
+            ActivityManager.getService().stopLocalVoiceInteraction(mToken);
         } catch (RemoteException re) {
         }
     }
@@ -1798,7 +1798,7 @@
      */
     public boolean showAssist(Bundle args) {
         try {
-            return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args);
+            return ActivityManager.getService().showAssistFromActivity(mToken, args);
         } catch (RemoteException e) {
         }
         return false;
@@ -1914,7 +1914,7 @@
         if (mDoReportFullyDrawn) {
             mDoReportFullyDrawn = false;
             try {
-                ActivityManagerNative.getDefault().reportActivityFullyDrawn(mToken);
+                ActivityManager.getService().reportActivityFullyDrawn(mToken);
             } catch (RemoteException e) {
             }
         }
@@ -1940,7 +1940,7 @@
      */
     public boolean isInMultiWindowMode() {
         try {
-            return ActivityManagerNative.getDefault().isInMultiWindowMode(mToken);
+            return ActivityManager.getService().isInMultiWindowMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1965,7 +1965,7 @@
      */
     public boolean isInPictureInPictureMode() {
         try {
-            return ActivityManagerNative.getDefault().isInPictureInPictureMode(mToken);
+            return ActivityManager.getService().isInPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1977,7 +1977,7 @@
      */
     public void enterPictureInPictureMode() {
         try {
-            ActivityManagerNative.getDefault().enterPictureInPictureMode(mToken);
+            ActivityManager.getService().enterPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -3037,7 +3037,7 @@
      */
     @Override
     public void exitFreeformMode() throws RemoteException {
-        ActivityManagerNative.getDefault().exitFreeformMode(mToken);
+        ActivityManager.getService().exitFreeformMode(mToken);
     }
 
     /** Returns the current stack Id for the window.
@@ -3045,7 +3045,7 @@
      */
     @Override
     public int getWindowStackId() throws RemoteException {
-        return ActivityManagerNative.getDefault().getActivityStackId(mToken);
+        return ActivityManager.getService().getActivityStackId(mToken);
     }
 
     /**
@@ -4533,7 +4533,7 @@
                 fillInIntent.prepareToLeaveProcess(this);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
                         fillInIntent, resolvedType, mToken, who,
                         requestCode, flagsMask, flagsValues, options);
@@ -4763,7 +4763,7 @@
                 }
                 intent.migrateExtraStreamToClipData();
                 intent.prepareToLeaveProcess(this);
-                result = ActivityManagerNative.getDefault()
+                result = ActivityManager.getService()
                     .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
                             intent, intent.resolveTypeIfNeeded(getContentResolver()), mToken,
                             mEmbeddedID, requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED,
@@ -4834,7 +4834,7 @@
             try {
                 intent.migrateExtraStreamToClipData();
                 intent.prepareToLeaveProcess(this);
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                     .startNextMatchingActivity(mToken, intent, options);
             } catch (RemoteException e) {
                 // Empty
@@ -5032,7 +5032,7 @@
      */
     public void overridePendingTransition(int enterAnim, int exitAnim) {
         try {
-            ActivityManagerNative.getDefault().overridePendingTransition(
+            ActivityManager.getService().overridePendingTransition(
                     mToken, getPackageName(), enterAnim, exitAnim);
         } catch (RemoteException e) {
         }
@@ -5157,7 +5157,7 @@
     @Nullable
     public String getCallingPackage() {
         try {
-            return ActivityManagerNative.getDefault().getCallingPackage(mToken);
+            return ActivityManager.getService().getCallingPackage(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5180,7 +5180,7 @@
     @Nullable
     public ComponentName getCallingActivity() {
         try {
-            return ActivityManagerNative.getDefault().getCallingActivity(mToken);
+            return ActivityManager.getService().getCallingActivity(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5265,7 +5265,7 @@
             throw new IllegalStateException("Must be called from main thread");
         }
         try {
-            ActivityManagerNative.getDefault().requestActivityRelaunch(mToken);
+            ActivityManager.getService().requestActivityRelaunch(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -5287,7 +5287,7 @@
                 if (resultData != null) {
                     resultData.prepareToLeaveProcess(this);
                 }
-                if (ActivityManagerNative.getDefault()
+                if (ActivityManager.getService()
                         .finishActivity(mToken, resultCode, resultData, finishTask)) {
                     mFinished = true;
                 }
@@ -5330,7 +5330,7 @@
             throw new IllegalStateException("Can not be called to deliver a result");
         }
         try {
-            if (ActivityManagerNative.getDefault().finishActivityAffinity(mToken)) {
+            if (ActivityManager.getService().finishActivityAffinity(mToken)) {
                 mFinished = true;
             }
         } catch (RemoteException e) {
@@ -5376,7 +5376,7 @@
     public void finishActivity(int requestCode) {
         if (mParent == null) {
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishSubActivity(mToken, mEmbeddedID, requestCode);
             } catch (RemoteException e) {
                 // Empty
@@ -5396,7 +5396,7 @@
      */
     public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
         try {
-            ActivityManagerNative.getDefault()
+            ActivityManager.getService()
                 .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
         } catch (RemoteException e) {
             // Empty
@@ -5424,7 +5424,7 @@
      */
     public boolean releaseInstance() {
         try {
-            return ActivityManagerNative.getDefault().releaseActivityInstance(mToken);
+            return ActivityManager.getService().releaseActivityInstance(mToken);
         } catch (RemoteException e) {
             // Empty
         }
@@ -5514,7 +5514,7 @@
         try {
             data.prepareToLeaveProcess(this);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                         ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
                         mParent == null ? mToken : mParent.mToken,
                         mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null,
@@ -5539,7 +5539,7 @@
     public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
             try {
-                ActivityManagerNative.getDefault().setRequestedOrientation(
+                ActivityManager.getService().setRequestedOrientation(
                         mToken, requestedOrientation);
             } catch (RemoteException e) {
                 // Empty
@@ -5562,7 +5562,7 @@
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                         .getRequestedOrientation(mToken);
             } catch (RemoteException e) {
                 // Empty
@@ -5581,7 +5581,7 @@
      */
     public int getTaskId() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getTaskForActivity(mToken, false);
         } catch (RemoteException e) {
             return -1;
@@ -5596,7 +5596,7 @@
      */
     public boolean isTaskRoot() {
         try {
-            return ActivityManagerNative.getDefault().getTaskForActivity(mToken, true) >= 0;
+            return ActivityManager.getService().getTaskForActivity(mToken, true) >= 0;
         } catch (RemoteException e) {
             return false;
         }
@@ -5615,7 +5615,7 @@
      */
     public boolean moveTaskToBack(boolean nonRoot) {
         try {
-            return ActivityManagerNative.getDefault().moveActivityTaskToBack(
+            return ActivityManager.getService().moveActivityTaskToBack(
                     mToken, nonRoot);
         } catch (RemoteException e) {
             // Empty
@@ -5786,7 +5786,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().setTaskDescription(mToken, mTaskDescription);
+            ActivityManager.getService().setTaskDescription(mToken, mTaskDescription);
         } catch (RemoteException e) {
         }
     }
@@ -6049,7 +6049,7 @@
      */
     public boolean isImmersive() {
         try {
-            return ActivityManagerNative.getDefault().isImmersive(mToken);
+            return ActivityManager.getService().isImmersive(mToken);
         } catch (RemoteException e) {
             return false;
         }
@@ -6067,7 +6067,7 @@
             return false;
         }
         try {
-            return ActivityManagerNative.getDefault().isTopOfTask(getActivityToken());
+            return ActivityManager.getService().isTopOfTask(getActivityToken());
         } catch (RemoteException e) {
             return false;
         }
@@ -6093,7 +6093,7 @@
     public void convertFromTranslucent() {
         try {
             mTranslucentCallback = null;
-            if (ActivityManagerNative.getDefault().convertFromTranslucent(mToken)) {
+            if (ActivityManager.getService().convertFromTranslucent(mToken)) {
                 WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
             }
         } catch (RemoteException e) {
@@ -6132,7 +6132,7 @@
         boolean drawComplete;
         try {
             mTranslucentCallback = callback;
-            mChangeCanvasToTranslucent = ActivityManagerNative.getDefault().convertToTranslucent(
+            mChangeCanvasToTranslucent = ActivityManager.getService().convertToTranslucent(
                     mToken, options == null ? null : options.toBundle());
             WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
             drawComplete = true;
@@ -6178,7 +6178,7 @@
     ActivityOptions getActivityOptions() {
         try {
             return ActivityOptions.fromBundle(
-                    ActivityManagerNative.getDefault().getActivityOptions(mToken));
+                    ActivityManager.getService().getActivityOptions(mToken));
         } catch (RemoteException e) {
         }
         return null;
@@ -6222,7 +6222,7 @@
             visible = false;
         }
         try {
-            mVisibleBehind = ActivityManagerNative.getDefault()
+            mVisibleBehind = ActivityManager.getService()
                     .requestVisibleBehind(mToken, visible) && visible;
         } catch (RemoteException e) {
             mVisibleBehind = false;
@@ -6263,7 +6263,7 @@
     @SystemApi
     public boolean isBackgroundVisibleBehind() {
         try {
-            return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken);
+            return ActivityManager.getService().isBackgroundVisibleBehind(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -6320,7 +6320,7 @@
      */
     public void setImmersive(boolean i) {
         try {
-            ActivityManagerNative.getDefault().setImmersive(mToken, i);
+            ActivityManager.getService().setImmersive(mToken, i);
         } catch (RemoteException e) {
             // pass
         }
@@ -6384,7 +6384,7 @@
     public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent)
           throws PackageManager.NameNotFoundException {
         try {
-            if (ActivityManagerNative.getDefault().setVrMode(mToken, enabled, requestedComponent)
+            if (ActivityManager.getService().setVrMode(mToken, enabled, requestedComponent)
                     != 0) {
                 throw new PackageManager.NameNotFoundException(
                         requestedComponent.flattenToString());
@@ -6505,7 +6505,7 @@
             if (info.taskAffinity == null) {
                 return false;
             }
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .shouldUpRecreateTask(mToken, info.taskAffinity);
         } catch (RemoteException e) {
             return false;
@@ -6558,7 +6558,7 @@
             }
             try {
                 upIntent.prepareToLeaveProcess(this);
-                return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent,
+                return ActivityManager.getService().navigateUpTo(mToken, upIntent,
                         resultCode, resultData);
             } catch (RemoteException e) {
                 return false;
@@ -7074,7 +7074,7 @@
      */
     public void startLockTask() {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeByToken(mToken);
+            ActivityManager.getService().startLockTaskModeByToken(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -7098,7 +7098,7 @@
      */
     public void stopLockTask() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            ActivityManager.getService().stopLockTaskMode();
         } catch (RemoteException e) {
         }
     }
@@ -7110,7 +7110,7 @@
      */
     public void showLockTaskEscapeMessage() {
         try {
-            ActivityManagerNative.getDefault().showLockTaskEscapeMessage(mToken);
+            ActivityManager.getService().showLockTaskEscapeMessage(mToken);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c55d3b8..65f74d1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -36,6 +36,7 @@
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
+import com.android.server.LocalServices;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -89,6 +90,8 @@
     private final Context mContext;
     private final Handler mHandler;
 
+    private static volatile boolean sSystemReady = false;
+
     static final class UidObserver extends IUidObserver.Stub {
         final OnUidImportanceListener mListener;
 
@@ -826,7 +829,7 @@
     /** @hide */
     public int getFrontActivityScreenCompatMode() {
         try {
-            return ActivityManagerNative.getDefault().getFrontActivityScreenCompatMode();
+            return getService().getFrontActivityScreenCompatMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -835,7 +838,7 @@
     /** @hide */
     public void setFrontActivityScreenCompatMode(int mode) {
         try {
-            ActivityManagerNative.getDefault().setFrontActivityScreenCompatMode(mode);
+            getService().setFrontActivityScreenCompatMode(mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -844,7 +847,7 @@
     /** @hide */
     public int getPackageScreenCompatMode(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getPackageScreenCompatMode(packageName);
+            return getService().getPackageScreenCompatMode(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -853,7 +856,7 @@
     /** @hide */
     public void setPackageScreenCompatMode(String packageName, int mode) {
         try {
-            ActivityManagerNative.getDefault().setPackageScreenCompatMode(packageName, mode);
+            getService().setPackageScreenCompatMode(packageName, mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -862,7 +865,7 @@
     /** @hide */
     public boolean getPackageAskScreenCompat(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getPackageAskScreenCompat(packageName);
+            return getService().getPackageAskScreenCompat(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -871,7 +874,7 @@
     /** @hide */
     public void setPackageAskScreenCompat(String packageName, boolean ask) {
         try {
-            ActivityManagerNative.getDefault().setPackageAskScreenCompat(packageName, ask);
+            getService().setPackageAskScreenCompat(packageName, ask);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1166,7 +1169,7 @@
         public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) {
             if (iconFilename != null) {
                 try {
-                    return ActivityManagerNative.getDefault().getTaskDescriptionIcon(iconFilename,
+                    return getService().getTaskDescriptionIcon(iconFilename,
                             userId);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -1555,7 +1558,7 @@
     public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
+            return getService().getRecentTasks(maxNum,
                     flags, UserHandle.myUserId()).getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1580,7 +1583,7 @@
     public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
+            return getService().getRecentTasks(maxNum,
                     flags, userId).getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1726,7 +1729,7 @@
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
         List<IBinder> appTasks;
         try {
-            appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
+            appTasks = getService().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1751,7 +1754,7 @@
     private void ensureAppTaskThumbnailSizeLocked() {
         if (mAppTaskThumbnailSize == null) {
             try {
-                mAppTaskThumbnailSize = ActivityManagerNative.getDefault().getAppTaskThumbnailSize();
+                mAppTaskThumbnailSize = getService().getAppTaskThumbnailSize();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1816,7 +1819,7 @@
             description = new TaskDescription();
         }
         try {
-            return ActivityManagerNative.getDefault().addAppTask(activity.getActivityToken(),
+            return getService().addAppTask(activity.getActivityToken(),
                     intent, description, thumbnail);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1859,7 +1862,7 @@
     public List<RunningTaskInfo> getRunningTasks(int maxNum)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTasks(maxNum, 0);
+            return getService().getTasks(maxNum, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1875,7 +1878,7 @@
      */
     public boolean removeTask(int taskId) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().removeTask(taskId);
+            return getService().removeTask(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2043,7 +2046,7 @@
     /** @hide */
     public TaskThumbnail getTaskThumbnail(int id) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTaskThumbnail(id);
+            return getService().getTaskThumbnail(id);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2052,7 +2055,7 @@
     /** @hide */
     public boolean isInHomeStack(int taskId) {
         try {
-            return ActivityManagerNative.getDefault().isInHomeStack(taskId);
+            return getService().isInHomeStack(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2101,7 +2104,7 @@
      */
     public void moveTaskToFront(int taskId, int flags, Bundle options) {
         try {
-            ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags, options);
+            getService().moveTaskToFront(taskId, flags, options);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2286,7 +2289,7 @@
     public List<RunningServiceInfo> getRunningServices(int maxNum)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault()
+            return getService()
                     .getServices(maxNum, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2301,7 +2304,7 @@
     public PendingIntent getRunningServiceControlPanel(ComponentName service)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault()
+            return getService()
                     .getRunningServiceControlPanel(service);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2406,7 +2409,7 @@
      */
     public void getMemoryInfo(MemoryInfo outInfo) {
         try {
-            ActivityManagerNative.getDefault().getMemoryInfo(outInfo);
+            getService().getMemoryInfo(outInfo);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2545,7 +2548,7 @@
      */
     public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
         try {
-            return ActivityManagerNative.getDefault().clearApplicationUserData(packageName,
+            return getService().clearApplicationUserData(packageName,
                     observer, UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2579,7 +2582,7 @@
      */
     public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getGrantedUriPermissions(packageName,
+            return getService().getGrantedUriPermissions(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2597,7 +2600,7 @@
      */
     public void clearGrantedUriPermissions(String packageName) {
         try {
-            ActivityManagerNative.getDefault().clearGrantedUriPermissions(packageName,
+            getService().clearGrantedUriPermissions(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2718,7 +2721,7 @@
      */
     public List<ProcessErrorStateInfo> getProcessesInErrorState() {
         try {
-            return ActivityManagerNative.getDefault().getProcessesInErrorState();
+            return getService().getProcessesInErrorState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3055,7 +3058,7 @@
      */
     public List<ApplicationInfo> getRunningExternalApplications() {
         try {
-            return ActivityManagerNative.getDefault().getRunningExternalApplications();
+            return getService().getRunningExternalApplications();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3071,7 +3074,7 @@
      */
     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
         try {
-            return ActivityManagerNative.getDefault().setProcessMemoryTrimLevel(process, userId,
+            return getService().setProcessMemoryTrimLevel(process, userId,
                     level);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3090,7 +3093,7 @@
      */
     public List<RunningAppProcessInfo> getRunningAppProcesses() {
         try {
-            return ActivityManagerNative.getDefault().getRunningAppProcesses();
+            return getService().getRunningAppProcesses();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3208,7 +3211,7 @@
      */
     static public void getMyMemoryState(RunningAppProcessInfo outState) {
         try {
-            ActivityManagerNative.getDefault().getMyMemoryState(outState);
+            getService().getMyMemoryState(outState);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3227,7 +3230,7 @@
      */
     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
         try {
-            return ActivityManagerNative.getDefault().getProcessMemoryInfo(pids);
+            return getService().getProcessMemoryInfo(pids);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3260,7 +3263,7 @@
      */
     public void killBackgroundProcesses(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killBackgroundProcesses(packageName,
+            getService().killBackgroundProcesses(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3278,7 +3281,7 @@
     @RequiresPermission(Manifest.permission.KILL_UID)
     public void killUid(int uid, String reason) {
         try {
-            ActivityManagerNative.getDefault().killUid(UserHandle.getAppId(uid),
+            getService().killUid(UserHandle.getAppId(uid),
                     UserHandle.getUserId(uid), reason);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3306,7 +3309,7 @@
      */
     public void forceStopPackageAsUser(String packageName, int userId) {
         try {
-            ActivityManagerNative.getDefault().forceStopPackage(packageName, userId);
+            getService().forceStopPackage(packageName, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3325,7 +3328,7 @@
      */
     public ConfigurationInfo getDeviceConfigurationInfo() {
         try {
-            return ActivityManagerNative.getDefault().getDeviceConfigurationInfo();
+            return getService().getDeviceConfigurationInfo();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3415,7 +3418,7 @@
      */
     public static boolean isUserAMonkey() {
         try {
-            return ActivityManagerNative.getDefault().isUserAMonkey();
+            return getService().isUserAMonkey();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3537,7 +3540,7 @@
             return userId;
         }
         try {
-            return ActivityManagerNative.getDefault().handleIncomingUser(callingPid,
+            return getService().handleIncomingUser(callingPid,
                     callingUid, userId, allowAll, requireFull, name, callerPackage);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3552,7 +3555,7 @@
     public static int getCurrentUser() {
         UserInfo ui;
         try {
-            ui = ActivityManagerNative.getDefault().getCurrentUser();
+            ui = getService().getCurrentUser();
             return ui != null ? ui.id : 0;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3565,7 +3568,7 @@
      */
     public boolean switchUser(int userid) {
         try {
-            return ActivityManagerNative.getDefault().switchUser(userid);
+            return getService().switchUser(userid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3580,8 +3583,8 @@
         int currentUser = ActivityManager.getCurrentUser();
         if (currentUser != UserHandle.USER_SYSTEM) {
             try {
-                ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM);
-                ActivityManagerNative.getDefault().stopUser(currentUser, /* force= */ false, null);
+                getService().switchUser(UserHandle.USER_SYSTEM);
+                getService().stopUser(currentUser, /* force= */ false, null);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
@@ -3608,7 +3611,7 @@
      */
     public boolean isUserRunning(int userId) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userId, 0);
+            return getService().isUserRunning(userId, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3617,7 +3620,7 @@
     /** {@hide} */
     public boolean isVrModePackageEnabled(ComponentName component) {
         try {
-            return ActivityManagerNative.getDefault().isVrModePackageEnabled(component);
+            return getService().isVrModePackageEnabled(component);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3662,6 +3665,23 @@
     /**
      * @hide
      */
+    public static boolean isSystemReady() {
+        if (!sSystemReady) {
+            if (ActivityThread.isSystem()) {
+                sSystemReady =
+                        LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
+            } else {
+                // Since this is being called from outside system server, system should be
+                // ready by now.
+                sSystemReady = true;
+            }
+        }
+        return sSystemReady;
+    }
+
+    /**
+     * @hide
+     */
     public static void broadcastStickyIntent(Intent intent, int userId) {
         broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId);
     }
@@ -3771,7 +3791,7 @@
      */
     public void setWatchHeapLimit(long pssSize) {
         try {
-            ActivityManagerNative.getDefault().setDumpHeapDebugLimit(null, 0, pssSize,
+            getService().setDumpHeapDebugLimit(null, 0, pssSize,
                     mContext.getPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3791,7 +3811,7 @@
      */
     public void clearWatchHeapLimit() {
         try {
-            ActivityManagerNative.getDefault().setDumpHeapDebugLimit(null, 0, 0, null);
+            getService().setDumpHeapDebugLimit(null, 0, 0, null);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3802,7 +3822,7 @@
      */
     public void startLockTaskMode(int taskId) {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeById(taskId);
+            getService().startLockTaskModeById(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3813,7 +3833,7 @@
      */
     public void stopLockTaskMode() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            getService().stopLockTaskMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3841,7 +3861,7 @@
      */
     public int getLockTaskModeState() {
         try {
-            return ActivityManagerNative.getDefault().getLockTaskModeState();
+            return getService().getLockTaskModeState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3859,7 +3879,7 @@
      */
     public static void setVrThread(int tid) {
         try {
-            ActivityManagerNative.getDefault().setVrThread(tid);
+            getService().setVrThread(tid);
         } catch (RemoteException e) {
             // pass
         }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index cabdd4b..c09403c 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -16,11 +16,7 @@
 
 package android.app;
 import android.content.Intent;
-import android.os.Debug;
 import android.os.IBinder;
-import android.util.Log;
-
-import com.android.server.LocalServices;
 
 /**
  * {@hide}
@@ -28,8 +24,6 @@
  */
 @Deprecated
 public abstract class ActivityManagerNative {
-    private final static String TAG = "ActivityManagerNative";
-
     /**
      * Cast a Binder object into an activity manager interface, generating
      * a proxy if needed.
@@ -55,21 +49,9 @@
      * @deprecated use ActivityManagerInternal.isSystemReady instead.
      */
     static public boolean isSystemReady() {
-        if (!sSystemReady) {
-            if (ActivityThread.isSystem()) {
-                sSystemReady =
-                        LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
-            } else {
-                // Since this is being called from outside system server, system should be
-                // ready by now.
-                sSystemReady = true;
-            }
-        }
-        return sSystemReady;
+        return ActivityManager.isSystemReady();
     }
 
-    static volatile boolean sSystemReady = false;
-
     /**
      * @deprecated use ActivityManager.broadcastStickyIntent instead.
      */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index d9a4690..1e7f4f0 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -152,6 +153,12 @@
     private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
 
     /**
+     * The display id the activity should be launched into.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";
+
+    /**
      * The stack id the activity should be launched into.
      * @hide
      */
@@ -240,6 +247,7 @@
     private int mResultCode;
     private int mExitCoordinatorIndex;
     private PendingIntent mUsageTimeReport;
+    private int mLaunchDisplayId = INVALID_DISPLAY;
     private int mLaunchStackId = INVALID_STACK_ID;
     private int mLaunchTaskId = -1;
     private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
@@ -850,6 +858,7 @@
                 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
                 break;
         }
+        mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
         mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
         mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
         mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
@@ -1015,6 +1024,25 @@
         }
     }
 
+    /**
+     * Gets the id of the display where activity should be launched.
+     * @return The id of the display where activity should be launched,
+     *         {@link android.view.Display#INVALID_DISPLAY} if not set.
+     */
+    public int getLaunchDisplayId() {
+        return mLaunchDisplayId;
+    }
+
+    /**
+     * Sets the id of the display where activity should be launched.
+     * @param launchDisplayId The id of the display where the activity should be launched.
+     * @return {@code this} {@link ActivityOptions} instance.
+     */
+    public ActivityOptions setLaunchDisplayId(int launchDisplayId) {
+        mLaunchDisplayId = launchDisplayId;
+        return this;
+    }
+
     /** @hide */
     public int getLaunchStackId() {
         return mLaunchStackId;
@@ -1209,6 +1237,7 @@
                 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
                 break;
         }
+        b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
         b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
         b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
         b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8dd4c9c..1aa13a9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1800,7 +1800,7 @@
             }
             if (a != null) {
                 mNewActivities = null;
-                IActivityManager am = ActivityManagerNative.getDefault();
+                IActivityManager am = ActivityManager.getService();
                 ActivityClientRecord prev;
                 do {
                     if (localLOGV) Slog.v(
@@ -2712,7 +2712,7 @@
     private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
         int displayId = Display.DEFAULT_DISPLAY;
         try {
-            displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
+            displayId = ActivityManager.getService().getActivityDisplayId(r.token);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2792,7 +2792,7 @@
         } else {
             // If there was an error, for any reason, tell the activity manager to stop us.
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                             Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
             } catch (RemoteException ex) {
@@ -2822,7 +2822,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
+            ActivityManager.getService().reportSizeConfigurations(r.token,
                     horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -2931,7 +2931,7 @@
             structure = new AssistStructure();
         }
         mLastAssistStructures.add(new WeakReference<>(structure));
-        IActivityManager mgr = ActivityManagerNative.getDefault();
+        IActivityManager mgr = ActivityManager.getService();
         try {
             mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
         } catch (RemoteException e) {
@@ -2970,7 +2970,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
+            ActivityManager.getService().backgroundResourcesReleased(token);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3069,7 +3069,7 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
 
-        IActivityManager mgr = ActivityManagerNative.getDefault();
+        IActivityManager mgr = ActivityManager.getService();
 
         BroadcastReceiver receiver;
         try {
@@ -3195,7 +3195,7 @@
 
             // tell the OS that we're live now
             try {
-                ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
+                ActivityManager.getService().backupAgentCreated(packageName, binder);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -3252,11 +3252,11 @@
 
             Application app = packageInfo.makeApplication(false, mInstrumentation);
             service.attach(context, this, data.info.name, data.token, app,
-                    ActivityManagerNative.getDefault());
+                    ActivityManager.getService());
             service.onCreate();
             mServices.put(data.token, service);
             try {
-                ActivityManagerNative.getDefault().serviceDoneExecuting(
+                ActivityManager.getService().serviceDoneExecuting(
                         data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -3281,11 +3281,11 @@
                 try {
                     if (!data.rebind) {
                         IBinder binder = s.onBind(data.intent);
-                        ActivityManagerNative.getDefault().publishService(
+                        ActivityManager.getService().publishService(
                                 data.token, data.intent, binder);
                     } else {
                         s.onRebind(data.intent);
-                        ActivityManagerNative.getDefault().serviceDoneExecuting(
+                        ActivityManager.getService().serviceDoneExecuting(
                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                     }
                     ensureJitEnabled();
@@ -3311,10 +3311,10 @@
                 boolean doRebind = s.onUnbind(data.intent);
                 try {
                     if (doRebind) {
-                        ActivityManagerNative.getDefault().unbindFinished(
+                        ActivityManager.getService().unbindFinished(
                                 data.token, data.intent, doRebind);
                     } else {
-                        ActivityManagerNative.getDefault().serviceDoneExecuting(
+                        ActivityManager.getService().serviceDoneExecuting(
                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                     }
                 } catch (RemoteException ex) {
@@ -3397,7 +3397,7 @@
                 QueuedWork.waitToFinish();
 
                 try {
-                    ActivityManagerNative.getDefault().serviceDoneExecuting(
+                    ActivityManager.getService().serviceDoneExecuting(
                             data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3428,7 +3428,7 @@
                 QueuedWork.waitToFinish();
 
                 try {
-                    ActivityManagerNative.getDefault().serviceDoneExecuting(
+                    ActivityManager.getService().serviceDoneExecuting(
                             token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3550,7 +3550,7 @@
             boolean willBeVisible = !a.mStartedActivity;
             if (!willBeVisible) {
                 try {
-                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
+                    willBeVisible = ActivityManager.getService().willActivityBeVisible(
                             a.getActivityToken());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3638,7 +3638,7 @@
             // Tell the activity manager we have resumed.
             if (reallyResume) {
                 try {
-                    ActivityManagerNative.getDefault().activityResumed(token);
+                    ActivityManager.getService().activityResumed(token);
                 } catch (RemoteException ex) {
                     throw ex.rethrowFromSystemServer();
                 }
@@ -3648,7 +3648,7 @@
             // If an exception was thrown when trying to resume, then
             // just end this activity.
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishActivity(token, Activity.RESULT_CANCELED, null,
                             Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
             } catch (RemoteException ex) {
@@ -3737,7 +3737,7 @@
             // Tell the activity manager we have paused.
             if (!dontReport) {
                 try {
-                    ActivityManagerNative.getDefault().activityPaused(token);
+                    ActivityManager.getService().activityPaused(token);
                 } catch (RemoteException ex) {
                     throw ex.rethrowFromSystemServer();
                 }
@@ -3835,7 +3835,7 @@
             // Tell activity manager we have been stopped.
             try {
                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
-                ActivityManagerNative.getDefault().activityStopped(
+                ActivityManager.getService().activityStopped(
                     activity.token, state, persistentState, description);
             } catch (RemoteException ex) {
                 if (ex instanceof TransactionTooLargeException
@@ -4090,7 +4090,7 @@
 
             // Tell activity manager we slept.
             try {
-                ActivityManagerNative.getDefault().activitySlept(r.token);
+                ActivityManager.getService().activitySlept(r.token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -4344,7 +4344,7 @@
         }
         if (finishing) {
             try {
-                ActivityManagerNative.getDefault().activityDestroyed(token);
+                ActivityManager.getService().activityDestroyed(token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -4386,7 +4386,7 @@
                     // For each relaunch request, activity manager expects an answer
                     if (!r.onlyLocalRequest && fromServer) {
                         try {
-                            ActivityManagerNative.getDefault().activityRelaunched(token);
+                            ActivityManager.getService().activityRelaunched(token);
                         } catch (RemoteException e) {
                             throw e.rethrowFromSystemServer();
                         }
@@ -4512,7 +4512,7 @@
         if (r == null) {
             if (!tmp.onlyLocalRequest) {
                 try {
-                    ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
+                    ActivityManager.getService().activityRelaunched(tmp.token);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
@@ -4585,7 +4585,7 @@
 
         if (!tmp.onlyLocalRequest) {
             try {
-                ActivityManagerNative.getDefault().activityRelaunched(r.token);
+                ActivityManager.getService().activityRelaunched(r.token);
                 if (r.window != null) {
                     r.window.reportActivityRelaunched();
                 }
@@ -4950,7 +4950,7 @@
             Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
         }
         try {
-            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
+            ActivityManager.getService().dumpHeapFinished(dhd.path);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -5242,7 +5242,14 @@
         }
         updateDefaultDensity();
 
-        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
+        final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
+        Boolean is24Hr = null;
+        if (use24HourSetting != null) {
+            is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
+        }
+        // null : use locale default for 12/24 hour formatting,
+        // false : use 12 hour format,
+        // true : use 24 hour format.
         DateFormat.set24HourTimePref(is24Hr);
 
         View.mDebugViewAttributes =
@@ -5294,7 +5301,7 @@
                 Slog.w(TAG, "Application " + data.info.getPackageName()
                       + " is waiting for the debugger on port 8100...");
 
-                IActivityManager mgr = ActivityManagerNative.getDefault();
+                IActivityManager mgr = ActivityManager.getService();
                 try {
                     mgr.showWaitingForDebugger(mAppThread, true);
                 } catch (RemoteException ex) {
@@ -5488,12 +5495,12 @@
     }
 
     /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (mProfiler.profileFile != null && mProfiler.handlingProfiling
                 && mProfiler.profileFd == null) {
             Debug.stopMethodTracing();
         }
-        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
+        //Slog.i(TAG, "am: " + ActivityManager.getService()
         //      + ", app thr: " + mAppThread);
         try {
             am.finishInstrumentation(mAppThread, resultCode, results);
@@ -5524,7 +5531,7 @@
         }
 
         try {
-            ActivityManagerNative.getDefault().publishContentProviders(
+            ActivityManager.getService().publishContentProviders(
                 getApplicationThread(), results);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -5546,7 +5553,7 @@
         // be re-entrant in the case where the provider is in the same process.
         ContentProviderHolder holder = null;
         try {
-            holder = ActivityManagerNative.getDefault().getContentProvider(
+            holder = ActivityManager.getService().getContentProvider(
                     getApplicationThread(), auth, userId, stable);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -5592,7 +5599,7 @@
                                 + prc.holder.info.name + ": unstableDelta="
                                 + unstableDelta);
                     }
-                    ActivityManagerNative.getDefault().refContentProvider(
+                    ActivityManager.getService().refContentProvider(
                             prc.holder.connection, 1, unstableDelta);
                 } catch (RemoteException e) {
                     //do nothing content provider object is dead any way
@@ -5621,7 +5628,7 @@
                             Slog.v(TAG, "incProviderRef: Now unstable - "
                                     + prc.holder.info.name);
                         }
-                        ActivityManagerNative.getDefault().refContentProvider(
+                        ActivityManager.getService().refContentProvider(
                                 prc.holder.connection, 0, 1);
                     } catch (RemoteException e) {
                         //do nothing content provider object is dead any way
@@ -5695,7 +5702,7 @@
                             Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
                                     + lastRef + " - " + prc.holder.info.name);
                         }
-                        ActivityManagerNative.getDefault().refContentProvider(
+                        ActivityManager.getService().refContentProvider(
                                 prc.holder.connection, -1, lastRef ? 1 : 0);
                     } catch (RemoteException e) {
                         //do nothing content provider object is dead any way
@@ -5719,7 +5726,7 @@
                                 Slog.v(TAG, "releaseProvider: No longer unstable - "
                                         + prc.holder.info.name);
                             }
-                            ActivityManagerNative.getDefault().refContentProvider(
+                            ActivityManager.getService().refContentProvider(
                                     prc.holder.connection, 0, -1);
                         } catch (RemoteException e) {
                             //do nothing content provider object is dead any way
@@ -5783,10 +5790,10 @@
 
         try {
             if (DEBUG_PROVIDER) {
-                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
+                Slog.v(TAG, "removeProvider: Invoking ActivityManagerService."
                         + "removeContentProvider(" + prc.holder.info.name + ")");
             }
-            ActivityManagerNative.getDefault().removeContentProvider(
+            ActivityManager.getService().removeContentProvider(
                     prc.holder.connection, false);
         } catch (RemoteException e) {
             //do nothing content provider object is dead any way
@@ -5820,7 +5827,7 @@
                 // it knows it is dead (so we don't race with its death
                 // notification).
                 try {
-                    ActivityManagerNative.getDefault().unstableProviderDied(
+                    ActivityManager.getService().unstableProviderDied(
                             prc.holder.connection);
                 } catch (RemoteException e) {
                     //do nothing content provider object is dead any way
@@ -5834,7 +5841,7 @@
             ProviderRefCount prc = mProviderRefCountMap.get(provider);
             if (prc != null) {
                 try {
-                    ActivityManagerNative.getDefault()
+                    ActivityManager.getService()
                             .appNotRespondingViaProvider(prc.holder.connection);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -5992,7 +5999,7 @@
                     if (!noReleaseNeeded) {
                         incProviderRefLocked(prc, stable);
                         try {
-                            ActivityManagerNative.getDefault().removeContentProvider(
+                            ActivityManager.getService().removeContentProvider(
                                     holder.connection, stable);
                         } catch (RemoteException e) {
                             //do nothing content provider object is dead any way
@@ -6029,7 +6036,7 @@
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                     UserHandle.myUserId());
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
-            final IActivityManager mgr = ActivityManagerNative.getDefault();
+            final IActivityManager mgr = ActivityManager.getService();
             try {
                 mgr.attachApplication(mAppThread);
             } catch (RemoteException ex) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index ec21882..af41db0 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -37,6 +37,8 @@
 import android.view.Window;
 import android.widget.ImageView;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -570,16 +572,9 @@
     protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) {
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver().addOnPreDrawListener(
-                    new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            notifySharedElementEnd(snapshots);
-                            return true;
-                        }
-                    }
-            );
+            OneShotPreDrawListener.add(decorView, () -> {
+                notifySharedElementEnd(snapshots);
+            });
         }
     }
 
@@ -816,6 +811,7 @@
                 if (moveWithParent && !isInTransitionGroup(parent, decor)) {
                     GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
                     parent.getViewTreeObserver().addOnPreDrawListener(listener);
+                    parent.addOnAttachStateChangeListener(listener);
                     mGhostViewListeners.add(listener);
                 }
             }
@@ -842,8 +838,7 @@
         int numListeners = mGhostViewListeners.size();
         for (int i = 0; i < numListeners; i++) {
             GhostViewListeners listener = mGhostViewListeners.get(i);
-            ViewGroup parent = (ViewGroup) listener.getView().getParent();
-            parent.getViewTreeObserver().removeOnPreDrawListener(listener);
+            listener.removeListener();
         }
         mGhostViewListeners.clear();
 
@@ -874,15 +869,9 @@
     protected void scheduleGhostVisibilityChange(final int visibility) {
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver()
-                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            setGhostVisibility(visibility);
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(decorView, () -> {
+                setGhostVisibility(visibility);
+            });
         }
     }
 
@@ -988,16 +977,19 @@
         }
     }
 
-    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener {
+    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener,
+            View.OnAttachStateChangeListener {
         private View mView;
         private ViewGroup mDecor;
         private View mParent;
         private Matrix mMatrix = new Matrix();
+        private ViewTreeObserver mViewTreeObserver;
 
         public GhostViewListeners(View view, View parent, ViewGroup decor) {
             mView = view;
             mParent = parent;
             mDecor = decor;
+            mViewTreeObserver = parent.getViewTreeObserver();
         }
 
         public View getView() {
@@ -1008,13 +1000,32 @@
         public boolean onPreDraw() {
             GhostView ghostView = GhostView.getGhost(mView);
             if (ghostView == null) {
-                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
+                removeListener();
             } else {
                 GhostView.calculateMatrix(mView, mDecor, mMatrix);
                 ghostView.setMatrix(mMatrix);
             }
             return true;
         }
+
+        public void removeListener() {
+            if (mViewTreeObserver.isAlive()) {
+                mViewTreeObserver.removeOnPreDrawListener(this);
+            } else {
+                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
+            }
+            mParent.removeOnAttachStateChangeListener(this);
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+            mViewTreeObserver = v.getViewTreeObserver();
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            removeListener();
+        }
     }
 
     static class SharedElementOriginalState {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 60046b5..f2616ff 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -22,9 +22,10 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.view.Window;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
@@ -321,18 +322,12 @@
                 }
                 if (delayExitBack && decor != null) {
                     final ViewGroup finalDecor = decor;
-                    decor.getViewTreeObserver().addOnPreDrawListener(
-                            new ViewTreeObserver.OnPreDrawListener() {
-                                @Override
-                                public boolean onPreDraw() {
-                                    finalDecor.getViewTreeObserver().removeOnPreDrawListener(this);
-                                    if (mReturnExitCoordinator != null) {
-                                        mReturnExitCoordinator.startExit(activity.mResultCode,
-                                                activity.mResultData);
-                                    }
-                                    return true;
-                                }
-                            });
+                    OneShotPreDrawListener.add(decor, () -> {
+                        if (mReturnExitCoordinator != null) {
+                            mReturnExitCoordinator.startExit(activity.mResultCode,
+                                    activity.mResultData);
+                        }
+                    });
                 } else {
                     mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData);
                 }
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index cada1b8..29b83dc 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -152,7 +152,7 @@
 
         try {
             mActivityContainer = new ActivityContainerWrapper(
-                    ActivityManagerNative.getDefault().createVirtualActivityContainer(
+                    ActivityManager.getService().createVirtualActivityContainer(
                             mActivity.getActivityToken(), new ActivityContainerCallback(this)));
         } catch (RemoteException e) {
             throw new RuntimeException("ActivityView: Unable to create ActivityContainer. "
diff --git a/core/java/android/app/AppImportanceMonitor.java b/core/java/android/app/AppImportanceMonitor.java
index e0d0d8d..b5cbeeb 100644
--- a/core/java/android/app/AppImportanceMonitor.java
+++ b/core/java/android/app/AppImportanceMonitor.java
@@ -86,7 +86,7 @@
         };
         ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
         try {
-            ActivityManagerNative.getDefault().registerProcessObserver(mProcessObserver);
+            ActivityManager.getService().registerProcessObserver(mProcessObserver);
         } catch (RemoteException e) {
         }
         List<ActivityManager.RunningAppProcessInfo> apps = am.getRunningAppProcesses();
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 6b16e8f..e222fee 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -764,7 +764,7 @@
         }
         if (!mAllowOptimization) {
             // Added fragments are added at the end to comply with prior behavior.
-            mManager.moveToState(mManager.mCurState);
+            mManager.moveToState(mManager.mCurState, true);
         }
     }
 
@@ -810,7 +810,7 @@
             }
         }
         if (!mAllowOptimization) {
-            mManager.moveToState(mManager.mCurState);
+            mManager.moveToState(mManager.mCurState, true);
         }
     }
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c5180fd..827e026 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -61,7 +61,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -798,7 +798,7 @@
     @Override
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         try {
-            ActivityManagerNative.getDefault().startActivityAsUser(
+            ActivityManager.getService().startActivityAsUser(
                 mMainThread.getApplicationThread(), getBasePackageName(), intent,
                 intent.resolveTypeIfNeeded(getContentResolver()),
                 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
@@ -860,7 +860,7 @@
                 fillInIntent.prepareToLeaveProcess(this);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
                         fillInIntent, resolvedType, null, null,
                         0, flagsMask, flagsValues, options);
@@ -879,7 +879,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                     getUserId());
@@ -896,7 +896,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, false, false, getUserId());
@@ -911,7 +911,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, false, false, getUserId());
@@ -928,7 +928,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     options, false, false, getUserId());
@@ -945,7 +945,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
                     getUserId());
@@ -962,7 +962,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, true, false, getUserId());
@@ -1025,7 +1025,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermissions, appOp,
                     options, true, false, getUserId());
@@ -1039,7 +1039,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
+            ActivityManager.getService().broadcastIntent(mMainThread.getApplicationThread(),
                     intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
                     AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
         } catch (RemoteException e) {
@@ -1061,7 +1061,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     options, false, false, user.getIdentifier());
@@ -1078,7 +1078,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
                     user.getIdentifier());
@@ -1129,7 +1129,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermissions,
                     appOp, options, true, false, user.getIdentifier());
@@ -1145,7 +1145,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
                 getUserId());
@@ -1181,7 +1181,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
                     AppOpsManager.OP_NONE, null, true, true, getUserId());
@@ -1200,7 +1200,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1213,7 +1213,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
                     user.getIdentifier());
@@ -1228,7 +1228,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, options, false, true,
                 user.getIdentifier());
@@ -1263,7 +1263,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
                     AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
@@ -1282,7 +1282,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1329,7 +1329,7 @@
             }
         }
         try {
-            final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
+            final Intent intent = ActivityManager.getService().registerReceiver(
                     mMainThread.getApplicationThread(), mBasePackageName,
                     rd, filter, broadcastPermission, userId);
             if (intent != null) {
@@ -1348,7 +1348,7 @@
             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
                     getOuterContext(), receiver);
             try {
-                ActivityManagerNative.getDefault().unregisterReceiver(rd);
+                ActivityManager.getService().unregisterReceiver(rd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1391,7 +1391,7 @@
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
-            ComponentName cn = ActivityManagerNative.getDefault().startService(
+            ComponentName cn = ActivityManager.getService().startService(
                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                             getContentResolver()), getOpPackageName(), user.getIdentifier());
             if (cn != null) {
@@ -1420,7 +1420,7 @@
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
-            int res = ActivityManagerNative.getDefault().stopService(
+            int res = ActivityManager.getService().stopService(
                 mMainThread.getApplicationThread(), service,
                 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
             if (res < 0) {
@@ -1492,7 +1492,7 @@
                 flags |= BIND_WAIVE_PRIORITY;
             }
             service.prepareToLeaveProcess(this);
-            int res = ActivityManagerNative.getDefault().bindService(
+            int res = ActivityManager.getService().bindService(
                 mMainThread.getApplicationThread(), getActivityToken(), service,
                 service.resolveTypeIfNeeded(getContentResolver()),
                 sd, flags, getOpPackageName(), user.getIdentifier());
@@ -1515,7 +1515,7 @@
             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                     getOuterContext(), conn);
             try {
-                ActivityManagerNative.getDefault().unbindService(sd);
+                ActivityManager.getService().unbindService(sd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1531,7 +1531,7 @@
             if (arguments != null) {
                 arguments.setAllowFds(false);
             }
-            return ActivityManagerNative.getDefault().startInstrumentation(
+            return ActivityManager.getService().startInstrumentation(
                     className, profileFile, 0, arguments, null, null, getUserId(),
                     null /* ABI override */);
         } catch (RemoteException e) {
@@ -1556,7 +1556,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermission(
+            return ActivityManager.getService().checkPermission(
                     permission, pid, uid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1571,7 +1571,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermissionWithToken(
+            return ActivityManager.getService().checkPermissionWithToken(
                     permission, pid, uid, callerToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1656,7 +1656,7 @@
     @Override
     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
          try {
-            ActivityManagerNative.getDefault().grantUriPermission(
+            ActivityManager.getService().grantUriPermission(
                     mMainThread.getApplicationThread(), toPackage,
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
@@ -1667,7 +1667,7 @@
     @Override
     public void revokeUriPermission(Uri uri, int modeFlags) {
          try {
-            ActivityManagerNative.getDefault().revokeUriPermission(
+            ActivityManager.getService().revokeUriPermission(
                     mMainThread.getApplicationThread(),
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
@@ -1678,7 +1678,7 @@
     @Override
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
         try {
-            return ActivityManagerNative.getDefault().checkUriPermission(
+            return ActivityManager.getService().checkUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
                     resolveUserId(uri), null);
         } catch (RemoteException e) {
@@ -1690,7 +1690,7 @@
     @Override
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
         try {
-            return ActivityManagerNative.getDefault().checkUriPermission(
+            return ActivityManager.getService().checkUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
                     resolveUserId(uri), callerToken);
         } catch (RemoteException e) {
@@ -2213,10 +2213,11 @@
                     if (!dir.exists()) {
                         // Failing to mkdir() may be okay, since we might not have
                         // enough permissions; ask vold to create on our behalf.
-                        final IMountService mount = IMountService.Stub.asInterface(
+                        final IStorageManager storageManager = IStorageManager.Stub.asInterface(
                                 ServiceManager.getService("mount"));
                         try {
-                            final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
+                            final int res = storageManager.mkdirs(
+                                    getPackageName(), dir.getAbsolutePath());
                             if (res != 0) {
                                 Log.w(TAG, "Failed to ensure " + dir + ": " + res);
                                 dir = null;
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 27a0200..3464c4d 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -30,10 +30,11 @@
 import android.view.ViewGroup;
 import android.view.ViewGroupOverlay;
 import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 
 /**
@@ -58,7 +59,7 @@
     private boolean mAreViewsReady;
     private boolean mIsViewsTransitionStarted;
     private Transition mEnterViewsTransition;
-    private OnPreDrawListener mViewsReadyListener;
+    private OneShotPreDrawListener mViewsReadyListener;
     private final boolean mIsCrossTask;
 
     public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
@@ -74,12 +75,17 @@
         mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver().addOnPreDrawListener(
+            final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
+            viewTreeObserver.addOnPreDrawListener(
                     new ViewTreeObserver.OnPreDrawListener() {
                         @Override
                         public boolean onPreDraw() {
                             if (mIsReadyForTransition) {
-                                decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                                if (viewTreeObserver.isAlive()) {
+                                    viewTreeObserver.removeOnPreDrawListener(this);
+                                } else {
+                                    decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                                }
                             }
                             return mIsReadyForTransition;
                         }
@@ -147,16 +153,10 @@
                 (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()))) {
             viewsReady(sharedElements);
         } else {
-            mViewsReadyListener = new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    mViewsReadyListener = null;
-                    decor.getViewTreeObserver().removeOnPreDrawListener(this);
-                    viewsReady(sharedElements);
-                    return true;
-                }
-            };
-            decor.getViewTreeObserver().addOnPreDrawListener(mViewsReadyListener);
+            mViewsReadyListener = OneShotPreDrawListener.add(decor, () -> {
+                mViewsReadyListener = null;
+                viewsReady(sharedElements);
+            });
             decor.invalidate();
         }
     }
@@ -206,19 +206,13 @@
             moveSharedElementsToOverlay();
             mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
         } else if (decorView != null) {
-            decorView.getViewTreeObserver()
-                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            if (mResultReceiver != null) {
-                                Bundle state = captureSharedElementState();
-                                moveSharedElementsToOverlay();
-                                mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
-                            }
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(decorView, () -> {
+                if (mResultReceiver != null) {
+                    Bundle state = captureSharedElementState();
+                    moveSharedElementsToOverlay();
+                    mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
+                }
+            });
         }
         if (allowOverlappingTransitions()) {
             startEnterTransitionOnly();
@@ -271,7 +265,7 @@
             mIsReadyForTransition = true;
             final ViewGroup decor = getDecor();
             if (decor != null && mViewsReadyListener != null) {
-                decor.getViewTreeObserver().removeOnPreDrawListener(mViewsReadyListener);
+                mViewsReadyListener.removeListener();
                 mViewsReadyListener = null;
             }
             showViews(mTransitioningViews, true);
@@ -457,20 +451,11 @@
             public void onSharedElementsReady() {
                 final View decorView = getDecor();
                 if (decorView != null) {
-                    decorView.getViewTreeObserver()
-                            .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                                @Override
-                                public boolean onPreDraw() {
-                                    decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                                    startTransition(new Runnable() {
-                                        @Override
-                                        public void run() {
-                                            startSharedElementTransition(sharedElementState);
-                                        }
-                                    });
-                                    return false;
-                                }
-                            });
+                    OneShotPreDrawListener.add(decorView, () -> {
+                        startTransition(() -> {
+                                startSharedElementTransition(sharedElementState);
+                        });
+                    });
                     decorView.invalidate();
                 }
             }
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index b5b6e4a..6a79e6c 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -34,9 +34,10 @@
 import android.transition.TransitionManager;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.view.Window;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 
 /**
@@ -168,15 +169,9 @@
         });
         final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
                 mSharedElementNames);
-        decorView.getViewTreeObserver()
-                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
-                        return true;
-                    }
-                });
+        OneShotPreDrawListener.add(decorView, () -> {
+            setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
+        });
         setGhostVisibility(View.INVISIBLE);
         scheduleGhostVisibilityChange(View.INVISIBLE);
         if (mListener != null) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 8124232..10ab2bc 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -414,6 +414,10 @@
     // True if this fragment has been restored from previously saved state.
     boolean mRestored;
 
+    // True if performCreateView has been called and a matching call to performDestroyView
+    // has not yet happened.
+    boolean mPerformedCreateView;
+
     // Number of active back stack entries this fragment is in.
     int mBackStackNesting;
 
@@ -611,7 +615,7 @@
             Fragment f = (Fragment)clazz.newInstance();
             if (args != null) {
                 args.setClassLoader(f.getClass().getClassLoader());
-                f.mArguments = args;
+                f.setArguments(args);
             }
             return f;
         } catch (ClassNotFoundException e) {
@@ -2464,6 +2468,7 @@
         if (mChildFragmentManager != null) {
             mChildFragmentManager.noteStateNotSaved();
         }
+        mPerformedCreateView = true;
         return onCreateView(inflater, container, savedInstanceState);
     }
 
@@ -2690,6 +2695,7 @@
         if (mLoaderManager != null) {
             mLoaderManager.doReportNextStart();
         }
+        mPerformedCreateView = false;
     }
 
     void performDestroy() {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 5a2c5e7..c7d6a48 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1072,7 +1072,7 @@
         if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
             newState = Fragment.STOPPED;
         }
-        if (f.mState < newState) {
+        if (f.mState <= newState) {
             // For fragments that are created from a layout, when restoring from
             // state we don't want to allow them to be created until they are
             // being reloaded from the layout.
@@ -1089,65 +1089,59 @@
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
-                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
-                    if (f.mSavedFragmentState != null) {
-                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
-                                FragmentManagerImpl.VIEW_STATE_TAG);
-                        f.mTarget = getFragment(f.mSavedFragmentState,
-                                FragmentManagerImpl.TARGET_STATE_TAG);
-                        if (f.mTarget != null) {
-                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
-                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
-                        }
-                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
-                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
-                        if (!f.mUserVisibleHint) {
-                            f.mDeferStart = true;
-                            if (newState > Fragment.STOPPED) {
-                                newState = Fragment.STOPPED;
+                    if (newState > Fragment.INITIALIZING) {
+                        if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
+                        if (f.mSavedFragmentState != null) {
+                            f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
+                                    FragmentManagerImpl.VIEW_STATE_TAG);
+                            f.mTarget = getFragment(f.mSavedFragmentState,
+                                    FragmentManagerImpl.TARGET_STATE_TAG);
+                            if (f.mTarget != null) {
+                                f.mTargetRequestCode = f.mSavedFragmentState.getInt(
+                                        FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
+                            }
+                            f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
+                                    FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
+                            if (!f.mUserVisibleHint) {
+                                f.mDeferStart = true;
+                                if (newState > Fragment.STOPPED) {
+                                    newState = Fragment.STOPPED;
+                                }
                             }
                         }
-                    }
-                    f.mHost = mHost;
-                    f.mParentFragment = mParent;
-                    f.mFragmentManager = mParent != null
-                            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
-                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
-                    f.mCalled = false;
-                    f.onAttach(mHost.getContext());
-                    if (!f.mCalled) {
-                        throw new SuperNotCalledException("Fragment " + f
-                                + " did not call through to super.onAttach()");
-                    }
-                    if (f.mParentFragment == null) {
-                        mHost.onAttachFragment(f);
-                    } else {
-                        f.mParentFragment.onAttachFragment(f);
-                    }
-                    dispatchOnFragmentAttached(f, mHost.getContext(), false);
-
-                    if (!f.mRetaining) {
-                        f.performCreate(f.mSavedFragmentState);
-                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
-                    } else {
-                        f.restoreChildFragmentState(f.mSavedFragmentState, true);
-                        f.mState = Fragment.CREATED;
-                    }
-                    f.mRetaining = false;
-                    if (f.mFromLayout) {
-                        // For fragments that are part of the content view
-                        // layout, we need to instantiate the view immediately
-                        // and the inflater will take care of adding it.
-                        f.mView = f.performCreateView(f.getLayoutInflater(
-                                f.mSavedFragmentState), null, f.mSavedFragmentState);
-                        if (f.mView != null) {
-                            f.mView.setSaveFromParentEnabled(false);
-                            if (f.mHidden) f.mView.setVisibility(View.GONE);
-                            f.onViewCreated(f.mView, f.mSavedFragmentState);
-                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
+                        f.mHost = mHost;
+                        f.mParentFragment = mParent;
+                        f.mFragmentManager = mParent != null
+                                ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
+                        dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
+                        f.mCalled = false;
+                        f.onAttach(mHost.getContext());
+                        if (!f.mCalled) {
+                            throw new SuperNotCalledException("Fragment " + f
+                                    + " did not call through to super.onAttach()");
                         }
+                        if (f.mParentFragment == null) {
+                            mHost.onAttachFragment(f);
+                        } else {
+                            f.mParentFragment.onAttachFragment(f);
+                        }
+                        dispatchOnFragmentAttached(f, mHost.getContext(), false);
+
+                        if (!f.mRetaining) {
+                            f.performCreate(f.mSavedFragmentState);
+                            dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
+                        } else {
+                            f.restoreChildFragmentState(f.mSavedFragmentState, true);
+                            f.mState = Fragment.CREATED;
+                        }
+                        f.mRetaining = false;
                     }
                 case Fragment.CREATED:
+                    // This is outside the if statement below on purpose; we want this to run
+                    // even if we do a moveToState from CREATED => *, CREATED => CREATED, and
+                    // * => CREATED as part of the case fallthrough above.
+                    ensureInflatedFragmentView(f);
+
                     if (newState > Fragment.CREATED) {
                         if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                         if (!f.mFromLayout) {
@@ -1281,6 +1275,7 @@
                         }
                         f.mContainer = null;
                         f.mView = null;
+                        f.mInLayout = false;
                     }
                 case Fragment.CREATED:
                     if (newState < Fragment.CREATED) {
@@ -1340,6 +1335,19 @@
         moveToState(f, mCurState, 0, 0, false);
     }
 
+    void ensureInflatedFragmentView(Fragment f) {
+        if (f.mFromLayout && !f.mPerformedCreateView) {
+            f.mView = f.performCreateView(f.getLayoutInflater(
+                    f.mSavedFragmentState), null, f.mSavedFragmentState);
+            if (f.mView != null) {
+                f.mView.setSaveFromParentEnabled(false);
+                if (f.mHidden) f.mView.setVisibility(View.GONE);
+                f.onViewCreated(f.mView, f.mSavedFragmentState);
+                dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
+            }
+        }
+    }
+
     /**
      * Fragments that have been shown or hidden don't have their visibility changed or
      * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)}
@@ -1445,11 +1453,24 @@
         }
     }
 
-    void moveToState(int newState) {
+    /**
+     * Changes the state of the fragment manager to {@code newState}. If the fragment manager
+     * changes state or {@code always} is {@code true}, any fragments within it have their
+     * states updated as well.
+     *
+     * @param newState The new state for the fragment manager
+     * @param always If {@code true}, all fragments update their state, even
+     *               if {@code newState} matches the current fragment manager's state.
+     */
+    void moveToState(int newState, boolean always) {
         if (mHost == null && newState != Fragment.INITIALIZING) {
             throw new IllegalStateException("No activity");
         }
 
+        if (!always && mCurState == newState) {
+            return;
+        }
+
         mCurState = newState;
 
         if (mActive != null) {
@@ -2024,7 +2045,7 @@
             // need to run something now
             FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                     postponeIndex, true);
-            moveToState(mCurState);
+            moveToState(mCurState, true);
         }
 
         for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
@@ -2117,7 +2138,7 @@
             FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true);
         }
         if (moveToState) {
-            moveToState(mCurState);
+            moveToState(mCurState, true);
         } else if (mActive != null) {
             final int numActive = mActive.size();
             for (int i = 0; i < numActive; i++) {
@@ -2691,40 +2712,40 @@
     
     public void dispatchCreate() {
         mStateSaved = false;
-        moveToState(Fragment.CREATED);
+        moveToState(Fragment.CREATED, false);
     }
     
     public void dispatchActivityCreated() {
         mStateSaved = false;
-        moveToState(Fragment.ACTIVITY_CREATED);
+        moveToState(Fragment.ACTIVITY_CREATED, false);
     }
     
     public void dispatchStart() {
         mStateSaved = false;
-        moveToState(Fragment.STARTED);
+        moveToState(Fragment.STARTED, false);
     }
     
     public void dispatchResume() {
         mStateSaved = false;
-        moveToState(Fragment.RESUMED);
+        moveToState(Fragment.RESUMED, false);
     }
     
     public void dispatchPause() {
-        moveToState(Fragment.STARTED);
+        moveToState(Fragment.STARTED, false);
     }
     
     public void dispatchStop() {
-        moveToState(Fragment.STOPPED);
+        moveToState(Fragment.STOPPED, false);
     }
     
     public void dispatchDestroyView() {
-        moveToState(Fragment.CREATED);
+        moveToState(Fragment.CREATED, false);
     }
 
     public void dispatchDestroy() {
         mDestroyed = true;
         execPendingActions();
-        moveToState(Fragment.INITIALIZING);
+        moveToState(Fragment.INITIALIZING, false);
         mHost = null;
         mContainer = null;
         mParent = null;
@@ -3249,7 +3270,9 @@
         }
 
         // If we haven't finished entering the CREATED state ourselves yet,
-        // push the inflated child fragment along.
+        // push the inflated child fragment along. This will ensureInflatedFragmentView
+        // at the right phase of the lifecycle so that we will have mView populated
+        // for compliant fragments below.
         if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
             moveToState(fragment, Fragment.CREATED, 0, 0, false);
         } else {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index d27dff5..088fd08 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -24,7 +24,8 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
+
+import com.android.internal.view.OneShotPreDrawListener;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -320,16 +321,9 @@
                 && exitingFragment.mHidden && exitingFragment.mHiddenChanged) {
             exitingFragment.setHideReplaced(true);
             final View fragmentView = exitingFragment.getView();
-            final ViewGroup container = exitingFragment.mContainer;
-            container.getViewTreeObserver().addOnPreDrawListener(
-                    new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            container.getViewTreeObserver().removeOnPreDrawListener(this);
-                            setViewVisibility(exitingViews, View.INVISIBLE);
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(exitingFragment.mContainer, () -> {
+                setViewVisibility(exitingViews, View.INVISIBLE);
+            });
             exitTransition.addListener(new Transition.TransitionListenerAdapter() {
                 @Override
                 public void onTransitionEnd(Transition transition) {
@@ -364,30 +358,22 @@
             final Transition enterTransition, final ArrayList<View> enteringViews,
             final Transition exitTransition, final ArrayList<View> exitingViews) {
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            if (enterTransition != null) {
+                enterTransition.removeTarget(nonExistentView);
+                ArrayList<View> views = configureEnteringExitingViews(
+                        enterTransition, inFragment, sharedElementsIn, nonExistentView);
+                enteringViews.addAll(views);
+            }
 
-                        if (enterTransition != null) {
-                            enterTransition.removeTarget(nonExistentView);
-                            ArrayList<View> views = configureEnteringExitingViews(
-                                    enterTransition, inFragment, sharedElementsIn, nonExistentView);
-                            enteringViews.addAll(views);
-                        }
-
-                        if (exitingViews != null) {
-                            ArrayList<View> tempExiting = new ArrayList<>();
-                            tempExiting.add(nonExistentView);
-                            replaceTargets(exitTransition, exitingViews, tempExiting);
-                            exitingViews.clear();
-                            exitingViews.add(nonExistentView);
-                        }
-
-                        return true;
-                    }
-                });
+            if (exitingViews != null) {
+                ArrayList<View> tempExiting = new ArrayList<>();
+                tempExiting.add(nonExistentView);
+                replaceTargets(exitTransition, exitingViews, tempExiting);
+                exitingViews.clear();
+                exitingViews.add(nonExistentView);
+            }
+        });
     }
 
     /**
@@ -541,19 +527,13 @@
             epicenterView = null;
         }
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
-                                inSharedElements, false);
-                        if (epicenterView != null) {
-                            epicenterView.getBoundsOnScreen(epicenter);
-                        }
-                        return true;
-                    }
-                });
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                    inSharedElements, false);
+            if (epicenterView != null) {
+                epicenterView.getBoundsOnScreen(epicenter);
+            }
+        });
         return sharedElementTransition;
     }
 
@@ -643,36 +623,30 @@
 
         TransitionSet finalSharedElementTransition = sharedElementTransition;
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-                        ArrayMap<String, View> inSharedElements = captureInSharedElements(
-                                nameOverrides, finalSharedElementTransition, fragments);
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            ArrayMap<String, View> inSharedElements = captureInSharedElements(
+                    nameOverrides, finalSharedElementTransition, fragments);
 
-                        if (inSharedElements != null) {
-                            sharedElementsIn.addAll(inSharedElements.values());
-                            sharedElementsIn.add(nonExistentView);
-                        }
+            if (inSharedElements != null) {
+                sharedElementsIn.addAll(inSharedElements.values());
+                sharedElementsIn.add(nonExistentView);
+            }
 
-                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
-                                inSharedElements, false);
-                        if (finalSharedElementTransition != null) {
-                            finalSharedElementTransition.getTargets().clear();
-                            finalSharedElementTransition.getTargets().addAll(sharedElementsIn);
-                            replaceTargets(finalSharedElementTransition, sharedElementsOut,
-                                    sharedElementsIn);
+            callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                    inSharedElements, false);
+            if (finalSharedElementTransition != null) {
+                finalSharedElementTransition.getTargets().clear();
+                finalSharedElementTransition.getTargets().addAll(sharedElementsIn);
+                replaceTargets(finalSharedElementTransition, sharedElementsOut,
+                        sharedElementsIn);
 
-                            final View inEpicenterView = getInEpicenterView(inSharedElements,
-                                    fragments, enterTransition, inIsPop);
-                            if (inEpicenterView != null) {
-                                inEpicenterView.getBoundsOnScreen(inEpicenter);
-                            }
-                        }
-                        return true;
-                    }
-                });
+                final View inEpicenterView = getInEpicenterView(inSharedElements,
+                        fragments, enterTransition, inIsPop);
+                if (inEpicenterView != null) {
+                    inEpicenterView.getBoundsOnScreen(inEpicenter);
+                }
+            }
+        });
         return sharedElementTransition;
     }
 
diff --git a/core/java/android/app/IInstrumentationWatcher.aidl b/core/java/android/app/IInstrumentationWatcher.aidl
index 6c8c4d6..405a3d8 100644
--- a/core/java/android/app/IInstrumentationWatcher.aidl
+++ b/core/java/android/app/IInstrumentationWatcher.aidl
@@ -21,7 +21,7 @@
 import android.os.Bundle;
 
 /** @hide */
-interface IInstrumentationWatcher
+oneway interface IInstrumentationWatcher
 {
     void instrumentationStatus(in ComponentName name, int resultCode,
             in Bundle results);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index f934a9f..cc7981c 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1505,7 +1505,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
@@ -1565,7 +1565,7 @@
                 intents[i].prepareToLeaveProcess(who);
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
                         token, options, userId);
             checkStartActivityResult(result, intents[0]);
@@ -1624,7 +1624,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target, requestCode, 0, null, options);
@@ -1684,7 +1684,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
@@ -1723,7 +1723,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 7754244..a38377e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -452,7 +452,7 @@
 
         if (mRegisterPackage) {
             try {
-                ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
+                ActivityManager.getService().addPackageDependency(mPackageName);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -891,7 +891,7 @@
                         StrictMode.onIntentReceiverLeaked(leak);
                     }
                     try {
-                        ActivityManagerNative.getDefault().unregisterReceiver(
+                        ActivityManager.getService().unregisterReceiver(
                                 rd.getIIntentReceiver());
                     } catch (RemoteException e) {
                         throw e.rethrowFromSystemServer();
@@ -917,7 +917,7 @@
                         StrictMode.onServiceConnectionLeaked(leak);
                     }
                     try {
-                        ActivityManagerNative.getDefault().unbindService(
+                        ActivityManager.getService().unbindService(
                                 sd.getIServiceConnection());
                     } catch (RemoteException e) {
                         throw e.rethrowFromSystemServer();
@@ -1046,7 +1046,7 @@
                     // behalf so that the system's broadcast sequence can continue.
                     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                             "Finishing broadcast to unregistered receiver");
-                    IActivityManager mgr = ActivityManagerNative.getDefault();
+                    IActivityManager mgr = ActivityManager.getService();
                     try {
                         if (extras != null) {
                             extras.setAllowFds(false);
@@ -1095,7 +1095,7 @@
                             + " mOrderedHint=" + ordered);
                 }
                 
-                final IActivityManager mgr = ActivityManagerNative.getDefault();
+                final IActivityManager mgr = ActivityManager.getService();
                 final Intent intent = mCurIntent;
                 if (intent == null) {
                     Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched);
@@ -1209,7 +1209,7 @@
             }
             if (intent == null || !mActivityThread.post(args)) {
                 if (mRegistered && ordered) {
-                    IActivityManager mgr = ActivityManagerNative.getDefault();
+                    IActivityManager mgr = ActivityManager.getService();
                     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                             "Finishing sync broadcast to " + mReceiver);
                     args.sendFinished(mgr);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index cfa242b..02d5705 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -339,7 +339,7 @@
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
                     null, null, requestCode, new Intent[] { intent },
                     resolvedType != null ? new String[] { resolvedType } : null,
@@ -364,7 +364,7 @@
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
                     null, null, requestCode, new Intent[] { intent },
                     resolvedType != null ? new String[] { resolvedType } : null,
@@ -481,7 +481,7 @@
         }
         try {
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
                     null, null, requestCode, intents, resolvedTypes, flags, options,
                     UserHandle.myUserId());
@@ -507,7 +507,7 @@
         }
         try {
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
                     null, null, requestCode, intents, resolvedTypes,
                     flags, options, user.getIdentifier());
@@ -559,7 +559,7 @@
         try {
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_BROADCAST, packageName,
                     null, null, requestCode, new Intent[] { intent },
                     resolvedType != null ? new String[] { resolvedType } : null,
@@ -602,7 +602,7 @@
         try {
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                     ActivityManager.INTENT_SENDER_SERVICE, packageName,
                     null, null, requestCode, new Intent[] { intent },
                     resolvedType != null ? new String[] { resolvedType } : null,
@@ -629,7 +629,7 @@
      */
     public void cancel() {
         try {
-            ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
+            ActivityManager.getService().cancelIntentSender(mTarget);
         } catch (RemoteException e) {
         }
     }
@@ -833,7 +833,7 @@
             String resolvedType = intent != null ?
                     intent.resolveTypeIfNeeded(context.getContentResolver())
                     : null;
-            int res = ActivityManagerNative.getDefault().sendIntentSender(
+            int res = ActivityManager.getService().sendIntentSender(
                     mTarget, code, intent, resolvedType,
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
@@ -853,7 +853,7 @@
     @Deprecated
     public String getTargetPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -882,7 +882,7 @@
     @Nullable
     public String getCreatorPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -910,7 +910,7 @@
      */
     public int getCreatorUid() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -941,7 +941,7 @@
     @Nullable
     public UserHandle getCreatorUserHandle() {
         try {
-            int uid = ActivityManagerNative.getDefault()
+            int uid = ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
             return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
         } catch (RemoteException e) {
@@ -956,7 +956,7 @@
      */
     public boolean isTargetedToPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .isIntentSenderTargetedToPackage(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -970,7 +970,7 @@
      */
     public boolean isActivity() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .isIntentSenderAnActivity(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -984,7 +984,7 @@
      */
     public Intent getIntent() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getIntentForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -998,7 +998,7 @@
      */
     public String getTag(String prefix) {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getTagForIntentSender(mTarget, prefix);
         } catch (RemoteException e) {
             // Should never happen.
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ee6a3ac..c529e4b 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -946,7 +946,7 @@
         try {
             Intent intent = new Intent(Intent.ACTION_ASSIST);
             if (inclContext) {
-                IActivityManager am = ActivityManagerNative.getDefault();
+                IActivityManager am = ActivityManager.getService();
                 Bundle extras = am.getAssistContextExtras(ActivityManager.ASSIST_CONTEXT_BASIC);
                 if (extras != null) {
                     intent.replaceExtras(extras);
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index b859418..54cc4a0 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -768,7 +768,7 @@
             throwIfNotConnectedLocked();
         }
         try {
-            ActivityManagerNative.getDefault().setUserIsMonkey(enable);
+            ActivityManager.getService().setUserIsMonkey(enable);
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error while setting run as monkey!", re);
         }
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index cbd5a6d..d89d2bb 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -357,33 +357,40 @@
     public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;
 
     /** @hide */
-    public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
+    public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS =
+            "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
 
     /** @hide */
-    public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID = "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID";
+    public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID =
+            "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID";
 
     /** @hide */
-    public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI = "android.app.extra.CHOOSE_PRIVATE_KEY_URI";
+    public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI =
+            "android.app.extra.CHOOSE_PRIVATE_KEY_URI";
 
     /** @hide */
-    public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS";
+    public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS =
+            "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS";
 
     /** @hide */
-    public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE = "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE";
+    public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE =
+            "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE";
 
     /**
      * Broadcast action: notify device owner that there is a pending system update.
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
+    public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE =
+            "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
 
     /**
      * A long type extra for {@link #onSystemUpdatePending} recording the system time as given by
      * {@link System#currentTimeMillis()} when the current pending system update is first available.
      * @hide
      */
-    public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME = "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME";
+    public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME =
+            "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME";
 
     /**
      * Name under which a DevicePolicy component publishes information
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 10e6fb2..231dace 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -16,7 +16,7 @@
 
 package android.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.IActivityManager;
 import android.app.QueuedWork;
@@ -366,7 +366,7 @@
          */
         public final void finish() {
             if (mType == TYPE_COMPONENT) {
-                final IActivityManager mgr = ActivityManagerNative.getDefault();
+                final IActivityManager mgr = ActivityManager.getService();
                 if (QueuedWork.hasPendingWork()) {
                     // If this is a broadcast component, we need to make sure any
                     // queued work is complete before telling AM we are done, so
@@ -393,7 +393,7 @@
             } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
                 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                         "Finishing broadcast to " + mToken);
-                final IActivityManager mgr = ActivityManagerNative.getDefault();
+                final IActivityManager mgr = ActivityManager.getService();
                 sendFinished(mgr);
             }
         }
@@ -519,7 +519,7 @@
      * Context#startService(Intent)} for more information.
      */
     public IBinder peekService(Context myContext, Intent service) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         IBinder binder = null;
         try {
             service.prepareToLeaveProcess(myContext);
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 49b5853..f369409 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1131,7 +1131,6 @@
      *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
      *            canceled the refresh request.
      * @return true if the provider actually tried refreshing.
-     * @hide
      */
     public boolean refresh(Uri uri, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) {
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 857610d..fd6cddb 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -147,13 +147,7 @@
             if (cursor == null) {
                 return null;
             }
-
-            if ("com.google.android.gms".equals(mPackageName)) {
-                // They're casting to a concrete subclass, sigh
-                return cursor;
-            } else {
-                return new CursorWrapperInner(cursor);
-            }
+            return new CursorWrapperInner(cursor);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 705c091..54dcd0a 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -23,7 +23,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -397,7 +397,7 @@
         }
 
         try {
-            String type = ActivityManagerNative.getDefault().getProviderMimeType(
+            String type = ActivityManager.getService().getProviderMimeType(
                     ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
             return type;
         } catch (RemoteException e) {
@@ -673,19 +673,13 @@
     }
 
     /**
-     * Implement this to support refresh of content identified by {@code uri}. By default, this
-     * method returns false; providers who wish to implement this should return true to signal the
-     * client that the provider has tried refreshing with its own implementation.
-     * <p>
      * This allows clients to request an explicit refresh of content identified by {@code uri}.
      * <p>
      * Client code should only invoke this method when there is a strong indication (such as a user
      * initiated pull to refresh gesture) that the content is stale.
      * <p>
-     * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)}
-     * notifications when content changes.
      *
-     * @param uri The Uri identifying the data to refresh.
+     * @param url The Uri identifying the data to refresh.
      * @param args Additional options from the client. The definitions of these are specific to the
      *            content provider being called.
      * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
@@ -693,7 +687,6 @@
      *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
      *            canceled the refresh request.
      * @return true if the provider actually tried refreshing.
-     * @hide
      */
     public final boolean refresh(@NonNull Uri url, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) {
@@ -1849,7 +1842,7 @@
             @Intent.AccessUriMode int modeFlags) {
         Preconditions.checkNotNull(uri, "uri");
         try {
-            ActivityManagerNative.getDefault().takePersistableUriPermission(
+            ActivityManager.getService().takePersistableUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
@@ -1867,7 +1860,7 @@
             @Intent.AccessUriMode int modeFlags) {
         Preconditions.checkNotNull(uri, "uri");
         try {
-            ActivityManagerNative.getDefault().releasePersistableUriPermission(
+            ActivityManager.getService().releasePersistableUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
@@ -1885,7 +1878,7 @@
      */
     public @NonNull List<UriPermission> getPersistedUriPermissions() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, true).getList();
         } catch (RemoteException e) {
             throw new RuntimeException("Activity manager has died", e);
@@ -1901,7 +1894,7 @@
      */
     public @NonNull List<UriPermission> getOutgoingPersistedUriPermissions() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, false).getList();
         } catch (RemoteException e) {
             throw new RuntimeException("Activity manager has died", e);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 821b0f8..5fa4275 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2337,7 +2337,7 @@
      * matches <var>filter</var>, in the main application thread.
      *
      * <p>The system may broadcast Intents that are "sticky" -- these stay
-     * around after the broadcast as finished, to be sent to any later
+     * around after the broadcast has finished, to be sent to any later
      * registrations. If your IntentFilter matches one of these sticky
      * Intents, that Intent will be returned by this function
      * <strong>and</strong> sent to your <var>receiver</var> as if it had just
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a9e987a..c87de9a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3835,6 +3835,18 @@
     public static final String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
 
     /**
+     * The host name that triggered an ephemeral resolution.
+     * @hide
+     */
+    public static final String EXTRA_EPHEMERAL_HOSTNAME = "android.intent.extra.EPHEMERAL_HOSTNAME";
+
+    /**
+     * An opaque token to track ephemeral resolution.
+     * @hide
+     */
+    public static final String EXTRA_EPHEMERAL_TOKEN = "android.intent.extra.EPHEMERAL_TOKEN";
+
+    /**
      * A Bundle forming a mapping of potential target package names to different extras Bundles
      * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
      * {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 32ca6c2..4adb5b7 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,7 +16,7 @@
 
 package android.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.Handler;
@@ -187,7 +187,7 @@
             String resolvedType = intent != null ?
                     intent.resolveTypeIfNeeded(context.getContentResolver())
                     : null;
-            int res = ActivityManagerNative.getDefault().sendIntentSender(mTarget,
+            int res = ActivityManager.getService().sendIntentSender(mTarget,
                     code, intent, resolvedType,
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
@@ -207,7 +207,7 @@
     @Deprecated
     public String getTargetPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -226,7 +226,7 @@
      */
     public String getCreatorPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -245,7 +245,7 @@
      */
     public int getCreatorUid() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -266,7 +266,7 @@
      */
     public UserHandle getCreatorUserHandle() {
         try {
-            int uid = ActivityManagerNative.getDefault()
+            int uid = ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
             return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
         } catch (RemoteException e) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 74ec8e4..9b99bbf 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -489,6 +489,13 @@
     public static final int PRIVATE_FLAG_DIRECT_BOOT_AWARE = 1 << 6;
 
     /**
+     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
+     * and for most purposes is considered as not installed.
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 7;
+
+    /**
      * When set, at least one component inside this application is direct boot
      * aware.
      *
@@ -496,12 +503,6 @@
      */
     public static final int PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE = 1 << 8;
 
-    /**
-     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
-     * and for most purposes is considered as not installed.
-     * {@hide}
-     */
-    public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 9;
 
     /**
      * When set, signals that the application is required for the system user and should not be
@@ -509,7 +510,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER = 1 << 10;
+    public static final int PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER = 1 << 9;
 
     /**
      * When set, the application explicitly requested that its activities by resizeable by default.
@@ -517,7 +518,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET = 1 << 11;
+    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET = 1 << 10;
 
     /**
      * The application isn't requesting explicitly requesting for its activities to be resizeable or
@@ -531,7 +532,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION = 1 << 12;
+    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION = 1 << 11;
 
     /**
      * Value for {@link #privateFlags}: {@code true} means the OS should go ahead and
@@ -539,7 +540,7 @@
      * foreground-equivalent run state.  Defaults to {@code false} if unspecified.
      * @hide
      */
-    public static final int PRIVATE_FLAG_BACKUP_IN_FOREGROUND = 1 << 13;
+    public static final int PRIVATE_FLAG_BACKUP_IN_FOREGROUND = 1 << 12;
 
     /**
      * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
@@ -1219,5 +1220,5 @@
     /** {@hide} */ public String[] getSplitCodePaths() { return splitSourceDirs; }
     /** {@hide} */ public String getResourcePath() { return scanPublicSourceDir; }
     /** {@hide} */ public String getBaseResourcePath() { return publicSourceDir; }
-    /** {@hide} */ public String[] getSplitResourcePaths() { return splitSourceDirs; }
+    /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
 }
diff --git a/core/java/android/content/pm/EphemeralRequest.java b/core/java/android/content/pm/EphemeralRequest.java
new file mode 100644
index 0000000..7f2b3ee1
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralRequest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 android.content.pm;
+
+import android.content.Intent;
+
+/**
+ * Information needed to make an ephemeral application resolution request.
+ * @hide
+ */
+public final class EphemeralRequest {
+    /** Response from the first phase of ephemeral application resolution */
+    public final EphemeralResponse responseObj;
+    /** The original intent that triggered ephemeral application resolution */
+    public final Intent origIntent;
+    /** Resolved type of the intent */
+    public final String resolvedType;
+    /** The intent that would launch if there were no ephemeral applications */
+    public final Intent launchIntent;
+    /** The name of the package requesting the ephemeral application */
+    public final String callingPackage;
+    /** ID of the user requesting the ephemeral application */
+    public final int userId;
+
+    public EphemeralRequest(EphemeralResponse responseObj, Intent origIntent,
+            String resolvedType, Intent launchIntent, String callingPackage, int userId) {
+        this.responseObj = responseObj;
+        this.origIntent = origIntent;
+        this.resolvedType = resolvedType;
+        this.launchIntent = launchIntent;
+        this.callingPackage = callingPackage;
+        this.userId = userId;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/EphemeralResolveInfo.java b/core/java/android/content/pm/EphemeralResolveInfo.java
index 3bed06b..f620088 100644
--- a/core/java/android/content/pm/EphemeralResolveInfo.java
+++ b/core/java/android/content/pm/EphemeralResolveInfo.java
@@ -137,28 +137,6 @@
         }
     };
 
-    /** @hide */
-    public static final class EphemeralResolveIntentInfo extends IntentFilter {
-        private final EphemeralResolveInfo mResolveInfo;
-        private final String mSplitName;
-
-        public EphemeralResolveIntentInfo(@NonNull IntentFilter orig,
-                @NonNull EphemeralResolveInfo resolveInfo,
-                @Nullable String splitName) {
-            super(orig);
-            mResolveInfo = resolveInfo;
-            mSplitName = splitName;
-        }
-
-        public EphemeralResolveInfo getEphemeralResolveInfo() {
-            return mResolveInfo;
-        }
-
-        public String getSplitName() {
-            return mSplitName;
-        }
-    }
-
     /**
      * Helper class to generate and store each of the digests and prefixes
      * sent to the Ephemeral Resolver.
diff --git a/core/java/android/content/pm/EphemeralResponse.java b/core/java/android/content/pm/EphemeralResponse.java
new file mode 100644
index 0000000..6e569f7
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralResponse.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.content.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.IntentFilter;
+
+/**
+ * Ephemeral application resolution response.
+ * @hide
+ */
+public final class EphemeralResponse extends IntentFilter {
+    /** Resolved information returned from the external ephemeral resolver */
+    public final EphemeralResolveInfo resolveInfo;
+    /** The resolved package. Copied from {@link #resolveInfo}. */
+    public final String packageName;
+    /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
+    public final String splitName;
+    /** Whether or not ephemeral resolution needs the second phase */
+    public final boolean needsPhase2;
+    /** Opaque token to track the ephemeral application resolution */
+    public final String token;
+
+    public EphemeralResponse(@NonNull EphemeralResolveInfo resolveInfo,
+            @NonNull IntentFilter orig,
+            @Nullable String splitName,
+            @NonNull String token,
+            boolean needsPhase2) {
+        super(orig);
+        this.resolveInfo = resolveInfo;
+        this.packageName = resolveInfo.getPackageName();
+        this.splitName = splitName;
+        this.token = token;
+        this.needsPhase2 = needsPhase2;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 11f0eb6..d753a6e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -492,7 +492,7 @@
     /**
      * Update status of external media on the package manager to scan and
      * install packages installed on the external media. Like say the
-     * MountService uses this to call into the package manager to update
+     * StorageManagerService uses this to call into the package manager to update
      * status of sdcard.
      */
     void updateExternalMediaStatus(boolean mounted, boolean reportStatus);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 2aa7ac6..ad0a6b2 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.util.SparseArray;
 
@@ -208,4 +209,16 @@
      */
     public abstract String getNameForUid(int uid);
 
+    /**
+     * Request to perform the second phase of ephemeral resolution.
+     * @param responseObj The response of the first phase of ephemeral resolution
+     * @param origIntent The original intent that triggered ephemeral resolution
+     * @param resolvedType The resolved type of the intent
+     * @param launchIntent The intent that would launch if there was no ephemeral application
+     * @param callingPackage The name of the package requesting the ephemeral application
+     * @param userId The ID of the user that triggered ephemeral resolution
+     */
+    public abstract void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+            Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage,
+            int userId);
 }
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 86dbe8a..f8b4570 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName;
 import android.content.IntentFilter;
-import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -66,7 +65,7 @@
      * only be set in specific circumstances.
      * @hide
      */
-    public EphemeralResolveIntentInfo ephemeralIntentInfo;
+    public EphemeralResponse ephemeralResponse;
 
     /**
      * The IntentFilter that was matched for this ResolveInfo.
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index f17fd55..cdf7013 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Binder;
 import android.os.CancellationSignal;
@@ -892,7 +892,7 @@
 
     private int getCurrentUserId() {
         try {
-            return ActivityManagerNative.getDefault().getCurrentUser().id;
+            return ActivityManager.getService().getCurrentUser().id;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 45aeb4a..025d46d 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -88,10 +88,10 @@
     /* Returns true if the specified USB function is enabled. */
     boolean isFunctionEnabled(String function);
 
-    /* Sets the current USB function as well as whether USB data 
-     * (for example, MTP exposed pictures) should be made available 
+    /* Sets the current USB function as well as whether USB data
+     * (for example, MTP exposed pictures) should be made available
      * on the USB connection. Unlocking data should only be done with
-     * user involvement, since exposing pictures or other data could 
+     * user involvement, since exposing pictures or other data could
      * leak sensitive user information.
      */
     void setCurrentFunction(String function, boolean usbDataUnlocked);
diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java
index 58acbcf..c7bf0fd 100644
--- a/core/java/android/os/CountDownTimer.java
+++ b/core/java/android/os/CountDownTimer.java
@@ -125,19 +125,28 @@
 
                 if (millisLeft <= 0) {
                     onFinish();
-                } else if (millisLeft < mCountdownInterval) {
-                    // no tick, just delay until done
-                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                 } else {
                     long lastTickStart = SystemClock.elapsedRealtime();
                     onTick(millisLeft);
 
                     // take into account user's onTick taking time to execute
-                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
+                    long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
+                    long delay;
 
-                    // special case: user's onTick took more than interval to
-                    // complete, skip to next interval
-                    while (delay < 0) delay += mCountdownInterval;
+                    if (millisLeft < mCountdownInterval) {
+                        // just delay until done
+                        delay = millisLeft - lastTickDuration;
+
+                        // special case: user's onTick took more than interval to
+                        // complete, trigger onFinish without delay
+                        if (delay < 0) delay = 0;
+                    } else {
+                        delay = mCountdownInterval - lastTickDuration;
+
+                        // special case: user's onTick took more than interval to
+                        // complete, skip to next interval
+                        while (delay < 0) delay += mCountdownInterval;
+                    }
 
                     sendMessageDelayed(obtainMessage(MSG), delay);
                 }
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index e9a3936..ef79b66 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -17,7 +17,6 @@
 
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
 import android.app.IActivityManager;
@@ -1606,7 +1605,7 @@
             public void run() {
                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                 try {
-                    IActivityManager am = ActivityManagerNative.getDefault();
+                    IActivityManager am = ActivityManager.getService();
                     if (am == null) {
                         Log.d(TAG, "No activity manager; failed to Dropbox violation.");
                     } else {
@@ -1943,7 +1942,7 @@
                 // We restore the current policy below, in the finally block.
                 setThreadPolicyMask(0);
 
-                ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
+                ActivityManager.getService().handleApplicationStrictModeViolation(
                     RuntimeInit.getApplicationObject(),
                     violationMaskSubset,
                     info);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 15dd282..50eb7cf 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -26,7 +26,6 @@
 import android.annotation.WorkerThread;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -983,7 +982,7 @@
     public boolean isUserRunning(int userId) {
         // TODO Switch to using UMS internal isUserRunning
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userId, 0);
+            return ActivityManager.getService().isUserRunning(userId, 0);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -999,7 +998,7 @@
     public boolean isUserRunningOrStopping(UserHandle user) {
         try {
             // TODO: reconcile stopped vs stopping?
-            return ActivityManagerNative.getDefault().isUserRunning(
+            return ActivityManager.getService().isUserRunning(
                     user.getIdentifier(), ActivityManager.FLAG_OR_STOPPED);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
@@ -1016,7 +1015,7 @@
     @Deprecated
     public boolean isUserRunningAndLocked(UserHandle user) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(
+            return ActivityManager.getService().isUserRunning(
                     user.getIdentifier(), ActivityManager.FLAG_AND_LOCKED);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
@@ -1033,7 +1032,7 @@
     @Deprecated
     public boolean isUserRunningAndUnlocked(UserHandle user) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(
+            return ActivityManager.getService().isUserRunning(
                     user.getIdentifier(), ActivityManager.FLAG_AND_UNLOCKED);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
@@ -1080,7 +1079,7 @@
     /** {@hide} */
     public boolean isUserUnlocked(@UserIdInt int userId) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userId,
+            return ActivityManager.getService().isUserRunning(userId,
                     ActivityManager.FLAG_AND_UNLOCKED);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
diff --git a/core/java/android/os/storage/IObbActionListener.aidl b/core/java/android/os/storage/IObbActionListener.aidl
index 61ba4d5..a86ba59 100644
--- a/core/java/android/os/storage/IObbActionListener.aidl
+++ b/core/java/android/os/storage/IObbActionListener.aidl
@@ -17,7 +17,7 @@
 package android.os.storage;
 
 /**
- * Callback class for receiving events from MountService about Opaque Binary
+ * Callback class for receiving events from StorageManagerService about Opaque Binary
  * Blobs (OBBs).
  *
  * Don't change the existing transaction Ids as they could be used in the native code.
diff --git a/core/java/android/os/storage/IMountServiceListener.aidl b/core/java/android/os/storage/IStorageEventListener.aidl
similarity index 89%
rename from core/java/android/os/storage/IMountServiceListener.aidl
rename to core/java/android/os/storage/IStorageEventListener.aidl
index 0e20cd3..4ba1dbe 100644
--- a/core/java/android/os/storage/IMountServiceListener.aidl
+++ b/core/java/android/os/storage/IStorageEventListener.aidl
@@ -21,15 +21,15 @@
 import android.os.storage.VolumeRecord;
 
 /**
- * Callback class for receiving events from MountService.
+ * Callback class for receiving events from StorageManagerService.
  *
  * Don't change the existing transaction Ids as they could be used in the native code.
  * When adding a new method, assign the next available transaction id.
  *
- * @hide - Applications should use IStorageEventListener for storage event
- *       callbacks.
+ * @hide - Applications should use {@link android.os.storage.StorageEventListener} class for
+ *         storage event callbacks.
  */
-oneway interface IMountServiceListener {
+oneway interface IStorageEventListener {
     /**
      * Detection state of USB Mass Storage has changed
      *
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IStorageManager.aidl
similarity index 90%
rename from core/java/android/os/storage/IMountService.aidl
rename to core/java/android/os/storage/IStorageManager.aidl
index 390df99..98cbce6 100644
--- a/core/java/android/os/storage/IMountService.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -19,8 +19,8 @@
 import android.content.pm.IPackageMoveObserver;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.DiskInfo;
-import android.os.storage.IMountServiceListener;
-import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IStorageEventListener;
+import android.os.storage.IStorageShutdownObserver;
 import android.os.storage.IObbActionListener;
 import android.os.storage.StorageVolume;
 import android.os.storage.VolumeInfo;
@@ -34,15 +34,15 @@
  * @hide - Applications should use android.os.storage.StorageManager to access
  *       storage functions.
  */
-interface IMountService {
+interface IStorageManager {
     /**
-     * Registers an IMountServiceListener for receiving async notifications.
+     * Registers an IStorageEventListener for receiving async notifications.
      */
-    void registerListener(IMountServiceListener listener) = 0;
+    void registerListener(IStorageEventListener listener) = 0;
     /**
-     * Unregisters an IMountServiceListener
+     * Unregisters an IStorageEventListener
      */
-    void unregisterListener(IMountServiceListener listener) = 1;
+    void unregisterListener(IStorageEventListener listener) = 1;
     /**
      * Returns true if a USB mass storage host is connected
      */
@@ -58,7 +58,7 @@
     boolean isUsbMassStorageEnabled() = 4;
     /**
      * Mount external storage at given mount point. Returns an int consistent
-     * with MountServiceResultCode
+     * with StorageResultCode
      */
     int mountVolume(in String mountPoint) = 5;
     /**
@@ -74,7 +74,7 @@
     void unmountVolume(in String mountPoint, boolean force, boolean removeEncryption) = 6;
     /**
      * Format external storage given a mount point. Returns an int consistent
-     * with MountServiceResultCode
+     * with StorageResultCode
      */
     int formatVolume(in String mountPoint) = 7;
     /**
@@ -87,30 +87,30 @@
     String getVolumeState(in String mountPoint) = 9;
     /*
      * Creates a secure container with the specified parameters. Returns an int
-     * consistent with MountServiceResultCode
+     * consistent with StorageResultCode
      */
     int createSecureContainer(in String id, int sizeMb, in String fstype, in String key,
             int ownerUid, boolean external) = 10;
     /*
      * Finalize a container which has just been created and populated. After
      * finalization, the container is immutable. Returns an int consistent with
-     * MountServiceResultCode
+     * StorageResultCode
      */
     int finalizeSecureContainer(in String id) = 11;
     /*
      * Destroy a secure container, and free up all resources associated with it.
      * NOTE: Ensure all references are released prior to deleting. Returns an
-     * int consistent with MountServiceResultCode
+     * int consistent with StorageResultCode
      */
     int destroySecureContainer(in String id, boolean force) = 12;
     /*
      * Mount a secure container with the specified key and owner UID. Returns an
-     * int consistent with MountServiceResultCode
+     * int consistent with StorageResultCode
      */
     int mountSecureContainer(in String id, in String key, int ownerUid, boolean readOnly) = 13;
     /*
      * Unount a secure container. Returns an int consistent with
-     * MountServiceResultCode
+     * StorageResultCode
      */
     int unmountSecureContainer(in String id, boolean force) = 14;
     /*
@@ -119,7 +119,7 @@
     boolean isSecureContainerMounted(in String id) = 15;
     /*
      * Rename an unmounted secure container. Returns an int consistent with
-     * MountServiceResultCode
+     * StorageResultCode
      */
     int renameSecureContainer(in String oldId, in String newId) = 16;
     /*
@@ -131,19 +131,19 @@
      */
     String[] getSecureContainerList() = 18;
     /**
-     * Shuts down the MountService and gracefully unmounts all external media.
+     * Shuts down the StorageManagerService and gracefully unmounts all external media.
      * Invokes call back once the shutdown is complete.
      */
-    void shutdown(IMountShutdownObserver observer) = 19;
+    void shutdown(IStorageShutdownObserver observer) = 19;
     /**
-     * Call into MountService by PackageManager to notify that its done
+     * Call into StorageManagerService by PackageManager to notify that its done
      * processing the media status update request.
      */
     void finishMediaUpdate() = 20;
     /**
      * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
      * only allows the calling process's UID access to the contents.
-     * MountService will call back to the supplied IObbActionListener to inform
+     * StorageManagerService will call back to the supplied IObbActionListener to inform
      * it of the terminal state of the call.
      */
     void mountObb(in String rawPath, in String canonicalPath, in String key,
@@ -151,7 +151,7 @@
     /**
      * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
      * any program using it will be forcibly killed to unmount the image.
-     * MountService will call back to the supplied IObbActionListener to inform
+     * StorageManagerService will call back to the supplied IObbActionListener to inform
      * it of the terminal state of the call.
      */
     void unmountObb(in String rawPath, boolean force, IObbActionListener token, int nonce) = 22;
@@ -209,7 +209,7 @@
     int verifyEncryptionPassword(in String password) = 32;
     /*
      * Fix permissions in a container which has just been created and populated.
-     * Returns an int consistent with MountServiceResultCode
+     * Returns an int consistent with StorageResultCode
      */
     int fixPermissionsSecureContainer(in String id, int gid, in String filename) = 33;
     /**
diff --git a/core/java/android/os/storage/IMountShutdownObserver.aidl b/core/java/android/os/storage/IStorageShutdownObserver.aidl
similarity index 91%
rename from core/java/android/os/storage/IMountShutdownObserver.aidl
rename to core/java/android/os/storage/IStorageShutdownObserver.aidl
index f3e1654..b284217 100644
--- a/core/java/android/os/storage/IMountShutdownObserver.aidl
+++ b/core/java/android/os/storage/IStorageShutdownObserver.aidl
@@ -24,9 +24,9 @@
  *
  * @hide - For internal consumption only.
  */
-interface IMountShutdownObserver {
+interface IStorageShutdownObserver {
     /**
-     * This method is called when the shutdown of MountService completed.
+     * This method is called when the shutdown of StorageManagerService completed.
      *
      * @param statusCode indicates success or failure of the shutdown.
      */
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 1942fde..0472e02 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -152,7 +152,7 @@
     /** @hide Underlying data is corrupt */
     public static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
 
-    private static volatile IMountService sMountService = null;
+    private static volatile IStorageManager sStorageManager = null;
 
     // TODO: the location of the primary storage block varies from device to device, so we need to
     // try the most likely candidates - a long-term solution would be a device-specific vold
@@ -166,13 +166,13 @@
     private final Context mContext;
     private final ContentResolver mResolver;
 
-    private final IMountService mMountService;
+    private final IStorageManager mStorageManager;
     private final Looper mLooper;
     private final AtomicInteger mNextNonce = new AtomicInteger(0);
 
     private final ArrayList<StorageEventListenerDelegate> mDelegates = new ArrayList<>();
 
-    private static class StorageEventListenerDelegate extends IMountServiceListener.Stub implements
+    private static class StorageEventListenerDelegate extends IStorageEventListener.Stub implements
             Handler.Callback {
         private static final int MSG_STORAGE_STATE_CHANGED = 1;
         private static final int MSG_VOLUME_STATE_CHANGED = 2;
@@ -374,7 +374,7 @@
         mContext = context;
         mResolver = context.getContentResolver();
         mLooper = looper;
-        mMountService = IMountService.Stub.asInterface(ServiceManager.getServiceOrThrow("mount"));
+        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getServiceOrThrow("mount"));
     }
 
     /**
@@ -389,7 +389,7 @@
             final StorageEventListenerDelegate delegate = new StorageEventListenerDelegate(listener,
                     mLooper);
             try {
-                mMountService.registerListener(delegate);
+                mStorageManager.registerListener(delegate);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -410,7 +410,7 @@
                 final StorageEventListenerDelegate delegate = i.next();
                 if (delegate.mCallback == listener) {
                     try {
-                        mMountService.unregisterListener(delegate);
+                        mStorageManager.unregisterListener(delegate);
                     } catch (RemoteException e) {
                         throw e.rethrowFromSystemServer();
                     }
@@ -488,7 +488,7 @@
         try {
             final String canonicalPath = new File(rawPath).getCanonicalPath();
             final int nonce = mObbActionListener.addListener(listener);
-            mMountService.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce);
+            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce);
             return true;
         } catch (IOException e) {
             throw new IllegalArgumentException("Failed to resolve path: " + rawPath, e);
@@ -523,7 +523,7 @@
 
         try {
             final int nonce = mObbActionListener.addListener(listener);
-            mMountService.unmountObb(rawPath, force, mObbActionListener, nonce);
+            mStorageManager.unmountObb(rawPath, force, mObbActionListener, nonce);
             return true;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -540,7 +540,7 @@
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
 
         try {
-            return mMountService.isObbMounted(rawPath);
+            return mStorageManager.isObbMounted(rawPath);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -559,7 +559,7 @@
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
 
         try {
-            return mMountService.getMountedObbPath(rawPath);
+            return mStorageManager.getMountedObbPath(rawPath);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -568,7 +568,7 @@
     /** {@hide} */
     public @NonNull List<DiskInfo> getDisks() {
         try {
-            return Arrays.asList(mMountService.getDisks());
+            return Arrays.asList(mStorageManager.getDisks());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -654,7 +654,7 @@
     /** {@hide} */
     public @NonNull List<VolumeInfo> getVolumes() {
         try {
-            return Arrays.asList(mMountService.getVolumes(0));
+            return Arrays.asList(mStorageManager.getVolumes(0));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -664,7 +664,7 @@
     public @NonNull List<VolumeInfo> getWritablePrivateVolumes() {
         try {
             final ArrayList<VolumeInfo> res = new ArrayList<>();
-            for (VolumeInfo vol : mMountService.getVolumes(0)) {
+            for (VolumeInfo vol : mStorageManager.getVolumes(0)) {
                 if (vol.getType() == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) {
                     res.add(vol);
                 }
@@ -678,7 +678,7 @@
     /** {@hide} */
     public @NonNull List<VolumeRecord> getVolumeRecords() {
         try {
-            return Arrays.asList(mMountService.getVolumeRecords(0));
+            return Arrays.asList(mStorageManager.getVolumeRecords(0));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -721,7 +721,7 @@
     /** {@hide} */
     public void mount(String volId) {
         try {
-            mMountService.mount(volId);
+            mStorageManager.mount(volId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -730,7 +730,7 @@
     /** {@hide} */
     public void unmount(String volId) {
         try {
-            mMountService.unmount(volId);
+            mStorageManager.unmount(volId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -739,7 +739,7 @@
     /** {@hide} */
     public void format(String volId) {
         try {
-            mMountService.format(volId);
+            mStorageManager.format(volId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -748,7 +748,7 @@
     /** {@hide} */
     public long benchmark(String volId) {
         try {
-            return mMountService.benchmark(volId);
+            return mStorageManager.benchmark(volId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -757,7 +757,7 @@
     /** {@hide} */
     public void partitionPublic(String diskId) {
         try {
-            mMountService.partitionPublic(diskId);
+            mStorageManager.partitionPublic(diskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -766,7 +766,7 @@
     /** {@hide} */
     public void partitionPrivate(String diskId) {
         try {
-            mMountService.partitionPrivate(diskId);
+            mStorageManager.partitionPrivate(diskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -775,7 +775,7 @@
     /** {@hide} */
     public void partitionMixed(String diskId, int ratio) {
         try {
-            mMountService.partitionMixed(diskId, ratio);
+            mStorageManager.partitionMixed(diskId, ratio);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -795,7 +795,7 @@
                 try {
                     // TODO: switch to explicit wipe command when we have it,
                     // for now rely on the fact that vfat format does a wipe
-                    mMountService.partitionPublic(diskId);
+                    mStorageManager.partitionPublic(diskId);
                 } catch (Exception e) {
                     Slog.w(TAG, "Failed to wipe " + diskId + ", but soldiering onward", e);
                 }
@@ -808,7 +808,7 @@
     /** {@hide} */
     public void setVolumeNickname(String fsUuid, String nickname) {
         try {
-            mMountService.setVolumeNickname(fsUuid, nickname);
+            mStorageManager.setVolumeNickname(fsUuid, nickname);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -817,7 +817,7 @@
     /** {@hide} */
     public void setVolumeInited(String fsUuid, boolean inited) {
         try {
-            mMountService.setVolumeUserFlags(fsUuid, inited ? VolumeRecord.USER_FLAG_INITED : 0,
+            mStorageManager.setVolumeUserFlags(fsUuid, inited ? VolumeRecord.USER_FLAG_INITED : 0,
                     VolumeRecord.USER_FLAG_INITED);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -827,7 +827,7 @@
     /** {@hide} */
     public void setVolumeSnoozed(String fsUuid, boolean snoozed) {
         try {
-            mMountService.setVolumeUserFlags(fsUuid, snoozed ? VolumeRecord.USER_FLAG_SNOOZED : 0,
+            mStorageManager.setVolumeUserFlags(fsUuid, snoozed ? VolumeRecord.USER_FLAG_SNOOZED : 0,
                     VolumeRecord.USER_FLAG_SNOOZED);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -837,7 +837,7 @@
     /** {@hide} */
     public void forgetVolume(String fsUuid) {
         try {
-            mMountService.forgetVolume(fsUuid);
+            mStorageManager.forgetVolume(fsUuid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -851,7 +851,7 @@
      */
     public String getPrimaryStorageUuid() {
         try {
-            return mMountService.getPrimaryStorageUuid();
+            return mStorageManager.getPrimaryStorageUuid();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -865,7 +865,7 @@
      */
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
         try {
-            mMountService.setPrimaryStorageUuid(volumeUuid, callback);
+            mStorageManager.setPrimaryStorageUuid(volumeUuid, callback);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -982,7 +982,7 @@
 
     /** {@hide} */
     public static @NonNull StorageVolume[] getVolumeList(int userId, int flags) {
-        final IMountService mountService = IMountService.Stub.asInterface(
+        final IStorageManager storageManager = IStorageManager.Stub.asInterface(
                 ServiceManager.getService("mount"));
         try {
             String packageName = ActivityThread.currentOpPackageName();
@@ -1003,7 +1003,7 @@
             if (uid <= 0) {
                 return new StorageVolume[0];
             }
-            return mountService.getVolumeList(uid, packageName, flags);
+            return storageManager.getVolumeList(uid, packageName, flags);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1085,7 +1085,7 @@
     /** {@hide} */
     public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
         try {
-            mMountService.createUserKey(userId, serialNumber, ephemeral);
+            mStorageManager.createUserKey(userId, serialNumber, ephemeral);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1094,7 +1094,7 @@
     /** {@hide} */
     public void destroyUserKey(int userId) {
         try {
-            mMountService.destroyUserKey(userId);
+            mStorageManager.destroyUserKey(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1103,7 +1103,7 @@
     /** {@hide} */
     public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
         try {
-            mMountService.unlockUserKey(userId, serialNumber, token, secret);
+            mStorageManager.unlockUserKey(userId, serialNumber, token, secret);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1112,7 +1112,7 @@
     /** {@hide} */
     public void lockUserKey(int userId) {
         try {
-            mMountService.lockUserKey(userId);
+            mStorageManager.lockUserKey(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1121,7 +1121,7 @@
     /** {@hide} */
     public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) {
         try {
-            mMountService.prepareUserStorage(volumeUuid, userId, serialNumber, flags);
+            mStorageManager.prepareUserStorage(volumeUuid, userId, serialNumber, flags);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1130,7 +1130,7 @@
     /** {@hide} */
     public void destroyUserStorage(String volumeUuid, int userId, int flags) {
         try {
-            mMountService.destroyUserStorage(volumeUuid, userId, flags);
+            mStorageManager.destroyUserStorage(volumeUuid, userId, flags);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1138,17 +1138,17 @@
 
     /** {@hide} */
     public static boolean isUserKeyUnlocked(int userId) {
-        if (sMountService == null) {
-            sMountService = IMountService.Stub
+        if (sStorageManager == null) {
+            sStorageManager = IStorageManager.Stub
                     .asInterface(ServiceManager.getService("mount"));
         }
-        if (sMountService == null) {
+        if (sStorageManager == null) {
             Slog.w(TAG, "Early during boot, assuming locked");
             return false;
         }
         final long token = Binder.clearCallingIdentity();
         try {
-            return sMountService.isUserKeyUnlocked(userId);
+            return sStorageManager.isUserKeyUnlocked(userId);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         } finally {
@@ -1224,9 +1224,9 @@
         }
 
         try {
-            IMountService mountService = IMountService.Stub.asInterface(
+            IStorageManager storageManager = IStorageManager.Stub.asInterface(
                     ServiceManager.getService("mount"));
-            return mountService.getPasswordType() != CRYPT_TYPE_DEFAULT;
+            return storageManager.getPasswordType() != CRYPT_TYPE_DEFAULT;
         } catch (RemoteException e) {
             Log.e(TAG, "Error getting encryption type");
             return false;
@@ -1280,10 +1280,10 @@
 
     /** {@hide} */
     public static File maybeTranslateEmulatedPathToInternal(File path) {
-        final IMountService mountService = IMountService.Stub.asInterface(
+        final IStorageManager storageManager = IStorageManager.Stub.asInterface(
                 ServiceManager.getService("mount"));
         try {
-            final VolumeInfo[] vols = mountService.getVolumes(0);
+            final VolumeInfo[] vols = storageManager.getVolumes(0);
             for (VolumeInfo vol : vols) {
                 if ((vol.getType() == VolumeInfo.TYPE_EMULATED
                         || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
@@ -1303,7 +1303,7 @@
     /** {@hide} */
     public ParcelFileDescriptor mountAppFuse(String name) {
         try {
-            return mMountService.mountAppFuse(name);
+            return mStorageManager.mountAppFuse(name);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1319,7 +1319,7 @@
     /** @hide */
     public static final int CRYPT_TYPE_PIN = 3;
 
-    // Constants for the data available via MountService.getField.
+    // Constants for the data available via StorageManagerService.getField.
     /** @hide */
     public static final String SYSTEM_LOCALE_KEY = "SystemLocale";
     /** @hide */
diff --git a/core/java/android/os/storage/MountServiceInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
similarity index 98%
rename from core/java/android/os/storage/MountServiceInternal.java
rename to core/java/android/os/storage/StorageManagerInternal.java
index 17aaef9..d102b19 100644
--- a/core/java/android/os/storage/MountServiceInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -21,7 +21,7 @@
  *
  * @hide Only for use within the system server.
  */
-public abstract class MountServiceInternal {
+public abstract class StorageManagerInternal {
 
     /**
      * Policy that influences how external storage is mounted and reported.
diff --git a/core/java/android/os/storage/StorageResultCode.java b/core/java/android/os/storage/StorageResultCode.java
index 8e7db31..c843887 100644
--- a/core/java/android/os/storage/StorageResultCode.java
+++ b/core/java/android/os/storage/StorageResultCode.java
@@ -18,7 +18,7 @@
 
 /**
  * Class that provides access to constants returned from StorageManager
- * and lower level MountService APIs.
+ * and lower level StorageManagerService APIs.
  * 
  * @hide
  */
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 7b0d2a4..46f2d38 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -332,7 +332,7 @@
      *            {@link Environment#DIRECTORY_ALARMS}, {@link Environment#DIRECTORY_NOTIFICATIONS},
      *            {@link Environment#DIRECTORY_PICTURES}, {@link Environment#DIRECTORY_MOVIES},
      *            {@link Environment#DIRECTORY_DOWNLOADS}, {@link Environment#DIRECTORY_DCIM}, or
-     *            {@link Environment#DIRECTORY_DOCUMENTS}, or {code null} to request access to the
+     *            {@link Environment#DIRECTORY_DOCUMENTS}, or {@code null} to request access to the
      *            entire volume.
      * @return intent to request access, or {@code null} if the requested directory is invalid for
      *         that volume.
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index f86193f..383cae1 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -156,6 +156,10 @@
     private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
 
     /** {@hide} */
+    public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY =
+            "com.android.externalstorage.documents";
+
+    /** {@hide} */
     public static final String PACKAGE_DOCUMENTS_UI = "com.android.documentsui";
 
     /**
@@ -699,7 +703,7 @@
     public static Uri buildHomeUri() {
         // TODO: Avoid this type of interpackage copying. Added here to avoid
         // direct coupling, but not ideal.
-        return DocumentsContract.buildRootUri("com.android.externalstorage.documents", "home");
+        return DocumentsContract.buildRootUri(EXTERNAL_STORAGE_PROVIDER_AUTHORITY, "home");
     }
 
     /**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index de19f81..c4684e7 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -18,11 +18,13 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.UriPermission;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteException;
@@ -32,17 +34,23 @@
 import android.media.MiniThumbFile;
 import android.media.ThumbnailUtils;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
 import android.service.media.CameraPrewarmService;
 import android.util.Log;
 
+import libcore.io.IoUtils;
+
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * The Media provider contains meta data for all available media on both internal
@@ -2297,4 +2305,86 @@
         }
         return null;
     }
+
+    /**
+     * Gets a URI backed by a {@link DocumentsProvider} that points to the same media
+     * file as the specified mediaUri. This allows apps who have permissions to access
+     * media files in Storage Access Framework to perform file operations through that
+     * on media files.
+     * <p>
+     * Note: this method doesn't grant any URI permission. Callers need to obtain
+     * permission before calling this method. One way to obtain permission is through
+     * a 3-step process:
+     * <ol>
+     *     <li>Call {@link android.os.storage.StorageManager#getStorageVolume(File)} to
+     *     obtain the {@link android.os.storage.StorageVolume} of a media file;</li>
+     *
+     *     <li>Invoke the intent returned by
+     *     {@link android.os.storage.StorageVolume#createAccessIntent(String)} to
+     *     obtain the access of the volume or one of its specific subdirectories;</li>
+     *
+     *     <li>Check whether permission is granted and take persistent permission.</li>
+     * </ol>
+     * @param mediaUri the media URI which document URI is requested
+     * @return the document URI
+     */
+    public static Uri getDocumentUri(Context context, Uri mediaUri) {
+
+        try {
+            final ContentResolver resolver = context.getContentResolver();
+
+            final String path = getFilePath(resolver, mediaUri);
+            final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
+
+            return getDocumentUri(resolver, path, uriPermissions);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    private static String getFilePath(ContentResolver resolver, Uri mediaUri)
+            throws RemoteException {
+
+        try (ContentProviderClient client =
+                     resolver.acquireUnstableContentProviderClient(AUTHORITY)) {
+            final Cursor c = client.query(
+                    mediaUri,
+                    new String[]{ MediaColumns.DATA },
+                    null, /* selection */
+                    null, /* selectionArg */
+                    null /* sortOrder */);
+
+            final String path;
+            try {
+                if (c.getCount() == 0) {
+                    throw new IllegalStateException("Not found media file under URI: " + mediaUri);
+                }
+
+                if (!c.moveToFirst()) {
+                    throw new IllegalStateException("Failed to move cursor to the first item.");
+                }
+
+                path = c.getString(0);
+            } finally {
+                IoUtils.closeQuietly(c);
+            }
+
+            return path;
+        }
+    }
+
+    private static Uri getDocumentUri(
+            ContentResolver resolver, String path, List<UriPermission> uriPermissions)
+            throws RemoteException {
+
+        try (ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY)) {
+            final Bundle in = new Bundle();
+            in.putParcelableList(
+                    DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY + ".extra.uriPermissions",
+                    uriPermissions);
+            final Bundle out = client.call("getDocumentId", path, in);
+            return out.getParcelable(DocumentsContract.EXTRA_URI);
+        }
+    }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79b42ba..afbc09b 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5854,7 +5854,8 @@
                 "search_per_source_concurrent_query_limit";
 
         /**
-         * Whether or not alert sounds are played on MountService events. (0 = false, 1 = true)
+         * Whether or not alert sounds are played on StorageManagerService events.
+         * (0 = false, 1 = true)
          * @hide
          */
         public static final String MOUNT_PLAY_NOTIFICATION_SND = "mount_play_not_snd";
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 479f493..6e4d78d 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -242,14 +242,20 @@
 
         Transition mTransition;
         ViewGroup mSceneRoot;
+        final ViewTreeObserver mViewTreeObserver;
 
         MultiListener(Transition transition, ViewGroup sceneRoot) {
             mTransition = transition;
             mSceneRoot = sceneRoot;
+            mViewTreeObserver = mSceneRoot.getViewTreeObserver();
         }
 
         private void removeListeners() {
-            mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+            if (mViewTreeObserver.isAlive()) {
+                mViewTreeObserver.removeOnPreDrawListener(this);
+            } else {
+                mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+            }
             mSceneRoot.removeOnAttachStateChangeListener(this);
         }
 
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 7a3c95e..8eca431 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -26,6 +26,8 @@
 
 import dalvik.annotation.optimization.FastNative;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * <p>A display list records a series of graphics related operations and can replay
  * them later. Display lists are usually built by recording operations on a
@@ -130,13 +132,20 @@
  */
 public class RenderNode {
 
+    // Use a Holder to allow static initialization in the boot image.
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
+    }
+
     private boolean mValid;
     // Do not access directly unless you are ThreadedRenderer
-    long mNativeRenderNode;
+    final long mNativeRenderNode;
     private final View mOwningView;
 
     private RenderNode(String name, View owningView) {
         mNativeRenderNode = nCreate(name);
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
         mOwningView = owningView;
     }
 
@@ -145,6 +154,7 @@
      */
     private RenderNode(long nativePtr) {
         mNativeRenderNode = nativePtr;
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
         mOwningView = null;
     }
 
@@ -154,19 +164,7 @@
      * is not feasible.
      */
     public void destroy() {
-        if (mNativeRenderNode != 0) {
-            nFinalize(mNativeRenderNode);
-            mNativeRenderNode = 0;
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroy();
-        } finally {
-            super.finalize();
-        }
+        // TODO: Removed temporarily
     }
 
     /**
@@ -835,7 +833,6 @@
 
     // Intentionally not static because it acquires a reference to 'this'
     private native long nCreate(String name);
-    private native void nFinalize(long renderNode);
 
     private static native long nGetNativeFinalizer();
     private static native void nSetDisplayList(long renderNode, long newData);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 0bb84cc..5012215 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -18,7 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -921,7 +921,7 @@
         private static void initSched(Context context, long renderProxy) {
             try {
                 int tid = nGetRenderThreadTid(renderProxy);
-                ActivityManagerNative.getDefault().setRenderThread(tid);
+                ActivityManager.getService().setRenderThread(tid);
             } catch (Throwable t) {
                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
             }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cdd8b6a..1ff8fb0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -26,7 +26,7 @@
 import android.Manifest;
 import android.animation.LayoutTransition;
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ResourcesManager;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -7084,7 +7084,7 @@
 
         private static int checkCallingPermission(String permission) {
             try {
-                return ActivityManagerNative.getDefault().checkPermission(
+                return ActivityManager.getService().checkPermission(
                         permission, Binder.getCallingPid(), Binder.getCallingUid());
             } catch (RemoteException e) {
                 return PackageManager.PERMISSION_DENIED;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4195d91..82379c4 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -672,7 +672,7 @@
      * button bar.
      */
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the display height available after excluding any screen
@@ -680,7 +680,7 @@
      * button bar.
      */
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the available screen width that we should report for the
@@ -689,7 +689,7 @@
      * that to account for more transient decoration like a status bar.
      */
     public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the available screen height that we should report for the
@@ -698,7 +698,7 @@
      * that to account for more transient decoration like a status bar.
      */
     public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return whether the given window can become the Keyguard window. Typically returns true for
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index f4ea90b..c147895 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -17,8 +17,8 @@
 package android.webkit;
 
 import android.annotation.SystemApi;
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.Application;
 import android.content.Context;
@@ -292,7 +292,7 @@
             // killed if the package info goes out-of-date.
             Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "ActivityManager.addPackageDependency()");
             try {
-                ActivityManagerNative.getDefault().addPackageDependency(
+                ActivityManager.getService().addPackageDependency(
                         response.packageInfo.packageName);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 5eaabe7..541fbe0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -111,6 +111,8 @@
 import android.widget.TextView.OnEditorActionListener;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 import com.android.internal.util.Preconditions;
@@ -1119,14 +1121,26 @@
             getInsertionController().show();
             mIsInsertionActionModeStartPending = true;
             handled = true;
+            MetricsLogger.action(
+                    mTextView.getContext(),
+                    MetricsEvent.TEXT_LONGPRESS,
+                    TextViewMetrics.SUBTYPE_LONG_PRESS_OTHER);
         }
 
         if (!handled && mTextActionMode != null) {
             if (touchPositionIsInSelection()) {
                 startDragAndDrop();
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_DRAG_AND_DROP);
             } else {
                 stopTextActionMode();
                 selectCurrentWordAndStartDrag();
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_SELECTION);
             }
             handled = true;
         }
@@ -1134,6 +1148,12 @@
         // Start a new selection
         if (!handled) {
             handled = selectCurrentWordAndStartDrag();
+            if (handled) {
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_SELECTION);
+            }
         }
 
         return handled;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 18ce260..a9268d4 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -404,6 +404,7 @@
         // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache
         mBitmapCache = new BitmapCache();
         setBitmapCache(mBitmapCache);
+        recalculateMemoryUsage();
     }
 
     private class SetEmptyView extends Action {
@@ -2117,26 +2118,8 @@
             return mMemoryUsage;
         }
 
-        @SuppressWarnings("deprecation")
         public void addBitmapMemory(Bitmap b) {
-            final Bitmap.Config c = b.getConfig();
-            // If we don't know, be pessimistic and assume 4
-            int bpp = 4;
-            if (c != null) {
-                switch (c) {
-                    case ALPHA_8:
-                        bpp = 1;
-                        break;
-                    case RGB_565:
-                    case ARGB_4444:
-                        bpp = 2;
-                        break;
-                    case ARGB_8888:
-                        bpp = 4;
-                        break;
-                }
-            }
-            increment(b.getWidth() * b.getHeight() * bpp);
+            increment(b.getAllocationByteCount());
         }
 
         int mMemoryUsage;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5426a37..69f463c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -148,6 +148,8 @@
 import android.widget.RemoteViews.RemoteView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.FastMath;
 import com.android.internal.widget.EditableInputConnection;
 
@@ -9685,6 +9687,11 @@
         if (handled) {
             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
             if (mEditor != null) mEditor.mDiscardNextActionUp = true;
+        } else {
+            MetricsLogger.action(
+                    mContext,
+                    MetricsEvent.TEXT_LONGPRESS,
+                    TextViewMetrics.SUBTYPE_LONG_PRESS_OTHER);
         }
 
         return handled;
diff --git a/core/java/android/widget/TextViewMetrics.java b/core/java/android/widget/TextViewMetrics.java
new file mode 100644
index 0000000..0a14d3e
--- /dev/null
+++ b/core/java/android/widget/TextViewMetrics.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.widget;
+
+/**
+ * {@link com.android.internal.logging.MetricsLogger} values for TextView.
+ *
+ * @hide
+ */
+final class TextViewMetrics {
+
+    private TextViewMetrics() {}
+
+    /**
+     * Long press on TextView - no special classification.
+     */
+    static final int SUBTYPE_LONG_PRESS_OTHER = 0;
+    /**
+     * Long press on TextView - selection started.
+     */
+    static final int SUBTYPE_LONG_PRESS_SELECTION = 1;
+    /**
+     * Long press on TextView - drag and drop started.
+     */
+    static final int SUBTYPE_LONG_PRESS_DRAG_AND_DROP = 2;
+}
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index 83ad9dc..459071b 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -19,7 +19,7 @@
 import com.android.internal.R;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
@@ -122,7 +122,7 @@
     private OnClickListener mSwitchOldListener = new OnClickListener() {
         public void onClick(View v) {
             try {
-                ActivityManagerNative.getDefault().moveTaskToFront(mCurTask, 0, null);
+                ActivityManager.getService().moveTaskToFront(mCurTask, 0, null);
             } catch (RemoteException e) {
             }
             finish();
@@ -132,7 +132,7 @@
     private OnClickListener mSwitchNewListener = new OnClickListener() {
         public void onClick(View v) {
             try {
-                ActivityManagerNative.getDefault().finishHeavyWeightApp();
+                ActivityManager.getService().finishHeavyWeightApp();
             } catch (RemoteException e) {
             }
             try {
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 015e60d..0b27c60 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -19,7 +19,7 @@
 import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
@@ -110,9 +110,9 @@
                 int launchedFromUid = -1;
                 String launchedFromPackage = "?";
                 try {
-                    launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+                    launchedFromUid = ActivityManager.getService().getLaunchedFromUid(
                             getActivityToken());
-                    launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                    launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
                             getActivityToken());
                 } catch (RemoteException ignored) {
                 }
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 472f583..9936ed5 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -18,7 +18,7 @@
 
 import com.android.internal.R;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.ListFragment;
 import android.app.backup.BackupManager;
@@ -269,7 +269,7 @@
      */
     public static void updateLocales(LocaleList locales) {
         try {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             final Configuration config = am.getConfiguration();
 
             config.setLocales(locales);
@@ -290,7 +290,7 @@
      */
     public static LocaleList getLocales() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getConfiguration().getLocales();
         } catch (RemoteException e) {
             // If something went wrong
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 72a40b7..dd8ef18 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -35,7 +35,6 @@
 import com.android.internal.content.PackageMonitor;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
@@ -245,7 +244,7 @@
         setProfileSwitchMessageId(intent.getContentUserHint());
 
         try {
-            mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+            mLaunchedFromUid = ActivityManager.getService().getLaunchedFromUid(
                     getActivityToken());
         } catch (RemoteException e) {
             mLaunchedFromUid = -1;
@@ -864,7 +863,7 @@
         } catch (RuntimeException e) {
             String launchedFromPackage;
             try {
-                launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
                         getActivityToken());
             } catch (RemoteException e2) {
                 launchedFromPackage = "??";
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 4e3c3fc..a3134b3b 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -29,7 +29,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
 import android.os.storage.StorageVolume;
@@ -53,7 +53,7 @@
 /**
  * Constants used internally between the PackageManager
  * and media container service transports.
- * Some utility methods to invoke MountService api.
+ * Some utility methods to invoke StorageManagerService api.
  */
 public class PackageHelper {
     public static final int RECOMMEND_INSTALL_INTERNAL = 1;
@@ -74,13 +74,13 @@
     public static final int APP_INSTALL_INTERNAL = 1;
     public static final int APP_INSTALL_EXTERNAL = 2;
 
-    public static IMountService getMountService() throws RemoteException {
+    public static IStorageManager getStorageManager() throws RemoteException {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
-            throw new RemoteException("Could not contact mount service");
+            Log.e(TAG, "Can't get storagemanager service");
+            throw new RemoteException("Could not contact storagemanager service");
         }
     }
 
@@ -89,23 +89,23 @@
         // Round up to nearest MB, plus another MB for filesystem overhead
         final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
         try {
-            IMountService mountService = getMountService();
+            IStorageManager storageManager = getStorageManager();
 
             if (localLOGV)
                 Log.i(TAG, "Size of container " + sizeMb + " MB");
 
-            int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
+            int rc = storageManager.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
                     isExternal);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.e(TAG, "Failed to create secure container " + cid);
                 return null;
             }
-            String cachePath = mountService.getSecureContainerPath(cid);
+            String cachePath = storageManager.getSecureContainerPath(cid);
             if (localLOGV) Log.i(TAG, "Created secure container " + cid +
                     " at " + cachePath);
                 return cachePath;
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         return null;
     }
@@ -114,13 +114,13 @@
         // Round up to nearest MB, plus another MB for filesystem overhead
         final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
         try {
-            IMountService mountService = getMountService();
-            int rc = mountService.resizeSecureContainer(cid, sizeMb, sdEncKey);
+            IStorageManager storageManager = getStorageManager();
+            int rc = storageManager.resizeSecureContainer(cid, sizeMb, sdEncKey);
             if (rc == StorageResultCode.OperationSucceeded) {
                 return true;
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         Log.e(TAG, "Failed to create secure container " + cid);
         return false;
@@ -132,35 +132,35 @@
 
     public static String mountSdDir(String cid, String key, int ownerUid, boolean readOnly) {
         try {
-            int rc = getMountService().mountSecureContainer(cid, key, ownerUid, readOnly);
+            int rc = getStorageManager().mountSecureContainer(cid, key, ownerUid, readOnly);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to mount container " + cid + " rc : " + rc);
                 return null;
             }
-            return getMountService().getSecureContainerPath(cid);
+            return getStorageManager().getSecureContainerPath(cid);
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         return null;
     }
 
    public static boolean unMountSdDir(String cid) {
     try {
-        int rc = getMountService().unmountSecureContainer(cid, true);
+        int rc = getStorageManager().unmountSecureContainer(cid, true);
         if (rc != StorageResultCode.OperationSucceeded) {
             Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
             return false;
         }
         return true;
     } catch (RemoteException e) {
-        Log.e(TAG, "MountService running?");
+        Log.e(TAG, "StorageManagerService running?");
     }
         return false;
    }
 
    public static boolean renameSdDir(String oldId, String newId) {
        try {
-           int rc = getMountService().renameSecureContainer(oldId, newId);
+           int rc = getStorageManager().renameSecureContainer(oldId, newId);
            if (rc != StorageResultCode.OperationSucceeded) {
                Log.e(TAG, "Failed to rename " + oldId + " to " +
                        newId + "with rc " + rc);
@@ -176,7 +176,7 @@
 
    public static String getSdDir(String cid) {
        try {
-            return getMountService().getSecureContainerPath(cid);
+            return getStorageManager().getSecureContainerPath(cid);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get container path for " + cid +
                 " with exception " + e);
@@ -186,7 +186,7 @@
 
    public static String getSdFilesystem(String cid) {
        try {
-            return getMountService().getSecureContainerFilesystemPath(cid);
+            return getStorageManager().getSecureContainerFilesystemPath(cid);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get container path for " + cid +
                 " with exception " + e);
@@ -196,7 +196,7 @@
 
     public static boolean finalizeSdDir(String cid) {
         try {
-            int rc = getMountService().finalizeSecureContainer(cid);
+            int rc = getStorageManager().finalizeSecureContainer(cid);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to finalize container " + cid);
                 return false;
@@ -212,7 +212,7 @@
     public static boolean destroySdDir(String cid) {
         try {
             if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid);
-            int rc = getMountService().destroySecureContainer(cid, true);
+            int rc = getStorageManager().destroySecureContainer(cid, true);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to destroy container " + cid);
                 return false;
@@ -227,7 +227,7 @@
 
     public static String[] getSecureContainerList() {
         try {
-            return getMountService().getSecureContainerList();
+            return getStorageManager().getSecureContainerList();
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get secure container list with exception" +
                     e);
@@ -237,7 +237,7 @@
 
    public static boolean isContainerMounted(String cid) {
        try {
-           return getMountService().isSecureContainerMounted(cid);
+           return getStorageManager().isSecureContainerMounted(cid);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to find out if container " + cid + " mounted");
        }
@@ -325,7 +325,7 @@
 
     public static boolean fixSdPermissions(String cid, int gid, String filename) {
         try {
-            int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename);
+            int rc = getStorageManager().fixPermissionsSecureContainer(cid, gid, filename);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to fixperms container " + cid);
                 return false;
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 80c55fb..7591488 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -27,6 +27,8 @@
             SystemProperties.getInt("ro.debuggable", 0) == 1;
     public static final int FACTORYTEST =
             SystemProperties.getInt("ro.factorytest", 0);
+    public static final boolean CONTROL_PRIVAPP_PERMISSIONS =
+            SystemProperties.getBoolean("ro.control_privapp_permissions", false);
 
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_LOW_RAM =
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index e57a224..304c31d 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.os;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
 import android.os.Build;
@@ -113,7 +113,7 @@
                 }
 
                 // Bring up crash dialog, wait for it to be dismissed
-                ActivityManagerNative.getDefault().handleApplicationCrash(
+                ActivityManager.getService().handleApplicationCrash(
                         mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
             } catch (Throwable t2) {
                 if (t2 instanceof DeadObjectException) {
@@ -379,7 +379,7 @@
      */
     public static void wtf(String tag, Throwable t, boolean system) {
         try {
-            if (ActivityManagerNative.getDefault().handleApplicationWtf(
+            if (ActivityManager.getService().handleApplicationWtf(
                     mApplicationObject, tag, system,
                     new ApplicationErrorReport.ParcelableCrashInfo(t))) {
                 // The Activity Manager has already written us off -- now exit.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 50621f4..2a004cfb 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -21,7 +21,7 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.SearchManager;
 import android.os.UserHandle;
 
@@ -3715,9 +3715,9 @@
     }
 
     public static void sendCloseSystemWindows(Context context, String reason) {
-        if (ActivityManagerNative.isSystemReady()) {
+        if (ActivityManager.isSystemReady()) {
             try {
-                ActivityManagerNative.getDefault().closeSystemDialogs(reason);
+                ActivityManager.getService().closeSystemDialogs(reason);
             } catch (RemoteException e) {
             }
         }
diff --git a/core/java/com/android/internal/policy/PipMotionHelper.java b/core/java/com/android/internal/policy/PipMotionHelper.java
index 0543442..944cd32 100644
--- a/core/java/com/android/internal/policy/PipMotionHelper.java
+++ b/core/java/com/android/internal/policy/PipMotionHelper.java
@@ -18,7 +18,7 @@
 
 import android.animation.RectEvaluator;
 import android.animation.ValueAnimator;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -51,7 +51,7 @@
     public void resizeToBounds(Rect toBounds) {
         mHandler.post(() -> {
             if (mActivityManager == null) {
-                mActivityManager = ActivityManagerNative.getDefault();
+                mActivityManager = ActivityManager.getService();
             }
             try {
                 mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */);
diff --git a/core/java/com/android/internal/util/ToBooleanFunction.java b/core/java/com/android/internal/util/ToBooleanFunction.java
new file mode 100644
index 0000000..83866c2
--- /dev/null
+++ b/core/java/com/android/internal/util/ToBooleanFunction.java
@@ -0,0 +1,43 @@
+/*
+ * 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.internal.util;
+
+import java.util.function.Function;
+
+/**
+ * Represents a function that produces an boolean-valued result.  This is the
+ * {@code boolean}-producing primitive specialization for {@link Function}.
+ *
+ * <p>This is a <a href="package-summary.html">functional interface</a>
+ * whose functional method is {@link #apply(Object)}.
+ *
+ * @param <T> the type of the input to the function
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToBooleanFunction<T> {
+
+    /**
+     * Applies this function to the given argument.
+     *
+     * @param value the function argument
+     * @return the function result
+     */
+    boolean apply(T value);
+}
diff --git a/core/java/com/android/internal/view/OneShotPreDrawListener.java b/core/java/com/android/internal/view/OneShotPreDrawListener.java
new file mode 100644
index 0000000..98ffd82
--- /dev/null
+++ b/core/java/com/android/internal/view/OneShotPreDrawListener.java
@@ -0,0 +1,89 @@
+/*
+ * 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.internal.view;
+
+import android.view.View;
+import android.view.ViewTreeObserver;
+
+/**
+ * An OnPreDrawListener that will remove itself after one OnPreDraw call. Typical
+ * usage is:
+ * <pre><code>
+ *     OneShotPreDrawListener.add(view, () -> { view.doSomething(); })
+ * </code></pre>
+ * <p>
+ * The onPreDraw always returns true.
+ * <p>
+ * The listener will also remove itself from the ViewTreeObserver when the view
+ * is detached from the view hierarchy. In that case, the Runnable will never be
+ * executed.
+ */
+public class OneShotPreDrawListener implements ViewTreeObserver.OnPreDrawListener,
+        View.OnAttachStateChangeListener {
+    private final View mView;
+    private ViewTreeObserver mViewTreeObserver;
+    private final Runnable mRunnable;
+
+    private OneShotPreDrawListener(View view, Runnable runnable) {
+        mView = view;
+        mViewTreeObserver = view.getViewTreeObserver();
+        mRunnable = runnable;
+    }
+
+    /**
+     * Creates a OneShotPreDrawListener and adds it to view's ViewTreeObserver.
+     * @param view The view whose ViewTreeObserver the OnPreDrawListener should listen.
+     * @param runnable The Runnable to execute in the OnPreDraw (once)
+     * @return The added OneShotPreDrawListener. It can be removed prior to
+     * the onPreDraw by calling {@link #removeListener()}.
+     */
+    public static OneShotPreDrawListener add(View view, Runnable runnable) {
+        OneShotPreDrawListener listener = new OneShotPreDrawListener(view, runnable);
+        view.getViewTreeObserver().addOnPreDrawListener(listener);
+        view.addOnAttachStateChangeListener(listener);
+        return listener;
+    }
+
+    @Override
+    public boolean onPreDraw() {
+        removeListener();
+        mRunnable.run();
+        return true;
+    }
+
+    /**
+     * Removes the listener from the ViewTreeObserver. This is useful to call if the
+     * callback should be removed prior to {@link #onPreDraw()}.
+     */
+    public void removeListener() {
+        if (mViewTreeObserver.isAlive()) {
+            mViewTreeObserver.removeOnPreDrawListener(this);
+        } else {
+            mView.getViewTreeObserver().removeOnPreDrawListener(this);
+        }
+        mView.removeOnAttachStateChangeListener(this);
+    }
+
+    @Override
+    public void onViewAttachedToWindow(View v) {
+        mViewTreeObserver = v.getViewTreeObserver();
+    }
+
+    @Override
+    public void onViewDetachedFromWindow(View v) {
+        removeListener();
+    }
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 71252fb..b0bc81b 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -36,7 +36,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -682,10 +682,10 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
             Log.d(TAG, "Setting owner info");
-            mountService.setField(StorageManager.OWNER_INFO_KEY, ownerInfo);
+            storageManager.setField(StorageManager.OWNER_INFO_KEY, ownerInfo);
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing user info", e);
         }
@@ -746,9 +746,9 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... dummy) {
-                IMountService mountService = IMountService.Stub.asInterface(service);
+                IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
                 try {
-                    mountService.changeEncryptionPassword(type, password);
+                    storageManager.changeEncryptionPassword(type, password);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error changing encryption password", e);
                 }
@@ -1122,9 +1122,9 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
-            mountService.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0");
+            storageManager.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0");
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing pattern visible state", e);
         }
@@ -1145,9 +1145,9 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
-            mountService.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0");
+            storageManager.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0");
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing password visible state", e);
         }
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 429131b..168da5f 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -25,6 +25,7 @@
 import android.os.Environment;
 import android.os.Process;
 import android.os.storage.StorageManager;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -129,6 +130,9 @@
     final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
             new ArrayMap<>();
 
+
+    final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
+
     public static SystemConfig getInstance() {
         synchronized (SystemConfig.class) {
             if (sInstance == null) {
@@ -194,6 +198,10 @@
         return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
     }
 
+    public ArraySet<String> getPrivAppPermissions(String packageName) {
+        return mPrivAppPermissions.get(packageName);
+    }
+
     SystemConfig() {
         // Read configuration from system
         readPermissions(Environment.buildPath(
@@ -507,6 +515,8 @@
                         associatedPkgs.add(pkgname);
                     }
                     XmlUtils.skipCurrentTag(parser);
+                } else if ("privapp-permissions".equals(name) && allowAppConfigs) {
+                    readPrivAppPermissions(parser);
                 } else {
                     XmlUtils.skipCurrentTag(parser);
                     continue;
@@ -584,4 +594,32 @@
             XmlUtils.skipCurrentTag(parser);
         }
     }
+
+    void readPrivAppPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
+        String packageName = parser.getAttributeValue(null, "package");
+        if (TextUtils.isEmpty(packageName)) {
+            Slog.w(TAG, "package is required for <privapp-permissions> in "
+                    + parser.getPositionDescription());
+            return;
+        }
+
+        ArraySet<String> permissions = mPrivAppPermissions.get(packageName);
+        if (permissions == null) {
+            permissions = new ArraySet<>();
+        }
+        int depth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, depth)) {
+            String name = parser.getName();
+            if ("permission".equals(name)) {
+                String permName = parser.getAttributeValue(null, "name");
+                if (TextUtils.isEmpty(permName)) {
+                    Slog.w(TAG, "name is required for <permission> in "
+                            + parser.getPositionDescription());
+                    continue;
+                }
+                permissions.add(permName);
+            }
+        }
+        mPrivAppPermissions.put(packageName, permissions);
+    }
 }
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index e10fdbd..3456839 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -915,6 +915,16 @@
         paint->setLetterSpacing(letterSpacing);
     }
 
+    static jfloat getWordSpacing(jlong paintHandle) {
+        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        return paint->getWordSpacing();
+    }
+
+    static void setWordSpacing(jlong paintHandle, jfloat wordSpacing) {
+        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        paint->setWordSpacing(wordSpacing);
+    }
+
     static jint getHyphenEdit(jlong paintHandle, jint hyphen) {
         Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         return paint->getHyphenEdit();
@@ -1043,6 +1053,8 @@
     {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX},
     {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
     {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
+    {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing},
+    {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing},
     {"nGetHyphenEdit", "(J)I", (void*) PaintGlue::getHyphenEdit},
     {"nSetHyphenEdit", "(JI)V", (void*) PaintGlue::setHyphenEdit},
     {"nAscent","(JJ)F", (void*) PaintGlue::ascent},
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 0de46e6..7e417b4 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -93,7 +93,7 @@
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+        android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
     }
 
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 7fc79d2..c920b8d 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -70,7 +70,7 @@
 
 static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
     Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
-    return Typeface::setDefault(face);
+    Typeface::setDefault(face);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android_os_HwBlob.h b/core/jni/android_os_HwBlob.h
index 6bd82e9..0920488 100644
--- a/core/jni/android_os_HwBlob.h
+++ b/core/jni/android_os_HwBlob.h
@@ -20,6 +20,7 @@
 #include <android-base/macros.h>
 #include <jni.h>
 #include <hidl/HidlSupport.h>
+#include <hwbinder/Parcel.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index f909580..a10d807 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -26,6 +26,7 @@
 
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
 #include <nativehelper/ScopedLocalRef.h>
 
@@ -383,7 +384,7 @@
     hardware::Parcel *parcel =
         JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
-    status_t err = status.writeToParcel(parcel);
+    status_t err = ::android::hardware::writeToParcel(status, parcel);
     signalExceptionForError(env, err);
 }
 
@@ -394,7 +395,7 @@
         JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
     Status status;
-    status_t err = status.readFromParcel(*parcel);
+    status_t err = ::android::hardware::readFromParcel(&status, *parcel);
     signalExceptionForError(env, err);
 }
 
@@ -425,8 +426,8 @@
     status_t err = parcel->writeBuffer(s, sizeof(*s), &parentHandle);
 
     if (err == OK) {
-        err = s->writeEmbeddedToParcel(
-                parcel, parentHandle, 0 /* parentOffset */);
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *s, parcel, parentHandle, 0 /* parentOffset */);
     }
 
     signalExceptionForError(env, err);
@@ -453,7 +454,8 @@
     if (err == OK) {                                                           \
         size_t childHandle;                                                    \
                                                                                \
-        err = vec->writeEmbeddedToParcel(                                      \
+        err = ::android::hardware::writeEmbeddedToParcel(                      \
+                *vec,                                                          \
                 parcel,                                                        \
                 parentHandle,                                                  \
                 0 /* parentOffset */,                                          \
@@ -508,7 +510,8 @@
     if (err == OK) {
         size_t childHandle;
 
-        err = vec->writeEmbeddedToParcel(
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *vec,
                 parcel,
                 parentHandle,
                 0 /* parentOffset */,
@@ -568,7 +571,8 @@
         return NULL;
     }
 
-    status_t err = const_cast<hidl_string *>(s)->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+            const_cast<hidl_string *>(s),
             *parcel, parentHandle, 0 /* parentOffset */);
 
     if (err != OK) {
@@ -597,8 +601,8 @@
                                                                                \
     size_t childHandle;                                                        \
                                                                                \
-    status_t err = const_cast<hidl_vec<Type> *>(vec)                           \
-        ->readEmbeddedFromParcel(                                              \
+    status_t err = ::android::hardware::readEmbeddedFromParcel(                \
+                const_cast<hidl_vec<Type> *>(vec),                             \
                 *parcel,                                                       \
                 parentHandle,                                                  \
                 0 /* parentOffset */,                                          \
@@ -639,8 +643,8 @@
 
     size_t childHandle;
 
-    status_t err = const_cast<hidl_vec<bool> *>(vec)
-        ->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+                const_cast<hidl_vec<bool> *>(vec),
                 *parcel,
                 parentHandle,
                 0 /* parentOffset */,
@@ -701,12 +705,13 @@
     }
 
     size_t childHandle;
-    status_t err = const_cast<string_vec *>(vec)->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+            const_cast<string_vec *>(vec),
             *parcel, parentHandle, 0 /* parentOffset */, &childHandle);
 
     for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
-        err = const_cast<hidl_vec<hidl_string> *>(vec)
-            ->readEmbeddedFromParcel(
+        err = android::hardware::readEmbeddedFromParcel(
+                    const_cast<hidl_vec<hidl_string> *>(vec),
                     *parcel,
                     childHandle,
                     i * sizeof(hidl_string),
@@ -760,14 +765,16 @@
 
     if (err == OK) {
         size_t childHandle;
-        err = vec->writeEmbeddedToParcel(
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *vec,
                 parcel,
                 parentHandle,
                 0 /* parentOffset */,
                 &childHandle);
 
         for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
-            err = (*vec)[i].writeEmbeddedToParcel(
+            err = ::android::hardware::writeEmbeddedToParcel(
+                    (*vec)[i],
                     parcel,
                     childHandle,
                     i * sizeof(hidl_string));
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
index 1743731..b9376d8 100644
--- a/core/jni/android_view_GraphicBuffer.cpp
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -111,7 +111,7 @@
     }
 
     status_t error;
-    sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error));
+    sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, 1, usage, &error));
     if (buffer == NULL) {
         if (kDebugGraphicBuffer) {
             ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index f88de51..dd2a7a9 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -124,10 +124,6 @@
     renderNode->decStrong(0);
 }
 
-static void android_view_RenderNode_finalize(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
-    releaseRenderNode(reinterpret_cast<RenderNode*>(renderNodePtr));
-}
-
 static jlong android_view_RenderNode_getNativeFinalizer(JNIEnv* env,
         jobject clazz) {
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseRenderNode));
@@ -654,7 +650,6 @@
 // Regular JNI
 // ----------------------------------------------------------------------------
     { "nCreate",               "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
-    { "nFinalize",             "(J)V",   (void*) android_view_RenderNode_finalize },
     { "nGetNativeFinalizer",   "()J",    (void*) android_view_RenderNode_getNativeFinalizer },
     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
     { "nOutput",               "(J)V",    (void*) android_view_RenderNode_output },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0f7b5a5..fbad143 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -501,6 +501,10 @@
 
     <protected-broadcast android:name="android.intent.action.DEVICE_LOCKED_CHANGED" />
 
+    <!-- Added in O -->
+    <!-- TODO: temporary broadcast used by AutoFillManagerServiceImpl; will be removed -->
+    <protected-broadcast android:name="com.android.internal.autofill.action.REQUEST_AUTOFILL" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -717,6 +721,7 @@
         android:priority="400" />
 
     <!-- Allows an app to access precise location.
+         Alternatively, you might want {@link #ACCESS_COARSE_LOCATION}.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
@@ -726,6 +731,7 @@
         android:protectionLevel="dangerous|ephemeral" />
 
     <!-- Allows an app to access approximate location.
+         Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
diff --git a/core/res/res/drawable/watch_switch_track_material.xml b/core/res/res/color/watch_switch_track_color_material.xml
similarity index 73%
rename from core/res/res/drawable/watch_switch_track_material.xml
rename to core/res/res/color/watch_switch_track_color_material.xml
index 79e92a3..c7dc5d3 100644
--- a/core/res/res/drawable/watch_switch_track_material.xml
+++ b/core/res/res/color/watch_switch_track_color_material.xml
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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.
@@ -12,10 +15,8 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false">
-        <bitmap android:alpha="0.1" android:src="@drawable/watch_switch_track_mtrl_alpha" />
-    </item>
-    <item>
-        <bitmap android:alpha="0.2" android:src="@drawable/watch_switch_track_mtrl_alpha" />
-    </item>
-</selector>
+    <item android:state_enabled="false"
+          android:alpha="?attr/disabledAlpha"
+          android:color="?android:colorPrimary" />
+    <item android:color="?android:colorPrimary" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-hdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-hdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-hdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-xhdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-xhdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-xxhdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/layout-watch/preference_widget_switch.xml b/core/res/res/layout-watch/preference_widget_switch.xml
index 5881cf0..a1a845a 100644
--- a/core/res/res/layout-watch/preference_widget_switch.xml
+++ b/core/res/res/layout-watch/preference_widget_switch.xml
@@ -24,7 +24,8 @@
     android:thumb="@drawable/watch_switch_thumb_material_anim"
     android:thumbTint="@color/watch_switch_thumb_color_material"
     android:thumbTintMode="multiply"
-    android:track="@drawable/watch_switch_track_material"
+    android:track="@drawable/watch_switch_track_mtrl"
+    android:trackTint="@color/watch_switch_track_color_material"
     android:focusable="false"
     android:clickable="false"
     android:background="@null" />
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c63ec41..522efc5 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -596,7 +596,7 @@
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax de casa"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"Cercapersones"</string>
     <string name="phoneTypeOther" msgid="1544425847868765990">"Altres"</string>
-    <string name="phoneTypeCallback" msgid="2712175203065678206">"Torna la trucada"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Devolució de trucada"</string>
     <string name="phoneTypeCar" msgid="8738360689616716982">"Cotxe"</string>
     <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Telèfon d\'empresa"</string>
     <string name="phoneTypeIsdn" msgid="8022453193171370337">"XDSI"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 77b43b1..fa03897 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -258,7 +258,7 @@
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"hacer fotos y grabar vídeos"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
-    <string name="permgroupdesc_phone" msgid="6234224354060641055">"hacer y administrar llamadas de teléfono"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"hacer y administrar llamadas telefónicas"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Sensores corporales"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"acceder a datos de sensores de tus constantes vitales"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de la ventana"</string>
diff --git a/core/res/res/values-watch/colors_material.xml b/core/res/res/values-watch/colors_material.xml
index 1456976..72f589b 100644
--- a/core/res/res/values-watch/colors_material.xml
+++ b/core/res/res/values-watch/colors_material.xml
@@ -22,7 +22,7 @@
     <color name="accent_material_dark">#5E97F6</color>
     <color name="accent_material_50">#93B7F5</color>
 
-    <color name="primary_material_dark">#4D4D4D</color>
+    <color name="primary_material_dark">#33ffffff</color>
 
     <color name="button_material_dark">#ff919699</color>
 </resources>
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index 9e45d09..d7b38e8 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -19,8 +19,7 @@
 LOCAL_SRC_FILES := \
     com_android_frameworks_coretests_JNITest.cpp
 
-LOCAL_SHARED_LIBRARIES := \
-    libnativehelper
+LOCAL_SDK_VERSION := 16
 
 LOCAL_CFLAGS += -Wall -Werror
 
diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
index 8d91192..0cf3a84 100644
--- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
+++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
@@ -14,41 +14,23 @@
  * limitations under the License.
  */
 
-#include "nativehelper/JNIHelp.h"
+#include <jni.h>
 
-namespace android {
-
-static jint checkFunction(JNIEnv*, jclass) {
+extern "C" JNIEXPORT
+jint JNICALL Java_com_android_frameworks_coretests_JNITests_checkFunction(JNIEnv*, jclass) {
     return 1;
 }
 
-static const JNINativeMethod sMethods[] = {
-    /* name, signature, funcPtr */
-    { "checkFunction", "()I", (void*) checkFunction },
-};
-
-int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods,
-            NELEM(sMethods));
-}
-
-}
-
 /*
  * JNI Initialization
  */
 jint JNI_OnLoad(JavaVM *jvm, void */* reserved */) {
     JNIEnv *e;
-    int status;
 
     // Check JNI version
     if (jvm->GetEnv((void **) &e, JNI_VERSION_1_6)) {
         return JNI_ERR;
     }
 
-    if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) {
-        return JNI_ERR;
-    }
-
     return JNI_VERSION_1_6;
 }
diff --git a/core/tests/coretests/src/android/app/activity/BroadcastTest.java b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
index f28ba7e..e9e8bfc 100644
--- a/core/tests/coretests/src/android/app/activity/BroadcastTest.java
+++ b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
@@ -17,7 +17,7 @@
 package android.app.activity;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -304,10 +304,10 @@
     public void testSetSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.getDefault().unbroadcastIntent(null, intent,
+        ActivityManager.getService().unbroadcastIntent(null, intent,
                 UserHandle.myUserId());
 
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         addIntermediate("finished-broadcast");
 
         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
@@ -319,9 +319,9 @@
     public void testClearSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
-        ActivityManagerNative.getDefault().unbroadcastIntent(
+        ActivityManager.getService().unbroadcastIntent(
                 null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null),
                 UserHandle.myUserId());
         addIntermediate("finished-unbroadcast");
@@ -334,10 +334,10 @@
     public void testReplaceSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         intent.putExtra("test", LaunchpadActivity.DATA_2);
 
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         addIntermediate("finished-broadcast");
 
         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
@@ -351,7 +351,7 @@
     public void testReceiveSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY1);
     }
@@ -361,10 +361,10 @@
     public void testReceive2Sticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         intent = new Intent(LaunchpadActivity.BROADCAST_STICKY2, null);
         intent.putExtra("test", LaunchpadActivity.DATA_2);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY2);
     }
diff --git a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
index 06c495e..5af2667 100644
--- a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
@@ -21,7 +21,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -31,14 +31,14 @@
     private static final boolean localLOGV = true;
     public static final String TAG = "PackageHelperTests";
     protected final String PREFIX = "android.content.pm";
-    private IMountService mMs;
+    private IStorageManager mSm;
     private String fullId;
     private String fullId2;
 
-    private IMountService getMs() {
+    private IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
             Log.e(TAG, "Can't get mount service");
         }
@@ -47,12 +47,12 @@
 
     private void cleanupContainers() throws RemoteException {
         Log.d(TAG,"cleanUp");
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
         for (int i = 0; i < containers.length; i++) {
             if (containers[i].startsWith(PREFIX)) {
                 Log.d(TAG,"cleaing up "+containers[i]);
-                ms.destroySecureContainer(containers[i], true);
+                sm.destroySecureContainer(containers[i], true);
             }
         }
     }
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index b5f0617..a15cba0 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -46,7 +46,7 @@
 import android.os.StatFs;
 import android.os.SystemClock;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
@@ -1149,12 +1149,12 @@
         }
     }
 
-    IMountService getMs() {
+    IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
+            Log.e(TAG, "Can't get storagemanager service");
         }
         return null;
     }
@@ -1185,7 +1185,7 @@
         try {
             // Wait on observer
             synchronized (observer) {
-                int ret = getMs().mountVolume(path);
+                int ret = getSm().mountVolume(path);
                 if (ret != StorageResultCode.OperationSucceeded) {
                     throw new Exception("Could not mount the media");
                 }
@@ -1224,7 +1224,7 @@
         try {
             // Wait on observer
             synchronized (observer) {
-                getMs().unmountVolume(path, true, false);
+                getSm().unmountVolume(path, true, false);
                 long waitTime = 0;
                 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
                     observer.wait(WAIT_TIME_INCR);
@@ -2754,7 +2754,7 @@
         }
     }
 
-    /* This test creates a stale container via MountService and then installs
+    /* This test creates a stale container via StorageManagerService and then installs
      * a package and verifies that the stale container is cleaned up and install
      * is successful.
      * Please note that this test is very closely tied to the framework's
diff --git a/core/tests/coretests/src/android/os/storage/AsecTests.java b/core/tests/coretests/src/android/os/storage/AsecTests.java
index 4f724fe..e9a810d 100644
--- a/core/tests/coretests/src/android/os/storage/AsecTests.java
+++ b/core/tests/coretests/src/android/os/storage/AsecTests.java
@@ -50,21 +50,21 @@
     }
 
     private void cleanupContainers() throws RemoteException {
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
 
         for (int i = 0; i < containers.length; i++) {
             if (containers[i].startsWith(SECURE_CONTAINER_PREFIX)) {
                 if (localLOGV)
                     Log.i(TAG, "Cleaning: " + containers[i]);
-                ms.destroySecureContainer(containers[i], true);
+                sm.destroySecureContainer(containers[i], true);
             }
         }
     }
 
     private boolean containerExists(String localId) throws RemoteException {
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
         for (int i = 0; i < containers.length; i++) {
@@ -80,8 +80,8 @@
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(),
+        IStorageManager sm = getSm();
+        return sm.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(),
                 isExternal);
     }
 
@@ -89,8 +89,8 @@
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.mountSecureContainer(fullId, key, android.os.Process.myUid(), true);
+        IStorageManager sm = getSm();
+        return sm.mountSecureContainer(fullId, key, android.os.Process.myUid(), true);
     }
 
     private int renameContainer(String localId1, String localId2) throws Exception {
@@ -98,47 +98,47 @@
         String fullId1 = SECURE_CONTAINER_PREFIX + localId1;
         String fullId2 = SECURE_CONTAINER_PREFIX + localId2;
 
-        IMountService ms = getMs();
-        return ms.renameSecureContainer(fullId1, fullId2);
+        IStorageManager sm = getSm();
+        return sm.renameSecureContainer(fullId1, fullId2);
     }
 
     private int unmountContainer(String localId, boolean force) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.unmountSecureContainer(fullId, force);
+        IStorageManager sm = getSm();
+        return sm.unmountSecureContainer(fullId, force);
     }
 
     private int destroyContainer(String localId, boolean force) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.destroySecureContainer(fullId, force);
+        IStorageManager sm = getSm();
+        return sm.destroySecureContainer(fullId, force);
     }
 
     private boolean isContainerMounted(String localId) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.isSecureContainerMounted(fullId);
+        IStorageManager sm = getSm();
+        return sm.isSecureContainerMounted(fullId);
     }
 
-    private IMountService getMs() {
+    private IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
+            Log.e(TAG, "Can't get storagemanager service");
         }
         return null;
     }
 
     private boolean isMediaMounted() throws Exception {
         String mPath = Environment.getExternalStorageDirectory().toString();
-        String state = getMs().getVolumeState(mPath);
+        String state = getSm().getVolumeState(mPath);
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 
@@ -385,11 +385,11 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testUnmountBusyContainer", 4, "none", FS_FAT, true));
 
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX
                 + "testUnmountBusyContainer");
 
         File f = new File(path, "reference");
@@ -408,12 +408,12 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
 
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testDestroyBusyContainer", 4, "none", FS_FAT, true));
 
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX
                 + "testDestroyBusyContainer");
 
         File f = new File(path, "reference");
@@ -480,10 +480,10 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testContainerSize", 1, "none", FS_FAT, true));
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize");
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize");
 
         byte[] buf = new byte[4096];
         File f = new File(path, "reference");
@@ -495,9 +495,9 @@
     }
 
     public void testGetSecureContainerPath_NonExistPath_Failure() throws Exception {
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertNull("Getting the path for an invalid container should return null",
-                ms.getSecureContainerPath("jparks.broke.it"));
+                sm.getSecureContainerPath("jparks.broke.it"));
     }
 
     /*------------ Tests for unmounting volume ---*/
@@ -506,7 +506,7 @@
 
     boolean getMediaState() throws Exception {
         String mPath = Environment.getExternalStorageDirectory().toString();
-        String state = getMs().getVolumeState(mPath);
+        String state = getSm().getVolumeState(mPath);
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 
@@ -520,7 +520,7 @@
         }
 
         String mPath = Environment.getExternalStorageDirectory().toString();
-        int ret = getMs().mountVolume(mPath);
+        int ret = getSm().mountVolume(mPath);
         return ret == StorageResultCode.OperationSucceeded;
     }
 
@@ -567,7 +567,7 @@
         try {
             // Wait on observer
             synchronized(observer) {
-                getMs().unmountVolume(path, false, false);
+                getSm().unmountVolume(path, false, false);
                 long waitTime = 0;
                 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                     observer.wait(WAIT_TIME_INCR);
@@ -634,7 +634,7 @@
             // Wait on observer
             synchronized(observer) {
                 for (int i = 0; i < 5; i++) {
-                    getMs().unmountVolume(path, false, false);
+                    getSm().unmountVolume(path, false, false);
                 }
                 long waitTime = 0;
                 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
@@ -661,7 +661,7 @@
         }
     }
 
-    class ShutdownObserver extends  IMountShutdownObserver.Stub{
+    class ShutdownObserver extends  IStorageShutdownObserver.Stub{
         private boolean doneFlag = false;
         int statusCode;
 
@@ -683,10 +683,10 @@
     }
 
     void invokeShutdown() throws Exception {
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         ShutdownObserver observer = new ShutdownObserver();
         synchronized (observer) {
-            ms.shutdown(observer);
+            sm.shutdown(observer);
         }
     }
 
@@ -731,12 +731,12 @@
             if (!getMediaState()) {
                 mountMedia();
             }
-            IMountService ms = getMs();
+            IStorageManager sm = getSm();
             ShutdownObserver observer = new ShutdownObserver();
             synchronized (observer) {
-                ms.shutdown(observer);
+                sm.shutdown(observer);
                 for (int i = 0; i < 4; i++) {
-                    ms.shutdown(null);
+                    sm.shutdown(null);
                 }
             }
         } finally {
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index 134ac0c..6718259 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -18,30 +18,17 @@
 
 ########################
 include $(CLEAR_VARS)
-
 LOCAL_MODULE := platform.xml
-
 LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
 include $(BUILD_PREBUILT)
 
 ########################
-#include $(CLEAR_VARS)
+include $(CLEAR_VARS)
+LOCAL_MODULE := privapp-permissions-platform.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
 
-#LOCAL_MODULE := required_hardware.xml
-
-#LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-#LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-#LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-#include $(BUILD_PREBUILT)
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
new file mode 100644
index 0000000..3fc7914
--- /dev/null
+++ b/data/etc/privapp-permissions-platform.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+
+<!--
+This XML file declares which signature|privileged permissions should be granted to privileged
+applications that come with the platform
+-->
+<permissions>
+    <privapp-permissions package="com.android.backupconfirm">
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.CRYPT_KEEPER"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.cellbroadcastreceiver">
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.contacts">
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.defcontainer">
+        <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.dialer">
+        <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
+        <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+        <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.emergency">
+        <permission name="android.permission.MANAGE_USERS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.externalstorage">
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.launcher">
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.location.fused">
+        <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.managedprovisioning">
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CRYPT_KEEPER"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.SET_TIME_ZONE"/>
+        <permission name="android.permission.SHUTDOWN"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.mms.service">
+        <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.mtp">
+        <permission name="android.permission.MANAGE_USB"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.musicfx">
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.packageinstaller">
+        <permission name="android.permission.CLEAR_APP_CACHE"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.phone">
+        <permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
+        <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
+        <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+        <permission name="android.permission.SEND_RESPOND_VIA_MESSAGE"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.SET_TIME_ZONE"/>
+        <permission name="android.permission.SHUTDOWN"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+        <permission name="android.permission.UPDATE_LOCK"/>
+        <permission name="android.permission.WRITE_APN_SETTINGS"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+        <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.calendar">
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.contacts">
+        <permission name="android.permission.BIND_DIRECTORY_SEARCH"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.downloads">
+        <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
+        <permission name="android.permission.CLEAR_APP_CACHE"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.MODIFY_NETWORK_ACCOUNTING"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.media">
+        <permission name="android.permission.ACCESS_MTP"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.telephony">
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.provision">
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.server.telecom">
+        <permission name="android.permission.BIND_CONNECTION_SERVICE"/>
+        <permission name="android.permission.BIND_INCALL_SERVICE"/>
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.settings">
+        <permission name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
+        <permission name="android.permission.ACCESS_NOTIFICATIONS"/>
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.FORCE_STOP_PACKAGES"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MANAGE_FINGERPRINT"/>
+        <permission name="android.permission.MANAGE_USB"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.MOVE_PACKAGE"/>
+        <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
+        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+        <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
+        <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.TETHER_PRIVILEGED"/>
+        <permission name="android.permission.USER_ACTIVITY"/>
+        <permission name="android.permission.WRITE_APN_SETTINGS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.sharedstoragebackup">
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.shell">
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.DELETE_CACHE_FILES"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.FORCE_STOP_PACKAGES"/>
+        <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_ACTIVITY_STACKS"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.MOVE_PACKAGE"/>
+        <permission name="android.permission.READ_FRAME_BUFFER"/>
+        <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
+        <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
+        <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+        <permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/>
+        <permission name="android.permission.SET_ALWAYS_FINISH"/>
+        <permission name="android.permission.SET_ANIMATION_SCALE"/>
+        <permission name="android.permission.SET_DEBUG_APP"/>
+        <permission name="android.permission.SET_PROCESS_LIMIT"/>
+        <permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.statementservice">
+        <permission name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.storagemanager">
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.systemui">
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CONTROL_VPN"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_ACTIVITY_STACKS"/>
+        <permission name="android.permission.MANAGE_USB"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
+        <permission name="android.permission.READ_DREAM_STATE"/>
+        <permission name="android.permission.READ_FRAME_BUFFER"/>
+        <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
+        <permission name="android.permission.START_TASKS_FROM_RECENTS"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+        <permission name="android.permission.TETHER_PRIVILEGED"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.WRITE_DREAM_STATE"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.vpndialogs">
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CONTROL_VPN"/>
+    </privapp-permissions>
+
+</permissions>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 79c63ee..e628cf8 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1241,6 +1241,11 @@
      * #getAllocationByteCount()}.</p>
      */
     public final int getByteCount() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getByteCount() on a recycle()'d bitmap! "
+                    + "This is undefined behavior!");
+            return 0;
+        }
         // int result permits bitmaps up to 46,340 x 46,340
         return getRowBytes() * getHeight();
     }
@@ -1260,6 +1265,11 @@
      * @see #reconfigure(int, int, Config)
      */
     public final int getAllocationByteCount() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getAllocationByteCount() on a recycle()'d bitmap! "
+                    + "This is undefined behavior!");
+            return 0;
+        }
         return nativeGetAllocationByteCount(mNativePtr);
     }
 
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 98d45dc..554e5d2 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1442,6 +1442,28 @@
     }
 
     /**
+     * Return the paint's word-spacing for text. The default value is 0.
+     *
+     * @return the paint's word-spacing for drawing text.
+     * @hide
+     */
+    public float getWordSpacing() {
+        return nGetWordSpacing(mNativePaint);
+    }
+
+    /**
+     * Set the paint's word-spacing for text. The default value is 0.
+     * The value is in pixels (note the units are not the same as for
+     * letter-spacing).
+     *
+     * @param wordSpacing set the paint's word-spacing for drawing text.
+     * @hide
+     */
+    public void setWordSpacing(float wordSpacing) {
+        nSetWordSpacing(mNativePaint, wordSpacing);
+    }
+
+    /**
      * Returns the font feature settings. The format is the same as the CSS
      * font-feature-settings attribute:
      * <a href="https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop">
@@ -2711,6 +2733,10 @@
     @CriticalNative
     private static native void nSetLetterSpacing(long paintPtr, float letterSpacing);
     @CriticalNative
+    private static native float nGetWordSpacing(long paintPtr);
+    @CriticalNative
+    private static native void nSetWordSpacing(long paintPtr, float wordSpacing);
+    @CriticalNative
     private static native int nGetHyphenEdit(long paintPtr);
     @CriticalNative
     private static native void nSetHyphenEdit(long paintPtr, int hyphen);
diff --git a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java b/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
index 6763dd1..318bfb6 100644
--- a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
@@ -218,4 +218,13 @@
             assertEquals(width, p.measureText(bidiText), 1.0f);
         }
     }
+
+    public void testSetGetWordSpacing() {
+        Paint p = new Paint();
+        assertEquals(0.0f, p.getWordSpacing());  // The default value should be 0.
+        p.setWordSpacing(1.0f);
+        assertEquals(1.0f, p.getWordSpacing());
+        p.setWordSpacing(-2.0f);
+        assertEquals(-2.0f, p.getWordSpacing());
+    }
 }
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 5e59a64..e566b9d 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -414,6 +414,9 @@
         if (alias == null) {
             throw new NullPointerException("alias == null");
         }
+        if (context == null) {
+            throw new NullPointerException("context == null");
+        }
 
         final String keyId;
         try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 4722050..fdf4d52 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -24,6 +24,7 @@
     pipeline/skia/ReorderBarrierDrawables.cpp \
     pipeline/skia/SkiaDisplayList.cpp \
     pipeline/skia/SkiaOpenGLPipeline.cpp \
+    pipeline/skia/SkiaOpenGLReadback.cpp \
     pipeline/skia/SkiaPipeline.cpp \
     pipeline/skia/SkiaProfileRenderer.cpp \
     pipeline/skia/SkiaRecordingCanvas.cpp \
@@ -84,6 +85,7 @@
     LayerUpdateQueue.cpp \
     Matrix.cpp \
     OpDumper.cpp \
+    OpenGLReadback.cpp \
     Patch.cpp \
     PatchCache.cpp \
     PathCache.cpp \
@@ -96,7 +98,6 @@
     Properties.cpp \
     PropertyValuesAnimatorSet.cpp \
     PropertyValuesHolder.cpp \
-    Readback.cpp \
     RecordingCanvas.cpp \
     RenderBufferCache.cpp \
     RenderNode.cpp \
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/OpenGLReadback.cpp
similarity index 82%
rename from libs/hwui/Readback.cpp
rename to libs/hwui/OpenGLReadback.cpp
index 1645218..da6d994 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Readback.h"
+#include "OpenGLReadback.h"
 
 #include "Caches.h"
 #include "Image.h"
@@ -31,8 +31,69 @@
 namespace android {
 namespace uirenderer {
 
-static CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
-        Texture& sourceTexture, Matrix4& texTransform, const Rect& srcRect,
+CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
+        SkBitmap* bitmap) {
+    ATRACE_CALL();
+    mRenderThread.eglManager().initialize();
+
+    // Setup the source
+    sp<GraphicBuffer> sourceBuffer;
+    sp<Fence> sourceFence;
+    Matrix4 texTransform;
+    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence,
+            texTransform.data);
+    texTransform.invalidateType();
+    if (err != NO_ERROR) {
+        ALOGW("Failed to get last queued buffer, error = %d", err);
+        return CopyResult::UnknownError;
+    }
+    if (!sourceBuffer.get()) {
+        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
+        return CopyResult::SourceEmpty;
+    }
+    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
+        ALOGW("Surface is protected, unable to copy from it");
+        return CopyResult::SourceInvalid;
+    }
+    err = sourceFence->wait(500 /* ms */);
+    if (err != NO_ERROR) {
+        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
+        return CopyResult::Timeout;
+    }
+
+    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
+    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
+    // to be able to properly sample from the buffer.
+
+    // Create the EGLImage object that maps the GraphicBuffer
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) sourceBuffer->getNativeBuffer();
+    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+            EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
+
+    if (sourceImage == EGL_NO_IMAGE_KHR) {
+        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
+        return CopyResult::UnknownError;
+    }
+
+    CopyResult copyResult = copyImageInto(sourceImage, texTransform, sourceBuffer->getWidth(),
+            sourceBuffer->getHeight(), srcRect, bitmap);
+
+    // All we're flushing & finishing is the deletion of the texture since
+    // copyImageInto already did a major flush & finish as an implicit
+    // part of glReadPixels, so this shouldn't pose any major stalls.
+    glFinish();
+    eglDestroyImageKHR(display, sourceImage);
+    return copyResult;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
+        Texture& sourceTexture, const Matrix4& texTransform, const Rect& srcRect,
         SkBitmap* bitmap) {
     int destWidth = bitmap->width();
     int destHeight = bitmap->height();
@@ -134,88 +195,40 @@
     return CopyResult::Success;
 }
 
-CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
-        Surface& surface, const Rect& srcRect, SkBitmap* bitmap) {
-    ATRACE_CALL();
-    renderThread.eglManager().initialize();
+CopyResult OpenGLReadbackImpl::copyImageInto(EGLImageKHR eglImage,
+        const Matrix4& imgTransform, int imgWidth, int imgHeight, const Rect& srcRect,
+        SkBitmap* bitmap) {
 
     Caches& caches = Caches::getInstance();
-
-    // Setup the source
-    sp<GraphicBuffer> sourceBuffer;
-    sp<Fence> sourceFence;
-    Matrix4 texTransform;
-    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence,
-            texTransform.data);
-    texTransform.invalidateType();
-    if (err != NO_ERROR) {
-        ALOGW("Failed to get last queued buffer, error = %d", err);
-        return CopyResult::UnknownError;
-    }
-    if (!sourceBuffer.get()) {
-        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
-        return CopyResult::SourceEmpty;
-    }
-    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
-        ALOGW("Surface is protected, unable to copy from it");
-        return CopyResult::SourceInvalid;
-    }
-    err = sourceFence->wait(500 /* ms */);
-    if (err != NO_ERROR) {
-        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
-        return CopyResult::Timeout;
-    }
-
-    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
-    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
-    // to be able to properly sample from the buffer.
-
-    // Create the EGLImage object that maps the GraphicBuffer
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    EGLClientBuffer clientBuffer = (EGLClientBuffer) sourceBuffer->getNativeBuffer();
-    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-
-    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
-            EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
-
-    if (sourceImage == EGL_NO_IMAGE_KHR) {
-        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
-        return CopyResult::UnknownError;
-    }
     GLuint sourceTexId;
     // Create a 2D texture to sample from the EGLImage
     glGenTextures(1, &sourceTexId);
     caches.textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, sourceImage);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
 
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
         ALOGW("glEGLImageTargetTexture2DOES failed (%#x)", status);
-        eglDestroyImageKHR(display, sourceImage);
         return CopyResult::UnknownError;
     }
 
     Texture sourceTexture(caches);
-    sourceTexture.wrap(sourceTexId, sourceBuffer->getWidth(),
-            sourceBuffer->getHeight(), 0, 0 /* total lie */, GL_TEXTURE_EXTERNAL_OES);
+    sourceTexture.wrap(sourceTexId, imgWidth, imgHeight, 0, 0 /* total lie */,
+            GL_TEXTURE_EXTERNAL_OES);
 
-    CopyResult copyResult = copyTextureInto(caches, renderThread.renderState(),
-            sourceTexture, texTransform, srcRect, bitmap);
+    CopyResult copyResult = copyTextureInto(caches, mRenderThread.renderState(),
+            sourceTexture, imgTransform, srcRect, bitmap);
     sourceTexture.deleteTexture();
-    // All we're flushing & finishing is the deletion of the texture since
-    // copyTextureInto already did a major flush & finish as an implicit
-    // part of glReadPixels, so this shouldn't pose any major stalls.
-    glFinish();
-    eglDestroyImageKHR(display, sourceImage);
     return copyResult;
 }
 
-CopyResult Readback::copyTextureLayerInto(renderthread::RenderThread& renderThread,
+bool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread,
         Layer& layer, SkBitmap* bitmap) {
-    ATRACE_CALL();
-    return copyTextureInto(Caches::getInstance(), renderThread.renderState(),
-            layer.getTexture(), layer.getTexTransform(), Rect(), bitmap);
+    return CopyResult::Success == copyTextureInto(Caches::getInstance(),
+            renderThread.renderState(), layer.getTexture(), layer.getTexTransform(),
+            Rect(), bitmap);
 }
 
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
new file mode 100644
index 0000000..7ec2a96
--- /dev/null
+++ b/libs/hwui/OpenGLReadback.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "Readback.h"
+
+namespace android {
+namespace uirenderer {
+
+class Matrix4;
+class Layer;
+
+class OpenGLReadback : public Readback {
+public:
+    virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
+            SkBitmap* bitmap) override;
+
+protected:
+    explicit OpenGLReadback(renderthread::RenderThread& thread) : Readback(thread) {}
+    virtual ~OpenGLReadback() {}
+
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) = 0;
+};
+
+class OpenGLReadbackImpl : public OpenGLReadback {
+public:
+    OpenGLReadbackImpl(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
+
+    /**
+     * Copies the layer's contents into the provided bitmap.
+     */
+    static bool copyLayerInto(renderthread::RenderThread& renderThread, Layer& layer,
+            SkBitmap* bitmap);
+
+protected:
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) override;
+};
+
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index e410d71..9c4cb09 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -133,7 +133,7 @@
 
     // Shaders
     bool hasBitmap;
-    bool isBitmapNpot;
+    bool useShaderBasedWrap;
 
     bool hasVertexAlpha;
     bool useShadowAlphaInterp;
@@ -180,7 +180,7 @@
         modulate = false;
 
         hasBitmap = false;
-        isBitmapNpot = false;
+        useShaderBasedWrap = false;
 
         hasGradient = false;
         gradientType = kGradientLinear;
@@ -234,7 +234,7 @@
         if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
         if (hasBitmap) {
             key |= PROGRAM_KEY_BITMAP;
-            if (isBitmapNpot) {
+            if (useShaderBasedWrap) {
                 key |= PROGRAM_KEY_BITMAP_NPOT;
                 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
                 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 1afc978..0c2309f 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -707,7 +707,7 @@
     if (blendFramebuffer) {
         generateBlend(shader, "blendFramebuffer", description.framebufferMode);
     }
-    if (description.isBitmapNpot) {
+    if (description.useShaderBasedWrap) {
         generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
     }
     if (description.hasGradient) {
@@ -736,7 +736,7 @@
             shader.append(gFS_Main_FetchGradient[gradientIndex(description)]);
         }
         if (description.hasBitmap) {
-            if (!description.isBitmapNpot) {
+            if (!description.useShaderBasedWrap) {
                 shader.append(gFS_Main_FetchBitmap);
             } else {
                 shader.append(gFS_Main_FetchBitmapNpot);
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index 55c943c..7fbc4bf 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -25,8 +25,6 @@
 namespace android {
 namespace uirenderer {
 
-class Layer;
-
 // Keep in sync with PixelCopy.java codes
 enum class CopyResult {
     Success = 0,
@@ -42,15 +40,14 @@
     /**
      * Copies the surface's most recently queued buffer into the provided bitmap.
      */
-    static CopyResult copySurfaceInto(renderthread::RenderThread& renderThread,
-            Surface& surface, const Rect& srcRect, SkBitmap* bitmap);
+    virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
+            SkBitmap* bitmap) = 0;
 
-    /**
-     * Copies the TextureLayer's texture content (thus, the currently rendering buffer) into the
-     * provided bitmap.
-     */
-    static CopyResult copyTextureLayerInto(renderthread::RenderThread& renderThread,
-            Layer& layer, SkBitmap* bitmap);
+protected:
+    explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {}
+    virtual ~Readback() {}
+
+    renderthread::RenderThread& mRenderThread;
 };
 
 } // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 971c2a3..34e6a06 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -58,7 +58,7 @@
 }
 
 static inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) {
-    caches->textureState().bindTexture(texture->id());
+    caches->textureState().bindTexture(texture->target(), texture->id());
     texture->setWrapST(wrapS, wrapT);
 }
 
@@ -218,10 +218,13 @@
     const float height = outData->bitmapTexture->height();
 
     description->hasBitmap = true;
-    if (!caches.extensions().hasNPot()
+    // gralloc doesn't support non-clamp modes
+    if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot()
             && (!isPowerOfTwo(width) || !isPowerOfTwo(height))
-            && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode)) {
-        description->isBitmapNpot = true;
+            && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode))) {
+        // need non-clamp mode, but it's not supported for this draw,
+        // so enable custom shader logic to mimic
+        description->useShaderBasedWrap = true;
         description->bitmapWrapS = gTileModes[xy[0]];
         description->bitmapWrapT = gTileModes[xy[1]];
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index b8f7d9f..c028f115 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -227,7 +227,7 @@
     PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
     status_t error;
     sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat,
-            GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
+            1, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
             | GraphicBuffer::USAGE_SW_READ_NEVER , &error);
 
     if (!buffer.get()) {
@@ -413,7 +413,6 @@
     case PixelStorageType::Heap:
         return mPixelStorage.heap.address;
     case PixelStorageType::Hardware:
-        LOG_ALWAYS_FATAL_IF("Can't get address for hardware bitmap");
         return nullptr;
     }
 }
@@ -470,6 +469,12 @@
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
 }
 
+void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
+    outBitmap->setInfo(info(), rowBytes());
+    outBitmap->setPixelRef(this);
+    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
+}
+
 void Bitmap::getBounds(SkRect* bounds) const {
     SkASSERT(bounds);
     bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 3940381..663238c 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -85,6 +85,10 @@
 
     void getSkBitmap(SkBitmap* outBitmap);
 
+    // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
+    // so it would crash if anyone tries to render this bitmap.
+    void getSkBitmapForShaders(SkBitmap* outBitmap);
+
     int getAshmemFd() const;
     size_t getAllocationByteCount() const;
 
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index a06cc37..8dd165c 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -45,6 +45,7 @@
     minikinPaint->scaleX = paint->getTextScaleX();
     minikinPaint->skewX = paint->getTextSkewX();
     minikinPaint->letterSpacing = paint->getLetterSpacing();
+    minikinPaint->wordSpacing = paint->getWordSpacing();
     minikinPaint->paintFlags = MinikinFontSkia::packPaintFlags(paint);
     minikinPaint->fontFeatureSettings = paint->getFontFeatureSettings();
     minikinPaint->hyphenEdit = minikin::HyphenEdit(paint->getHyphenEdit());
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 10a1db9..c9b5f00 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -48,6 +48,14 @@
         return mLetterSpacing;
     }
 
+    void setWordSpacing(float wordSpacing) {
+        mWordSpacing = wordSpacing;
+    }
+
+    float getWordSpacing() const {
+        return mWordSpacing;
+    }
+
     void setFontFeatureSettings(const std::string& fontFeatureSettings) {
         mFontFeatureSettings = fontFeatureSettings;
     }
@@ -82,6 +90,7 @@
 
 private:
     float mLetterSpacing = 0;
+    float mWordSpacing = 0;
     std::string mFontFeatureSettings;
     uint32_t mMinikinLangListId;
     minikin::FontVariant mFontVariant;
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index 84122d7..6742743 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -19,18 +19,19 @@
 namespace android {
 
 Paint::Paint() :
-        SkPaint(), mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
-        mFontVariant(minikin::VARIANT_DEFAULT) {
+        SkPaint(), mLetterSpacing(0), mWordSpacing(0), mFontFeatureSettings(),
+        mMinikinLangListId(0), mFontVariant(minikin::VARIANT_DEFAULT) {
 }
 
 Paint::Paint(const Paint& paint) : SkPaint(paint),
-        mLetterSpacing(paint.mLetterSpacing), mFontFeatureSettings(paint.mFontFeatureSettings),
+        mLetterSpacing(paint.mLetterSpacing), mWordSpacing(paint.mWordSpacing),
+        mFontFeatureSettings(paint.mFontFeatureSettings),
         mMinikinLangListId(paint.mMinikinLangListId), mFontVariant(paint.mFontVariant),
         mHyphenEdit(paint.mHyphenEdit) {
 }
 
 Paint::Paint(const SkPaint& paint) : SkPaint(paint),
-        mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+        mLetterSpacing(0), mWordSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
         mFontVariant(minikin::VARIANT_DEFAULT) {
 }
 
@@ -40,6 +41,7 @@
 Paint& Paint::operator=(const Paint& other) {
     SkPaint::operator=(other);
     mLetterSpacing = other.mLetterSpacing;
+    mWordSpacing = other.mWordSpacing;
     mFontFeatureSettings = other.mFontFeatureSettings;
     mMinikinLangListId = other.mMinikinLangListId;
     mFontVariant = other.mFontVariant;
@@ -50,6 +52,7 @@
 bool operator==(const Paint& a, const Paint& b) {
     return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
             && a.mLetterSpacing == b.mLetterSpacing
+            && a.mWordSpacing == b.mWordSpacing
             && a.mFontFeatureSettings == b.mFontFeatureSettings
             && a.mMinikinLangListId == b.mMinikinLangListId
             && a.mFontVariant == b.mFontVariant
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 59b1185..f95d98c 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -49,60 +49,10 @@
 }
 
 Typeface* gDefaultTypeface = NULL;
-pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT;
-
-// This installs a default typeface (from a hardcoded path) that allows
-// layouts to work (not crash on null pointer) before the default
-// typeface is set. This happens if HWUI is used outside of zygote/app_process.
-static minikin::FontCollection *makeFontCollection() {
-    std::vector<minikin::FontFamily *>typefaces;
-    const char *fns[] = {
-        "/system/fonts/Roboto-Regular.ttf",
-    };
-
-    minikin::FontFamily *family = new minikin::FontFamily();
-    for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) {
-        const char *fn = fns[i];
-        ALOGD("makeFontCollection adding %s", fn);
-        sk_sp<SkTypeface> skFace = SkTypeface::MakeFromFile(fn);
-        if (skFace != NULL) {
-            // TODO: might be a nice optimization to get access to the underlying font
-            // data, but would require us opening the file ourselves and passing that
-            // to the appropriate Create method of SkTypeface.
-            minikin::MinikinFont *font = new MinikinFontSkia(std::move(skFace), NULL, 0, 0);
-            family->addFont(font);
-            font->Unref();
-        } else {
-            ALOGE("failed to create font %s", fn);
-        }
-    }
-    typefaces.push_back(family);
-
-    minikin::FontCollection *result = new minikin::FontCollection(typefaces);
-    family->Unref();
-    return result;
-}
-
-static void getDefaultTypefaceOnce() {
-  minikin::Layout::init();
-    if (gDefaultTypeface == NULL) {
-        // We expect the client to set a default typeface, but provide a
-        // default so we can make progress before that happens.
-        gDefaultTypeface = new Typeface;
-        gDefaultTypeface->fFontCollection = makeFontCollection();
-        gDefaultTypeface->fSkiaStyle = SkTypeface::kNormal;
-        gDefaultTypeface->fBaseWeight = 400;
-        resolveStyle(gDefaultTypeface);
-    }
-}
 
 Typeface* Typeface::resolveDefault(Typeface* src) {
-    if (src == NULL) {
-        pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce);
-        return gDefaultTypeface;
-    } else {
-        return src;
-    }
+    LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr);
+    return src == nullptr ? gDefaultTypeface : src;
 }
 
 Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
@@ -164,4 +114,27 @@
     gDefaultTypeface = face;
 }
 
+void Typeface::setRobotoTypefaceForTest() {
+    const char* kRobotoFont = "/system/fonts/Roboto-Regular.ttf";
+    sk_sp<SkTypeface> typeface = SkTypeface::MakeFromFile(kRobotoFont);
+    LOG_ALWAYS_FATAL_IF(typeface == nullptr, "Failed to make typeface from %s", kRobotoFont);
+
+    minikin::FontFamily* family = new minikin::FontFamily();
+    minikin::MinikinFont* font = new MinikinFontSkia(std::move(typeface), nullptr, 0, 0);
+    family->addFont(font);
+    font->Unref();
+
+    std::vector<minikin::FontFamily*> typefaces = { family };
+    minikin::FontCollection *collection = new minikin::FontCollection(typefaces);
+    family->Unref();
+
+    Typeface* hwTypeface = new Typeface();
+    hwTypeface->fFontCollection = collection;
+    hwTypeface->fSkiaStyle = SkTypeface::kNormal;
+    hwTypeface->fBaseWeight = 400;
+    hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */);
+
+    Typeface::setDefault(hwTypeface);
+}
+
 }
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index ed0a7ebd..1be630c 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -48,6 +48,9 @@
     static Typeface* createFromFamilies(const std::vector<minikin::FontFamily*>& families);
 
     static void setDefault(Typeface* face);
+
+    // Sets roboto font as the default typeface for testing purpose.
+    static void setRobotoTypefaceForTest();
 };
 
 }
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 13a0ed8..f2af4a8 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -23,36 +23,41 @@
 namespace skiapipeline {
 
 void LayerDrawable::onDraw(SkCanvas* canvas) {
+    DrawLayer(canvas->getGrContext(), canvas, mLayer.get());
+}
+
+bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer) {
     // transform the matrix based on the layer
     int saveCount = -1;
-    if (!mLayer->getTransform().isIdentity()) {
+    if (!layer->getTransform().isIdentity()) {
         saveCount = canvas->save();
         SkMatrix transform;
-        mLayer->getTransform().copyTo(transform);
+        layer->getTransform().copyTo(transform);
         canvas->concat(transform);
     }
     GrGLTextureInfo externalTexture;
-    externalTexture.fTarget = mLayer->getRenderTarget();
-    externalTexture.fID = mLayer->getTextureId();
-    GrContext* context = canvas->getGrContext();
+    externalTexture.fTarget = layer->getRenderTarget();
+    externalTexture.fID = layer->getTextureId();
     GrBackendTextureDesc textureDescription;
-    textureDescription.fWidth = mLayer->getWidth();
-    textureDescription.fHeight = mLayer->getHeight();
+    textureDescription.fWidth = layer->getWidth();
+    textureDescription.fHeight = layer->getHeight();
     textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
     textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
     textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
     sk_sp<SkImage> layerImage = SkImage::MakeFromTexture(context, textureDescription);
     if (layerImage) {
         SkPaint paint;
-        paint.setAlpha(mLayer->getAlpha());
-        paint.setBlendMode(mLayer->getMode());
-        paint.setColorFilter(sk_ref_sp(mLayer->getColorFilter()));
+        paint.setAlpha(layer->getAlpha());
+        paint.setBlendMode(layer->getMode());
+        paint.setColorFilter(sk_ref_sp(layer->getColorFilter()));
         canvas->drawImage(layerImage, 0, 0, &paint);
     }
     // restore the original matrix
     if (saveCount >= 0) {
         canvas->restoreToCount(saveCount);
     }
+
+    return layerImage;
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 91e2744..4319895 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -33,6 +33,7 @@
     explicit LayerDrawable(Layer* layer)
             : mLayer(layer) {}
 
+    static bool DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer);
  protected:
      virtual SkRect onGetBounds() override {
          return SkRect::MakeWH(mLayer->getWidth(), mLayer->getHeight());
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index accbabd..7dcbbd0 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -164,6 +164,14 @@
                 paint = &tmpPaint;
             }
             renderNode->getLayerSurface()->draw(canvas, 0, 0, paint);
+
+            if (CC_UNLIKELY(Properties::debugLayersUpdates
+                    && !renderNode->getSkiaLayer()->hasRenderedSinceRepaint)) {
+                renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;
+                SkPaint layerPaint;
+                layerPaint.setColor(0x7f00ff00);
+                canvas->drawRect(bounds, layerPaint);
+            }
         // composing a software layer with alpha
         } else if (properties.effectiveLayerType() == LayerType::Software) {
             SkPaint paint;
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 4abaa90..2ad7f74 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -53,11 +53,15 @@
 
 bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer,
         std::function<void(RenderNode*, TreeInfo&, bool)> childFn) {
-    // If the prepare tree is triggered by the UI thread then we must force all
-    // mutable images to be pinned in the GPU cache until the next UI thread
-    // draw
-    if (info.mode == TreeInfo::MODE_FULL) {
-        info.prepareTextures = info.canvasContext.pinImages(mMutableImages);
+    // If the prepare tree is triggered by the UI thread and no previous call to
+    // pinImages has failed then we must pin all mutable images in the GPU cache
+    // until the next UI thread draw.
+    if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) {
+        // In the event that pinning failed we prevent future pinImage calls for the
+        // remainder of this tree traversal and also unpin any currently pinned images
+        // to free up GPU resources.
+        info.prepareTextures = false;
+        info.canvasContext.unpinImages();
     }
 
     for (auto& child : mChildNodes) {
diff --git a/libs/hwui/pipeline/skia/SkiaLayer.h b/libs/hwui/pipeline/skia/SkiaLayer.h
index 0988d7e..904d57e0 100644
--- a/libs/hwui/pipeline/skia/SkiaLayer.h
+++ b/libs/hwui/pipeline/skia/SkiaLayer.h
@@ -30,6 +30,7 @@
 {
     sk_sp<SkSurface> layerSurface;
     Matrix4 inverseTransformInWindow;
+    bool hasRenderedSinceRepaint = false;
 };
 
 
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index f046e4b..7f3474a 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -17,9 +17,9 @@
 #include "SkiaOpenGLPipeline.h"
 
 #include "DeferredLayerUpdater.h"
+#include "LayerDrawable.h"
 #include "renderthread/EglManager.h"
 #include "renderstate/RenderState.h"
-#include "Readback.h"
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "utils/TraceUtils.h"
@@ -121,10 +121,16 @@
     return *requireSwap;
 }
 
-bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
-    layer->apply();
-    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
-            == CopyResult::Success;
+bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) {
+    if (!mRenderThread.getGrContext()) {
+        return false;
+    }
+
+    deferredLayer->apply();
+
+    SkCanvas canvas(*bitmap);
+    Layer* layer = deferredLayer->backingLayer();
+    return LayerDrawable::DrawLayer(mRenderThread.getGrContext(), &canvas, layer);
 }
 
 DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
new file mode 100644
index 0000000..a18d264
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+#include "SkiaOpenGLReadback.h"
+
+#include "Matrix.h"
+#include "Properties.h"
+#include <SkCanvas.h>
+#include <SkSurface.h>
+#include <gl/GrGLInterface.h>
+#include <gl/GrGLTypes.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+CopyResult SkiaOpenGLReadback::copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+        int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) {
+
+    GLuint sourceTexId;
+    glGenTextures(1, &sourceTexId);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
+
+    sk_sp<GrContext> grContext = sk_ref_sp(mRenderThread.getGrContext());
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+        LOG_ALWAYS_FATAL_IF(!glInterface.get());
+        grContext.reset(GrContext::Create(GrBackend::kOpenGL_GrBackend,
+                (GrBackendContext)glInterface.get()));
+    } else {
+        grContext->resetContext();
+    }
+
+    GrGLTextureInfo externalTexture;
+    externalTexture.fTarget = GL_TEXTURE_EXTERNAL_OES;
+    externalTexture.fID = sourceTexId;
+
+    GrBackendTextureDesc textureDescription;
+    textureDescription.fWidth = imgWidth;
+    textureDescription.fHeight = imgHeight;
+    textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
+    textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
+    textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
+
+    CopyResult copyResult = CopyResult::UnknownError;
+    sk_sp<SkImage> image(SkImage::MakeFromAdoptedTexture(grContext.get(), textureDescription));
+    if (image) {
+        SkAutoLockPixels alp(*bitmap);
+
+        // convert to Skia data structures
+        const SkRect bufferRect = SkRect::MakeIWH(imgWidth, imgHeight);
+        SkRect skiaSrcRect = srcRect.toSkRect();
+        SkMatrix textureMatrix;
+        imgTransform.copyTo(textureMatrix);
+
+        // remove the y-flip applied to the matrix so that we can scale the srcRect.
+        // This flip is not needed as we specify the origin of the texture when we
+        // wrap it as an SkImage.
+        SkMatrix yFlip = SkMatrix::MakeScale(1, -1);
+        yFlip.postTranslate(0,1);
+        textureMatrix.preConcat(yFlip);
+
+        // copy the entire src if the rect is empty
+        if (skiaSrcRect.isEmpty()) {
+            skiaSrcRect = bufferRect;
+        }
+
+        // since the y-flip has been removed we can simply scale & translate
+        // the source rectangle
+        textureMatrix.mapRect(&skiaSrcRect);
+
+        if (skiaSrcRect.intersect(bufferRect)) {
+            SkPoint srcOrigin = SkPoint::Make(skiaSrcRect.fLeft, skiaSrcRect.fTop);
+
+            // if we need to scale the result we must render to an offscreen buffer
+            if (bitmap->width() != skiaSrcRect.width()
+                    || bitmap->height() != skiaSrcRect.height()) {
+                sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
+                        grContext.get(), SkBudgeted::kYes, bitmap->info());
+                SkPaint paint;
+                paint.setBlendMode(SkBlendMode::kSrc);
+                scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
+                        SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
+                image = scaledSurface->makeImageSnapshot();
+                srcOrigin.set(0,0);
+            }
+
+            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
+                                  srcOrigin.fX, srcOrigin.fY)) {
+                copyResult = CopyResult::Success;
+            }
+        }
+    }
+
+    // make sure that we have deleted the texture (in the SkImage) before we
+    // destroy the EGLImage that it was created from
+    image.reset();
+    return copyResult;
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
new file mode 100644
index 0000000..d914409
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "OpenGLReadback.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaOpenGLReadback : public OpenGLReadback {
+public:
+    SkiaOpenGLReadback(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
+protected:
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) override;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index a6612c9..c5a40d4 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -48,9 +48,11 @@
 
 bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
     for (SkImage* image : mutableImages) {
-        mPinnedImages.emplace_back(sk_ref_sp(image));
-        // TODO: return false if texture creation fails (see b/32691999)
-        SkImage_pinAsTexture(image, mRenderThread.getGrContext());
+        if (SkImage_pinAsTexture(image, mRenderThread.getGrContext())) {
+            mPinnedImages.emplace_back(sk_ref_sp(image));
+        } else {
+            return false;
+        }
     }
     return true;
 }
@@ -106,6 +108,7 @@
                 return;
             }
 
+            layerNode->getSkiaLayer()->hasRenderedSinceRepaint = false;
             layerCanvas->clear(SK_ColorTRANSPARENT);
 
             RenderNodeDrawable root(layerNode, layerCanvas, false);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index c322efb..0174b86 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -84,7 +84,7 @@
      * remain in the cache until it has been unpinned. We leverage this feature
      * to avoid making a CPU copy of the pixels.
      *
-     * @return true if the images have been successfully pinned to the GPU cache
+     * @return true if all images have been successfully pinned to the GPU cache
      *         and false otherwise (e.g. cache limits have been exceeded).
      */
     bool pinImages(std::vector<SkImage*>& mutableImages) {
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index afeeef8..177a729 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -20,7 +20,7 @@
 #include "EglManager.h"
 #include "ProfileRenderer.h"
 #include "renderstate/RenderState.h"
-#include "Readback.h"
+#include "OpenGLReadback.h"
 
 #include <android/native_window.h>
 #include <cutils/properties.h>
@@ -117,9 +117,9 @@
 }
 
 bool OpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    ATRACE_CALL();
     layer->apply();
-    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
-            == CopyResult::Success;
+    return OpenGLReadbackImpl::copyLayerInto(mRenderThread, *(layer->backingLayer()), bitmap);
 }
 
 DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 39e5931..2c48242 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -602,8 +602,8 @@
 
 CREATE_BRIDGE4(copySurfaceInto, RenderThread* thread,
         Surface* surface, Rect srcRect, SkBitmap* bitmap) {
-    return (void*) Readback::copySurfaceInto(*args->thread,
-            *args->surface, args->srcRect, args->bitmap);
+    return (void*)args->thread->readback().copySurfaceInto(*args->surface,
+            args->srcRect, args->bitmap);
 }
 
 int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top,
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index f3789c8..223958a 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -17,8 +17,10 @@
 #include "RenderThread.h"
 
 #include "../renderstate/RenderState.h"
+#include "../pipeline/skia/SkiaOpenGLReadback.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
+#include "OpenGLReadback.h"
 #include "RenderProxy.h"
 #include "VulkanManager.h"
 
@@ -196,6 +198,30 @@
     mVkManager = new VulkanManager(*this);
 }
 
+Readback& RenderThread::readback() {
+
+    if (!mReadback) {
+        auto renderType = Properties::getRenderPipelineType();
+        switch (renderType) {
+            case RenderPipelineType::OpenGL:
+                mReadback = new OpenGLReadbackImpl(*this);
+                break;
+            case RenderPipelineType::SkiaGL:
+            case RenderPipelineType::SkiaVulkan:
+                // It works to use the OpenGL pipeline for Vulkan but this is not
+                // ideal as it causes us to create an OpenGL context in addition
+                // to the Vulkan one.
+                mReadback = new skiapipeline::SkiaOpenGLReadback(*this);
+                break;
+            default:
+                LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+                break;
+        }
+    }
+
+    return *mReadback;
+}
+
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
         ALOGE("Display event receiver pipe was closed or an error occurred.  "
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 12050dd..d121bcf 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -37,6 +37,7 @@
 
 namespace uirenderer {
 
+class Readback;
 class RenderState;
 class TestUtils;
 
@@ -93,6 +94,7 @@
     RenderState& renderState() const { return *mRenderState; }
     EglManager& eglManager() const { return *mEglManager; }
     JankTracker& jankTracker() { return *mJankTracker; }
+    Readback& readback();
 
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
 
@@ -151,6 +153,7 @@
     EglManager* mEglManager;
 
     JankTracker* mJankTracker = nullptr;
+    Readback* mReadback = nullptr;
 
     sk_sp<GrContext> mGrContext;
     VulkanManager* mVkManager;
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
new file mode 100644
index 0000000..9b0b950
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include "TestSceneBase.h"
+#include "utils/Color.h"
+#include "tests/common/BitmapAllocationTestUtils.h"
+
+class BitmapShaders;
+
+static bool _BitmapShaders(
+        BitmapAllocationTestUtils::registerBitmapAllocationScene<BitmapShaders>(
+                "bitmapShader", "Draws bitmap shaders with repeat and mirror modes."));
+
+class BitmapShaders : public TestScene {
+public:
+    BitmapShaders(BitmapAllocationTestUtils::BitmapAllocator allocator)
+        : TestScene()
+        , mAllocator(allocator) { }
+
+    sp<RenderNode> card;
+    void createContent(int width, int height, Canvas& canvas) override {
+        canvas.drawColor(Color::Grey_200, SkBlendMode::kSrcOver);
+        sk_sp<Bitmap> hwuiBitmap = mAllocator(200, 200, kRGBA_8888_SkColorType,
+                            [](SkBitmap& skBitmap) {
+            skBitmap.eraseColor(Color::White);
+            SkCanvas skCanvas(skBitmap);
+            SkPaint skPaint;
+            skPaint.setColor(Color::Red_500);
+            skCanvas.drawRect(SkRect::MakeWH(100, 100), skPaint);
+            skPaint.setColor(Color::Blue_500);
+            skCanvas.drawRect(SkRect::MakeXYWH(100, 100, 100, 100), skPaint);
+        });
+
+        SkBitmap bitmap;
+        SkPaint paint;
+        hwuiBitmap->getSkBitmapForShaders(&bitmap);
+
+        sk_sp<SkShader> repeatShader = SkMakeBitmapShader(bitmap,
+                SkShader::TileMode::kRepeat_TileMode,
+                SkShader::TileMode::kRepeat_TileMode,
+                nullptr,
+                kNever_SkCopyPixelsMode,
+                nullptr);
+        paint.setShader(std::move(repeatShader));
+        canvas.drawRoundRect(0, 0, 500, 500, 50.0f, 50.0f, paint);
+
+        sk_sp<SkShader> mirrorShader = SkMakeBitmapShader(bitmap,
+                SkShader::TileMode::kMirror_TileMode,
+                SkShader::TileMode::kMirror_TileMode,
+                nullptr,
+                kNever_SkCopyPixelsMode,
+                nullptr);
+        paint.setShader(std::move(mirrorShader));
+        canvas.drawRoundRect(0, 600, 500, 1100, 50.0f, 50.0f, paint);
+    }
+
+    void doFrame(int frameNr) override { }
+
+    BitmapAllocationTestUtils::BitmapAllocator mAllocator;
+};
\ No newline at end of file
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index ebc1dd7..1f56222 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -17,6 +17,7 @@
 #include "tests/common/LeakChecker.h"
 #include "tests/common/TestScene.h"
 
+#include "hwui/Typeface.h"
 #include "protos/hwui.pb.h"
 #include "Properties.h"
 
@@ -303,6 +304,8 @@
     // set defaults
     gOpts.count = 150;
 
+    Typeface::setRobotoTypefaceForTest();
+
     parseOptions(argc, argv);
     if (!gBenchmarkReporter && gOpts.renderOffscreen) {
         gBenchmarkReporter.reset(new benchmark::ConsoleReporter());
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index da724a9..bbaf267 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -182,7 +182,7 @@
         canvas->insertReorderBarrier(true);
 
         // Draw child loop
-        for (int i = 0; i < benchState.range_x(); i++) {
+        for (int i = 0; i < benchState.range(0); i++) {
             canvas->drawRenderNode(child.get());
         }
 
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index d68f5bd..398e7a8 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -113,7 +113,7 @@
 
 void BM_FrameBuilder_defer_scene(benchmark::State& state) {
     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range_x());
+        const char* sceneName = *(SCENES.begin() + state.range(0));
         state.SetLabel(sceneName);
         auto node = getSyncedSceneNode(sceneName);
         while (state.KeepRunning()) {
@@ -129,7 +129,7 @@
 
 void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range_x());
+        const char* sceneName = *(SCENES.begin() + state.range(0));
         state.SetLabel(sceneName);
         auto node = getSyncedSceneNode(sceneName);
 
diff --git a/libs/hwui/tests/microbench/main.cpp b/libs/hwui/tests/microbench/main.cpp
index 9771c85..b5abf5b 100644
--- a/libs/hwui/tests/microbench/main.cpp
+++ b/libs/hwui/tests/microbench/main.cpp
@@ -17,6 +17,8 @@
 #include "debug/GlesDriver.h"
 #include "debug/NullGlesDriver.h"
 
+#include "hwui/Typeface.h"
+
 #include <benchmark/benchmark.h>
 
 #include <memory>
@@ -27,6 +29,7 @@
 int main(int argc, char** argv) {
     debug::GlesDriver::replace(std::make_unique<debug::NullGlesDriver>());
     benchmark::Initialize(&argc, argv);
+    Typeface::setRobotoTypefaceForTest();
     benchmark::RunSpecifiedBenchmarks();
     return 0;
 }
diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp
index d05bdbf..cea84c0 100644
--- a/libs/hwui/tests/unit/main.cpp
+++ b/libs/hwui/tests/unit/main.cpp
@@ -20,6 +20,7 @@
 #include "Caches.h"
 #include "debug/GlesDriver.h"
 #include "debug/NullGlesDriver.h"
+#include "hwui/Typeface.h"
 #include "thread/TaskManager.h"
 #include "tests/common/LeakChecker.h"
 
@@ -50,6 +51,13 @@
     raise(sig);
 }
 
+class TypefaceEnvironment : public testing::Environment {
+public:
+    virtual void SetUp() {
+        Typeface::setRobotoTypefaceForTest();
+    }
+};
+
 int main(int argc, char* argv[]) {
     // Register a crash handler
     struct sigaction sa;
@@ -69,6 +77,8 @@
     testing::InitGoogleTest(&argc, argv);
     testing::InitGoogleMock(&argc, argv);
 
+    testing::AddGlobalTestEnvironment(new TypefaceEnvironment());
+
     int ret = RUN_ALL_TESTS();
     test::LeakChecker::checkForLeaks();
     return ret;
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fe1ee02..fa3d8bd 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -553,7 +553,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IMountService")
+IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/storage/IMountServiceListener.cpp b/libs/storage/IMountServiceListener.cpp
index 6a093fd..033d70d 100644
--- a/libs/storage/IMountServiceListener.cpp
+++ b/libs/storage/IMountServiceListener.cpp
@@ -34,7 +34,7 @@
             const String16& /* oldState */, const String16& /* newState */) { }
 };
 
-IMPLEMENT_META_INTERFACE(MountServiceListener, "android.os.storage.IMountServiceListener")
+IMPLEMENT_META_INTERFACE(MountServiceListener, "android.os.storage.IStorageEventListener")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/storage/IMountShutdownObserver.cpp b/libs/storage/IMountShutdownObserver.cpp
index 6114d4a..e5de603 100644
--- a/libs/storage/IMountShutdownObserver.cpp
+++ b/libs/storage/IMountShutdownObserver.cpp
@@ -31,7 +31,7 @@
     virtual void onShutDownComplete(const int32_t /* statusCode */) {}
 };
 
-IMPLEMENT_META_INTERFACE(MountShutdownObserver, "android.os.storage.IMountShutdownObserver")
+IMPLEMENT_META_INTERFACE(MountShutdownObserver, "android.os.storage.IStorageShutdownObserver")
 
 status_t BnMountShutdownObserver::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b5e3af0..43fb4b9 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1513,9 +1513,9 @@
     }
 
     @Override
-    void playerSetVolume(float leftVolume, float rightVolume) {
-        leftVolume = clampGainOrLevel(leftVolume);
-        rightVolume = clampGainOrLevel(rightVolume);
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        leftVolume = clampGainOrLevel(muting ? 0.0f : leftVolume);
+        rightVolume = clampGainOrLevel(muting ? 0.0f : rightVolume);
 
         native_setVolume(leftVolume, rightVolume);
     }
@@ -2393,8 +2393,8 @@
     }
 
     @Override
-    int playerSetAuxEffectSendLevel(float level) {
-        level = clampGainOrLevel(level);
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        level = clampGainOrLevel(muting ? 0.0f : level);
         int err = native_setAuxEffectSendLevel(level);
         return err == 0 ? SUCCESS : ERROR;
     }
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index d77a082..bbb7184 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2189,9 +2189,9 @@
     /**
      * Loads EXIF attributes from a JPEG input stream.
      *
-     * @param inputStream The input stream that starts with the JPEG data.
+     * @param in The input stream that starts with the JPEG data.
      * @param jpegOffset The offset value in input stream for JPEG data.
-     * @param imageTypes The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
+     * @param imageType The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
      *                   primary image, IFD_TYPE_PREVIEW for preview image, and
      *                   IFD_TYPE_THUMBNAIL for thumbnail image.
      * @throws IOException If the data contains invalid JPEG markers, offsets, or length values.
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 82cf965..36ad90b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1826,8 +1826,8 @@
     }
 
     @Override
-    void playerSetVolume(float leftVolume, float rightVolume) {
-        _setVolume(leftVolume, rightVolume);
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        _setVolume(muting ? 0.0f : leftVolume, muting ? 0.0f : rightVolume);
     }
 
     private native void _setVolume(float leftVolume, float rightVolume);
@@ -1900,8 +1900,8 @@
     }
 
     @Override
-    int playerSetAuxEffectSendLevel(float level) {
-        _setAuxEffectSendLevel(level);
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        _setAuxEffectSendLevel(muting ? 0.0f : level);
         return AudioSystem.SUCCESS;
     }
 
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index b262d97..690a553 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -39,6 +39,11 @@
  */
 public abstract class PlayerBase {
 
+    private final static String TAG = "PlayerBase";
+    private static IAudioService sService; //lazy initialization, use getService()
+    /** Debug app ops */
+    protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG);
+
     // parameters of the player that affect AppOps
     protected AudioAttributes mAttributes;
     protected float mLeftVolume = 1.0f;
@@ -51,7 +56,6 @@
     private boolean mHasAppOpsPlayAudio = true;
     private final Object mAppOpsLock = new Object();
 
-
     /**
      * Constructor. Must be given audio attributes, as they are required for AppOps.
      * @param attr non-null audio attributes
@@ -101,7 +105,7 @@
     void baseStart() {
         synchronized (mAppOpsLock) {
             if (isRestricted_sync()) {
-                playerSetVolume(0, 0);
+                playerSetVolume(true/*muting*/,0, 0);
             }
         }
     }
@@ -114,7 +118,7 @@
                 return;
             }
         }
-        playerSetVolume(leftVolume, rightVolume);
+        playerSetVolume(false/*muting*/,leftVolume, rightVolume);
     }
 
     int baseSetAuxEffectSendLevel(float level) {
@@ -124,7 +128,7 @@
                 return AudioSystem.SUCCESS;
             }
         }
-        return playerSetAuxEffectSendLevel(level);
+        return playerSetAuxEffectSendLevel(false/*muting*/, level);
     }
 
     /**
@@ -159,11 +163,18 @@
         try {
             if (oldHasAppOpsPlayAudio != mHasAppOpsPlayAudio) {
                 if (mHasAppOpsPlayAudio) {
-                    playerSetVolume(mLeftVolume, mRightVolume);
-                    playerSetAuxEffectSendLevel(mAuxEffectSendLevel);
+                    if (DEBUG_APP_OPS) {
+                        Log.v(TAG, "updateAppOpsPlayAudio: unmuting player, vol=" + mLeftVolume
+                                + "/" + mRightVolume);
+                    }
+                    playerSetVolume(false/*muting*/, mLeftVolume, mRightVolume);
+                    playerSetAuxEffectSendLevel(false/*muting*/, mAuxEffectSendLevel);
                 } else {
-                    playerSetVolume(0.0f, 0.0f);
-                    playerSetAuxEffectSendLevel(0.0f);
+                    if (DEBUG_APP_OPS) {
+                        Log.v(TAG, "updateAppOpsPlayAudio: muting player");
+                    }
+                    playerSetVolume(true/*muting*/, 0.0f, 0.0f);
+                    playerSetAuxEffectSendLevel(true/*muting*/, 0.0f);
                 }
             }
         } catch (Exception e) {
@@ -171,7 +182,6 @@
         }
     }
 
-
     /**
      * To be called by the subclass whenever an operation is potentially restricted.
      * As the media player-common behavior are incorporated into this class, the subclass's need
@@ -189,10 +199,41 @@
         if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
             return false;
         }
+        // check force audibility flag and camera restriction
+        if (((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0)
+                && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)) {
+            boolean cameraSoundForced = false;
+            try {
+                cameraSoundForced = getService().isCameraSoundForced();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Cannot access AudioService in isRestricted_sync()");
+            } catch (NullPointerException e) {
+                Log.e(TAG, "Null AudioService in isRestricted_sync()");
+            }
+            if (cameraSoundForced) {
+                return false;
+            }
+        }
         return true;
     }
 
+    private static IAudioService getService()
+    {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+
     // Abstract methods a subclass needs to implement
-    abstract void playerSetVolume(float leftVolume, float rightVolume);
-    abstract int playerSetAuxEffectSendLevel(float level);
+    /**
+     * Abstract method for the subclass behavior's for volume and muting commands
+     * @param muting if true, the player is to be muted, and the volume values can be ignored
+     * @param leftVolume the left volume to use if muting is false
+     * @param rightVolume the right volume to use if muting is false
+     */
+    abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume);
+    abstract int playerSetAuxEffectSendLevel(boolean muting, float level);
 }
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 9fafda4..b429e22 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -35,9 +35,6 @@
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 
-import com.android.internal.app.IAppOpsCallback;
-import com.android.internal.app.IAppOpsService;
-
 
 /**
  * The SoundPool class manages and plays audio resources for applications.
@@ -111,7 +108,7 @@
  * another level, a new SoundPool is created, sounds are loaded, and play
  * resumes.</p>
  */
-public class SoundPool {
+public class SoundPool extends PlayerBase {
     static { System.loadLibrary("soundpool"); }
 
     // SoundPool messages
@@ -130,10 +127,6 @@
 
     private final Object mLock;
     private final AudioAttributes mAttributes;
-    private final IAppOpsService mAppOps;
-    private final IAppOpsCallback mAppOpsCallback;
-
-    private static IAudioService sService;
 
     /**
      * Constructor. Constructs a SoundPool object with the following
@@ -156,32 +149,14 @@
     }
 
     private SoundPool(int maxStreams, AudioAttributes attributes) {
+        super(attributes);
+
         // do native setup
         if (native_setup(new WeakReference<SoundPool>(this), maxStreams, attributes) != 0) {
             throw new RuntimeException("Native setup failed");
         }
         mLock = new Object();
         mAttributes = attributes;
-        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
-        mAppOps = IAppOpsService.Stub.asInterface(b);
-        // initialize mHasAppOpsPlayAudio
-        updateAppOpsPlayAudio();
-        // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
-        mAppOpsCallback = new IAppOpsCallback.Stub() {
-            public void opChanged(int op, int uid, String packageName) {
-                synchronized (mLock) {
-                    if (op == AppOpsManager.OP_PLAY_AUDIO) {
-                        updateAppOpsPlayAudio();
-                    }
-                }
-            }
-        };
-        try {
-            mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
-                    ActivityThread.currentPackageName(), mAppOpsCallback);
-        } catch (RemoteException e) {
-            mHasAppOpsPlayAudio = false;
-        }
     }
 
     /**
@@ -192,11 +167,7 @@
      * should be set to null.
      */
     public final void release() {
-        try {
-            mAppOps.stopWatchingMode(mAppOpsCallback);
-        } catch (RemoteException e) {
-            // nothing to do here, the SoundPool is being released anyway
-        }
+        baseRelease();
         native_release();
     }
 
@@ -333,9 +304,7 @@
      */
     public final int play(int soundID, float leftVolume, float rightVolume,
             int priority, int loop, float rate) {
-        if (isRestricted()) {
-            leftVolume = rightVolume = 0;
-        }
+        baseStart();
         return _play(soundID, leftVolume, rightVolume, priority, loop, rate);
     }
 
@@ -408,12 +377,26 @@
      * @param rightVolume right volume value (range = 0.0 to 1.0)
      */
     public final void setVolume(int streamID, float leftVolume, float rightVolume) {
-        if (isRestricted()) {
-            return;
-        }
+        // unlike other subclasses of PlayerBase, we are not calling
+        // baseSetVolume(leftVolume, rightVolume) as we need to keep track of each
+        // volume separately for each player, so we still send the command, but
+        // handle mute/unmute separately through playerSetVolume()
         _setVolume(streamID, leftVolume, rightVolume);
     }
 
+
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        // not used here to control the player volume directly, but used to mute/unmute
+        _mute(muting);
+    }
+
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        // no aux send functionality so no-op
+        return AudioSystem.SUCCESS;
+    }
+
     /**
      * Similar, except set volume of all channels to same value.
      * @hide
@@ -494,55 +477,6 @@
         }
     }
 
-    private static IAudioService getService()
-    {
-        if (sService != null) {
-            return sService;
-        }
-        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
-        sService = IAudioService.Stub.asInterface(b);
-        return sService;
-    }
-
-    private boolean isRestricted() {
-        // check app ops
-        if (mHasAppOpsPlayAudio) {
-            return false;
-        }
-        // check bypass flag
-        if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
-            return false;
-        }
-        // check force audibility flag and camera restriction
-        if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0) {
-// FIXME: should also check usage when set properly by camera app
-//          && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-            boolean cameraSoundForced = false;
-            try {
-                cameraSoundForced = getService().isCameraSoundForced();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Cannot access AudioService in isRestricted()");
-            } catch (NullPointerException e) {
-                Log.e(TAG, "Null AudioService in isRestricted()");
-            }
-            if (cameraSoundForced) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void updateAppOpsPlayAudio() {
-        try {
-            final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
-                    mAttributes.getUsage(),
-                    Process.myUid(), ActivityThread.currentPackageName());
-            mHasAppOpsPlayAudio = (mode == AppOpsManager.MODE_ALLOWED);
-        } catch (RemoteException e) {
-            mHasAppOpsPlayAudio = false;
-        }
-    }
-
     private native final int _load(FileDescriptor fd, long offset, long length, int priority); 
 
     private native final int native_setup(Object weakRef, int maxStreams,
@@ -553,6 +487,8 @@
 
     private native final void _setVolume(int streamID, float leftVolume, float rightVolume);
 
+    private native final void _mute(boolean muting);
+
     // post event from native code to message handler
     @SuppressWarnings("unchecked")
     private static void postEventFromNative(Object ref, int msg, int arg1, int arg2, Object obj) {
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index d2dc440..87092d0 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -60,6 +60,7 @@
     ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels);
 
     mQuit = false;
+    mMuted = false;
     mDecodeThread = 0;
     memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
     mAllocated = 0;
@@ -366,6 +367,19 @@
     }
 }
 
+void SoundPool::mute(bool muting)
+{
+    ALOGV("mute(%d)", muting);
+    Mutex::Autolock lock(&mLock);
+    mMuted = muting;
+    if (!mChannels.empty()) {
+            for (List<SoundChannel*>::iterator iter = mChannels.begin();
+                    iter != mChannels.end(); ++iter) {
+                (*iter)->mute(muting);
+            }
+        }
+}
+
 void SoundPool::autoResume()
 {
     ALOGV("autoResume()");
@@ -1032,7 +1046,7 @@
 {
     mLeftVolume = leftVolume;
     mRightVolume = rightVolume;
-    if (mAudioTrack != NULL)
+    if (mAudioTrack != NULL && !mMuted)
         mAudioTrack->setVolume(leftVolume, rightVolume);
 }
 
@@ -1042,6 +1056,19 @@
     setVolume_l(leftVolume, rightVolume);
 }
 
+void SoundChannel::mute(bool muting)
+{
+    Mutex::Autolock lock(&mLock);
+    mMuted = muting;
+    if (mAudioTrack != NULL) {
+        if (mMuted) {
+            mAudioTrack->setVolume(0.0f, 0.0f);
+        } else {
+            mAudioTrack->setVolume(mLeftVolume, mRightVolume);
+        }
+    }
+}
+
 void SoundChannel::setLoop(int loop)
 {
     Mutex::Autolock lock(&mLock);
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index aff101f..5c48a90 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -114,13 +114,14 @@
 public:
     enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING };
     SoundChannel() : mState(IDLE), mNumChannels(1),
-            mPos(0), mToggle(0), mAutoPaused(false) {}
+            mPos(0), mToggle(0), mAutoPaused(false), mMuted(false) {}
     ~SoundChannel();
     void init(SoundPool* soundPool);
     void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume,
             int priority, int loop, float rate);
     void setVolume_l(float leftVolume, float rightVolume);
     void setVolume(float leftVolume, float rightVolume);
+    void mute(bool muting);
     void stop_l();
     void stop();
     void pause();
@@ -154,6 +155,7 @@
     unsigned long       mToggle;
     bool                mAutoPaused;
     int                 mPrevSampleID;
+    bool                mMuted;
 };
 
 // application object for managing a pool of sounds
@@ -168,6 +170,7 @@
     int play(int sampleID, float leftVolume, float rightVolume, int priority,
             int loop, float rate);
     void pause(int channelID);
+    void mute(bool muting);
     void autoPause();
     void resume(int channelID);
     void autoResume();
@@ -222,6 +225,7 @@
     int                     mNextSampleID;
     int                     mNextChannelID;
     bool                    mQuit;
+    bool                    mMuted;
 
     // callback
     Mutex                   mCallbackLock;
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index ab3e340..9d0c1f8 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -132,6 +132,15 @@
 }
 
 static void
+android_media_SoundPool_mute(JNIEnv *env, jobject thiz, jboolean muting)
+{
+    ALOGV("android_media_SoundPool_mute(%d)", muting);
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->mute(muting == JNI_TRUE);
+}
+
+static void
 android_media_SoundPool_setPriority(JNIEnv *env, jobject thiz, jint channelID,
         jint priority)
 {
@@ -270,6 +279,10 @@
         "(IFF)V",
         (void *)android_media_SoundPool_setVolume
     },
+    {   "_mute",
+        "(Z)V",
+        (void *)android_media_SoundPool_mute
+    },
     {   "setPriority",
         "(II)V",
         (void *)android_media_SoundPool_setPriority
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index bfc9ff3..7fa5736 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -27,7 +27,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.text.Editable;
 import android.text.TextWatcher;
@@ -64,7 +64,7 @@
 
     Handler mHandler;
     IBackupManager mBackupManager;
-    IMountService mMountService;
+    IStorageManager mStorageManager;
     FullObserver mObserver;
     int mToken;
     boolean mIsEncrypted;
@@ -158,7 +158,7 @@
         }
 
         mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
-        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
 
         mHandler = new ObserverHandler(getApplicationContext());
         final Object oldObserver = getLastNonConfigurationInstance();
@@ -271,14 +271,14 @@
 
     boolean deviceIsEncrypted() {
         try {
-            return mMountService.getEncryptionState()
+            return mStorageManager.getEncryptionState()
                      != StorageManager.ENCRYPTION_STATE_NONE
-                && mMountService.getPasswordType()
+                && mStorageManager.getPasswordType()
                      != StorageManager.CRYPT_TYPE_DEFAULT;
         } catch (Exception e) {
-            // If we can't talk to the mount service we have a serious problem; fail
+            // If we can't talk to the storagemanager service we have a serious problem; fail
             // "secure" i.e. assuming that the device is encrypted.
-            Slog.e(TAG, "Unable to communicate with mount service: " + e.getMessage());
+            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
             return true;
         }
     }
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 9af20d0..8cf375a 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -20,6 +20,8 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.UriPermission;
+import android.content.pm.ParceledListSlice;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -63,6 +65,7 @@
 import java.io.PrintWriter;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Objects;
 
 public class ExternalStorageProvider extends DocumentsProvider {
     private static final String TAG = "ExternalStorage";
@@ -502,6 +505,70 @@
         return getDocIdForFile(file);
     }
 
+    private Uri getDocumentUri(String path, List<UriPermission> accessUriPermissions)
+            throws FileNotFoundException {
+        File doc = new File(path);
+
+        final String docId = getDocIdForFile(doc);
+
+        UriPermission docUriPermission = null;
+        UriPermission treeUriPermission = null;
+        for (UriPermission uriPermission : accessUriPermissions) {
+            final Uri uri = uriPermission.getUri();
+            if (AUTHORITY.equals(uri.getAuthority())) {
+                boolean matchesRequestedDoc = false;
+                if (DocumentsContract.isTreeUri(uri)) {
+                    final String parentDocId = DocumentsContract.getTreeDocumentId(uri);
+                    File parentFile = getFileForDocId(parentDocId);
+                    if (FileUtils.contains(parentFile, doc)) {
+                        treeUriPermission = uriPermission;
+                        matchesRequestedDoc = true;
+                    }
+                } else {
+                    final String candidateDocId = DocumentsContract.getDocumentId(uri);
+                    final File candidateDoc = getFileForDocId(candidateDocId);
+                    if (Objects.equals(doc.getAbsolutePath(), candidateDoc.getAbsolutePath())) {
+                        docUriPermission = uriPermission;
+                        matchesRequestedDoc = true;
+                    }
+                }
+
+                if (matchesRequestedDoc && allowsBothReadAndWrite(uriPermission)) {
+                    // This URI permission provides everything an app can get, no need to
+                    // further check any other granted URI.
+                    break;
+                }
+            }
+        }
+
+        // Full permission URI first.
+        if (allowsBothReadAndWrite(treeUriPermission)) {
+            return DocumentsContract.buildDocumentUriUsingTree(treeUriPermission.getUri(), docId);
+        }
+
+        if (allowsBothReadAndWrite(docUriPermission)) {
+            return docUriPermission.getUri();
+        }
+
+        // Then partial permission URI.
+        if (treeUriPermission != null) {
+            return DocumentsContract.buildDocumentUriUsingTree(treeUriPermission.getUri(), docId);
+        }
+
+        if (docUriPermission != null) {
+            return docUriPermission.getUri();
+        }
+
+        throw new SecurityException("The app is not given any access to the document under path " +
+                path + " with permissions granted in " + accessUriPermissions);
+    }
+
+    private static boolean allowsBothReadAndWrite(UriPermission permission) {
+        return permission != null
+                && permission.isReadPermission()
+                && permission.isWritePermission();
+    }
+
     @Override
     public String renameDocument(String docId, String displayName) throws FileNotFoundException {
         // Since this provider treats renames as generating a completely new
@@ -721,6 +788,21 @@
                     }
                     break;
                 }
+                case "getDocumentId": {
+                    final String path = arg;
+                    final List<UriPermission> accessUriPermissions =
+                            extras.getParcelableArrayList(AUTHORITY + ".extra.uriPermissions");
+
+                    try {
+                        final Bundle out = new Bundle();
+                        final Uri uri = getDocumentUri(path, accessUriPermissions);
+                        out.putParcelable(DocumentsContract.EXTRA_URI, uri);
+                        return out;
+                    } catch (FileNotFoundException e) {
+                        throw new IllegalStateException("File in " + path + " is not found.", e);
+                    }
+
+                }
                 default:
                     Log.w(TAG, "unknown method passed to call(): " + method);
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
index d12417b..e3ab05d 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -16,7 +16,7 @@
 
 package com.android.keyguard;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.Intent;
@@ -171,7 +171,7 @@
         // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
         mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
         try {
-            ActivityManagerNative.getDefault().stopSystemLockTaskMode();
+            ActivityManager.getService().stopSystemLockTaskMode();
         } catch (RemoteException e) {
             Slog.w(LOG_TAG, "Failed to stop app pinning");
         }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 66e56e0..6a2949a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -28,7 +28,6 @@
 import static android.os.BatteryManager.EXTRA_STATUS;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.UserSwitchObserver;
@@ -459,7 +458,7 @@
         try {
             final int userId;
             try {
-                userId = ActivityManagerNative.getDefault().getCurrentUser().id;
+                userId = ActivityManager.getService().getCurrentUser().id;
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to get current user id: ", e);
                 return;
@@ -1088,7 +1087,7 @@
 
         mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
         try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(
+            ActivityManager.getService().registerUserSwitchObserver(
                     new UserSwitchObserver() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
diff --git a/packages/Osu/src/com/android/hotspot2/flow/PlatformAdapter.java b/packages/Osu/src/com/android/hotspot2/flow/PlatformAdapter.java
index 43cc1d6..d95af61 100644
--- a/packages/Osu/src/com/android/hotspot2/flow/PlatformAdapter.java
+++ b/packages/Osu/src/com/android/hotspot2/flow/PlatformAdapter.java
@@ -530,7 +530,8 @@
 
     private int addSP(String xml) throws IOException, SAXException {
         WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        return wifiManager.addPasspointManagementObject(xml);
+        // TODO(b/32883320): use the new API for adding Passpoint configuration.
+        return 0;
     }
 
     private int modifySP(HomeSP homeSP, Collection<MOData> mods) throws IOException {
@@ -540,7 +541,8 @@
             defMods.add(new PasspointManagementObjectDefinition(mod.getBaseURI(),
                     mod.getURN(), mod.getMOTree().toXml()));
         }
-        return wifiManager.modifyPasspointManagementObject(homeSP.getFQDN(), defMods);
+        // TODO(b/32883320): use the new API to update Passpoint configuration.
+        return 0;
     }
 
     private void reconnect(Network osuNetwork, int newNwkId) {
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index ac9de74..ea03fb6 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -339,6 +339,6 @@
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"較大"</string>
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"最大"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
-    <string name="help_feedback_label" msgid="6815040660801785649">"說明與意見反映"</string>
+    <string name="help_feedback_label" msgid="6815040660801785649">"說明和意見反映"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"選單"</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 9608daa..24ede16 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -116,6 +116,10 @@
         List<BluetoothDevice> sinks = getConnectedDevices();
         if (sinks != null) {
             for (BluetoothDevice sink : sinks) {
+                if (sink.equals(device)) {
+                    Log.w(TAG, "Connecting to device " + device + " : disconnect skipped");
+                    continue;
+                }
                 mService.disconnect(sink);
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index e07856e..7e3f67b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -39,6 +39,8 @@
     public static final String CATEGORY_SYSTEM_INPUT = "com.android.settings.category.ia.input";
     public static final String CATEGORY_SYSTEM_LANGUAGE =
             "com.android.settings.category.ia.language";
+    public static final String CATEGORY_SYSTEM_DEVELOPMENT =
+            "com.android.settings.category.ia.development";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index ed411be..f3658c3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -18,19 +18,24 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.settingslib.applications.InterestingConfigChanges;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import static java.lang.String.CASE_INSENSITIVE_ORDER;
+
 public class CategoryManager {
 
     private static final String TAG = "CategoryManager";
@@ -111,6 +116,8 @@
                 mCategoryByKeyMap.put(category.key, category);
             }
             backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+            normalizePriority(context, mCategoryByKeyMap);
+            filterDuplicateTiles(mCategoryByKeyMap);
         }
     }
 
@@ -163,4 +170,81 @@
             }
         }
     }
+
+    /**
+     * Normalize priority values on tiles across injected from all apps to make sure they don't set
+     * the same priority value. However internal tiles' priority remains unchanged.
+     * <p/>
+     * A list of tiles are considered normalized when their priority value increases in a linear
+     * scan.
+     */
+    @VisibleForTesting
+    synchronized void normalizePriority(Context context,
+            Map<String, DashboardCategory> categoryByKeyMap) {
+        for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+            normalizePriorityForExternalTiles(context, categoryEntry.getValue());
+        }
+    }
+
+    /**
+     * Filter out duplicate tiles from category. Duplicate tiles are the ones pointing to the
+     * same intent.
+     */
+    @VisibleForTesting
+    synchronized void filterDuplicateTiles(Map<String, DashboardCategory> categoryByKeyMap) {
+        for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+            final DashboardCategory category = categoryEntry.getValue();
+            final int count = category.tiles.size();
+            final Set<ComponentName> components = new ArraySet<>();
+            for (int i = count - 1; i >= 0; i--) {
+                final Tile tile = category.tiles.get(i);
+                if (tile.intent == null) {
+                    continue;
+                }
+                final ComponentName tileComponent = tile.intent.getComponent();
+                if (components.contains(tileComponent)) {
+                    category.tiles.remove(i);
+                } else {
+                    components.add(tileComponent);
+                }
+            }
+        }
+    }
+
+    /**
+     * Normalize priority value for tiles within a single {@code DashboardCategory}.
+     *
+     * @see #normalizePriority(Context, Map)
+     */
+    private synchronized void normalizePriorityForExternalTiles(Context context,
+            DashboardCategory dashboardCategory) {
+        final String skipPackageName = context.getPackageName();
+
+        // Sort tiles based on [package, priority within package]
+        Collections.sort(dashboardCategory.tiles, (tile1, tile2) -> {
+            final String package1 = tile1.intent.getComponent().getPackageName();
+            final String package2 = tile2.intent.getComponent().getPackageName();
+            final int packageCompare = CASE_INSENSITIVE_ORDER.compare(package1, package2);
+            // First sort by package name
+            if (packageCompare != 0) {
+                return packageCompare;
+            } else if (TextUtils.equals(package1, skipPackageName)) {
+                return 0;
+            }
+            // Then sort by priority
+            return tile1.priority - tile2.priority;
+        });
+        // Update priority for all items so no package define the same priority value.
+        final int count = dashboardCategory.tiles.size();
+        for (int i = 0; i < count; i++) {
+            final String packageName =
+                    dashboardCategory.tiles.get(i).intent.getComponent().getPackageName();
+            if (TextUtils.equals(packageName, skipPackageName)) {
+                // We skip this tile because it's a intent pointing to our own app. We trust the
+                // priority is set correctly, so don't normalize.
+                continue;
+            }
+            dashboardCategory.tiles.get(i).priority = i;
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index a0254cd..b209f4e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -58,9 +58,10 @@
         allKeys.add(CategoryKey.CATEGORY_SYSTEM);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_INPUT);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
+        allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
         // DO NOT REMOVE ANYTHING ABOVE
 
-        assertThat(allKeys.size()).isEqualTo(13);
+        assertThat(allKeys.size()).isEqualTo(14);
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
index 380f622..573ec1f0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
@@ -16,7 +16,9 @@
 
 package com.android.settingslib.drawer;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.util.Pair;
 
 import com.android.settingslib.TestConfig;
@@ -116,4 +118,170 @@
         // Old category still exists.
         assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1);
     }
+
+    @Test
+    public void normalizePriority_singlePackage_shouldReorderBasedOnPriority() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage = "com.android.test";
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 50;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 200;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify they are now sorted.
+        assertThat(category.tiles.get(0)).isSameAs(tile2);
+        assertThat(category.tiles.get(1)).isSameAs(tile1);
+        assertThat(category.tiles.get(2)).isSameAs(tile3);
+        // Verify their priority is normalized
+        assertThat(category.tiles.get(0).priority).isEqualTo(0);
+        assertThat(category.tiles.get(1).priority).isEqualTo(1);
+        assertThat(category.tiles.get(2).priority).isEqualTo(2);
+    }
+
+    @Test
+    public void normalizePriority_multiPackage_shouldReorderBasedOnPackageAndPriority() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage1 = "com.android.test1";
+        final String testPackage2 = "com.android.test2";
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage1, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage1, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify they are now sorted.
+        assertThat(category.tiles.get(0)).isSameAs(tile3);
+        assertThat(category.tiles.get(1)).isSameAs(tile2);
+        assertThat(category.tiles.get(2)).isSameAs(tile1);
+        // Verify their priority is normalized
+        assertThat(category.tiles.get(0).priority).isEqualTo(0);
+        assertThat(category.tiles.get(1).priority).isEqualTo(1);
+        assertThat(category.tiles.get(2).priority).isEqualTo(2);
+    }
+
+    @Test
+    public void normalizePriority_internalPackageTiles_shouldSkipTileForInternalPackage() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify the sorting order is not changed
+        assertThat(category.tiles.get(0)).isSameAs(tile1);
+        assertThat(category.tiles.get(1)).isSameAs(tile2);
+        assertThat(category.tiles.get(2)).isSameAs(tile3);
+        // Verify their priorities are not changed.
+        assertThat(category.tiles.get(0).priority).isEqualTo(100);
+        assertThat(category.tiles.get(1).priority).isEqualTo(100);
+        assertThat(category.tiles.get(2).priority).isEqualTo(50);
+    }
+
+    @Test
+    public void filterTiles_noDuplicate_noChange() {
+        // Create some unique tiles
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+        assertThat(category.tiles.size()).isEqualTo(3);
+    }
+
+    @Test
+    public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() {
+        // Create tiles pointing to same intent.
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+        assertThat(category.tiles.size()).isEqualTo(1);
+    }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index dd543a3..d784a3a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -645,7 +645,7 @@
 
         if (upgradeVersion == 45) {
              /*
-              * New settings for MountService
+              * New settings for StorageManagerService
               */
             db.beginTransaction();
             try {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index bf48e5d..1c51773 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.providers.settings;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.backup.IBackupManager;
 import android.content.ContentResolver;
@@ -343,7 +343,7 @@
         if (loc == null) return; // Couldn't find the saved locale in this version of the software
 
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             Configuration config = am.getConfiguration();
             config.locale = loc;
             // indicate this isn't some passing default - the user wants this remembered
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index 169b01f..461573f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -16,7 +16,7 @@
 
 package com.android.providers.settings;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.IContentProvider;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
@@ -190,7 +190,7 @@
 
             if (mUser == UserHandle.USER_CURRENT) {
                 try {
-                    mUser = ActivityManagerNative.getDefault().getCurrentUser().id;
+                    mUser = ActivityManager.getService().getCurrentUser().id;
                 } catch (RemoteException e) {
                     throw new RuntimeException("Failed in IPC", e);
                 }
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index f6e558f..15ce90f 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -40,8 +40,7 @@
     private static final String TAG = "BugreportReceiver";
 
     /**
-     * Always keep the newest 8 bugreport files; 4 reports and 4 screenshots are
-     * roughly 17MB of disk space.
+     * Always keep the newest 8 bugreport files.
      */
     private static final int MIN_KEEP_COUNT = 8;
 
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b0a828f..8e34bd0 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -263,7 +263,7 @@
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Forstyr ikke"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Kun prioritet"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Kun Alarmer"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Kun alarmer"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Total stilhed"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> enheder)"</string>
@@ -356,7 +356,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Helt lydløs. Denne handling slukker også skærmlæsere."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Total stilhed"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"Kun prioritet"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"Kun Alarmer"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Kun alarmer"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nstilhed"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kun\nprioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kun\nalarmer"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 9a64a41..3a8536b 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -66,7 +66,7 @@
 
             UserInfo currentUser;
             try {
-                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+                currentUser = ActivityManager.getService().getCurrentUser();
             } catch (RemoteException e) {
                 return;
             }
@@ -96,7 +96,7 @@
         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         UserInfo currentUser;
         try {
-            currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            currentUser = ActivityManager.getService().getCurrentUser();
         } catch (RemoteException e) {
             Log.e(TAG, "Couldn't wipe session because ActivityManager is dead");
             return;
@@ -122,12 +122,12 @@
         try {
             if (newGuest == null) {
                 Log.e(TAG, "Could not create new guest, switching back to system user");
-                ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM);
+                ActivityManager.getService().switchUser(UserHandle.USER_SYSTEM);
                 userManager.removeUser(currentUser.id);
                 WindowManagerGlobal.getWindowManagerService().lockNow(null /* options */);
                 return;
             }
-            ActivityManagerNative.getDefault().switchUser(newGuest.id);
+            ActivityManager.getService().switchUser(newGuest.id);
             userManager.removeUser(currentUser.id);
         } catch (RemoteException e) {
             Log.e(TAG, "Couldn't wipe session because ActivityManager or WindowManager is dead");
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 8f1a943..34dc63f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -23,7 +23,6 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.SearchManager;
@@ -1619,7 +1618,7 @@
     private void updateActivityLockScreenState() {
         Trace.beginSection("KeyguardViewMediator#updateActivityLockScreenState");
         try {
-            ActivityManagerNative.getDefault().setLockScreenShown(mShowing);
+            ActivityManager.getService().setLockScreenShown(mShowing);
         } catch (RemoteException e) {
         }
         Trace.endSection();
@@ -1681,7 +1680,7 @@
                 // Don't actually hide the Keyguard at the moment, wait for window
                 // manager until it tells us it's safe to do so with
                 // startKeyguardExitAnimation.
-                ActivityManagerNative.getDefault().keyguardGoingAway(flags);
+                ActivityManager.getService().keyguardGoingAway(flags);
             } catch (RemoteException e) {
                 Log.e(TAG, "Error while calling WindowManager", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 7b8d27e..43cfa32 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.pip.phone;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.Context;
 import android.view.IWindowManager;
@@ -44,7 +44,7 @@
      */
     public void initialize(Context context) {
         mContext = context;
-        mActivityManager = ActivityManagerNative.getDefault();
+        mActivityManager = ActivityManager.getService();
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
 
         mMenuController = new PipMenuActivityController(context, mActivityManager, mWindowManager);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 5b93aa2..a622656 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.pip.tv;
 
+import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackInfo;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -208,7 +208,7 @@
         mInitialized = true;
         mContext = context;
 
-        mActivityManager = ActivityManagerNative.getDefault();
+        mActivityManager = ActivityManager.getService();
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
         SystemServicesProxy.getInstance(context).registerTaskStackListener(mTaskStackListener);
         IntentFilter intentFilter = new IntentFilter();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index b961055..cf75c4f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -19,7 +19,6 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -117,7 +116,7 @@
     public void onClick(View v) {
         if (v.getId() == R.id.screen_pinning_ok_button || mRequestWindow == v) {
             try {
-                ActivityManagerNative.getDefault().startSystemLockTaskMode(taskId);
+                ActivityManager.getService().startSystemLockTaskMode(taskId);
             } catch (RemoteException e) {}
         }
         clearPrompt();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index ea9714f..2272a72 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -25,7 +25,6 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -157,7 +156,7 @@
 
     /**
      * Implementation of {@link android.app.ITaskStackListener} to listen task stack changes from
-     * ActivityManagerNative.
+     * ActivityManagerService.
      * This simply passes callbacks to listeners through {@link H}.
      * */
     private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() {
@@ -207,7 +206,7 @@
     private SystemServicesProxy(Context context) {
         mAccm = AccessibilityManager.getInstance(context);
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        mIam = ActivityManagerNative.getDefault();
+        mIam = ActivityManager.getService();
         mPm = context.getPackageManager();
         mIpm = AppGlobals.getPackageManager();
         mAssistUtils = new AssistUtils(context);
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 2684722..19eefec 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -18,7 +18,6 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -59,7 +58,7 @@
 
     private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this);
     private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
-    private IActivityManager mActivityManager = ActivityManagerNative.getDefault();
+    private IActivityManager mActivityManager = ActivityManager.getService();
 
     protected final long META_MASK = ((long) KeyEvent.META_META_ON) << Integer.SIZE;
     protected final long ALT_MASK = ((long) KeyEvent.META_ALT_ON) << Integer.SIZE;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index ef32f7e..c245126 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -19,7 +19,7 @@
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.view.WindowManager.DOCKED_INVALID;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.Log;
@@ -72,7 +72,7 @@
                 mTmpRect5.set(mTempOtherInsetRect);
             }
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                         .resizeDockedStack(mTmpRect1,
                                 mTmpRect2.isEmpty() ? null : mTmpRect2,
                                 mTmpRect3.isEmpty() ? null : mTmpRect3,
@@ -88,7 +88,7 @@
         @Override
         public void run() {
             try {
-                ActivityManagerNative.getDefault().moveTasksToFullscreenStack(
+                ActivityManager.getService().moveTasksToFullscreenStack(
                         DOCKED_STACK_ID, false /* onTop */);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to remove stack: " + e);
@@ -100,7 +100,7 @@
         @Override
         public void run() {
             try {
-                ActivityManagerNative.getDefault().resizeStack(
+                ActivityManager.getService().resizeStack(
                         DOCKED_STACK_ID, null, true, true, false, -1);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to resize stack: " + e);
@@ -124,7 +124,7 @@
         @Override
         public void run() {
             try {
-                ActivityManagerNative.getDefault().swapDockedAndFullscreenStack();
+                ActivityManager.getService().swapDockedAndFullscreenStack();
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to resize stack: " + e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 93ddd17..19e511cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -20,7 +20,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -334,7 +333,7 @@
             // the user switches to home.  We know it is safe to do at this
             // point, so make sure new activity switches are now allowed.
             try {
-                ActivityManagerNative.getDefault().resumeAppSwitches();
+                ActivityManager.getService().resumeAppSwitches();
             } catch (RemoteException e) {
             }
             final boolean isActivity = pendingIntent.isActivity();
@@ -346,7 +345,7 @@
                     @Override
                     public boolean onDismiss() {
                         try {
-                            ActivityManagerNative.getDefault().resumeAppSwitches();
+                            ActivityManager.getService().resumeAppSwitches();
                         } catch (RemoteException e) {
                         }
 
@@ -515,7 +514,7 @@
             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                 List<ActivityManager.RecentTaskInfo> recentTask = null;
                 try {
-                    recentTask = ActivityManagerNative.getDefault().getRecentTasks(1,
+                    recentTask = ActivityManager.getService().getRecentTasks(1,
                             ActivityManager.RECENT_WITH_EXCLUDED
                             | ActivityManager.RECENT_INCLUDE_PROFILES,
                             mCurrentUserId).getList();
@@ -1321,7 +1320,7 @@
 
     protected void sendCloseSystemWindows(String reason) {
         try {
-            ActivityManagerNative.getDefault().closeSystemDialogs(reason);
+            ActivityManager.getService().closeSystemDialogs(reason);
         } catch (RemoteException e) {
         }
     }
@@ -1820,7 +1819,7 @@
                             // won't have permission to immediately start an activity after
                             // the user switches to home.  We know it is safe to do at this
                             // point, so make sure new activity switches are now allowed.
-                            ActivityManagerNative.getDefault().resumeAppSwitches();
+                            ActivityManager.getService().resumeAppSwitches();
                         } catch (RemoteException e) {
                         }
                         try {
@@ -1924,7 +1923,7 @@
                                 // won't have permission to immediately start an activity after
                                 // the user switches to home.  We know it is safe to do at this
                                 // point, so make sure new activity switches are now allowed.
-                                ActivityManagerNative.getDefault().resumeAppSwitches();
+                                ActivityManager.getService().resumeAppSwitches();
                             } catch (RemoteException e) {
                             }
                             if (intent != null) {
@@ -1938,7 +1937,7 @@
                                             && mKeyguardManager.isDeviceLocked(userId)) {
                                         boolean canBypass = false;
                                         try {
-                                            canBypass = ActivityManagerNative.getDefault()
+                                            canBypass = ActivityManager.getService()
                                                     .canBypassWorkChallenge(intent);
                                         } catch (RemoteException e) {
                                         }
@@ -2058,7 +2057,7 @@
                 Intent.EXTRA_INTENT,
                 callBackPendingIntent.getIntentSender());
         try {
-            ActivityManagerNative.getDefault().startConfirmDeviceCredentialIntent(newIntent);
+            ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent);
         } catch (RemoteException ex) {
             // ignore
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 8a5a8a0..dd5832b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.car;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -256,7 +255,7 @@
     private int startActivityWithOptions(Intent intent, Bundle options) {
         int result = ActivityManager.START_CANCELED;
         try {
-            result = ActivityManagerNative.getDefault().startActivityAsUser(null /* caller */,
+            result = ActivityManager.getService().startActivityAsUser(null /* caller */,
                     mContext.getBasePackageName(),
                     intent,
                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index dbae6b8..89defec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -20,7 +20,6 @@
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
@@ -363,7 +362,7 @@
                 (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (dpm != null && mPhoneStatusBar != null) {
             try {
-                final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
+                final int userId = ActivityManager.getService().getCurrentUser().id;
                 final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
                 final  boolean disabledBecauseKeyguardSecure =
                         (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
@@ -487,7 +486,7 @@
                     o.setRotationAnimationHint(
                             WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
                     try {
-                        result = ActivityManagerNative.getDefault().startActivityAsUser(
+                        result = ActivityManager.getService().startActivityAsUser(
                                 null, getContext().getBasePackageName(),
                                 intent,
                                 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index df167e6..97df237 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -21,7 +21,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -422,7 +422,7 @@
 
     private boolean inLockTask() {
         try {
-            return ActivityManagerNative.getDefault().isInLockTaskMode();
+            return ActivityManager.getService().isInLockTaskMode();
         } catch (RemoteException e) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 69d76e5..068631d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1226,7 +1226,7 @@
     }
 
     private String getKeyguardOrLockScreenString() {
-        if (mQs.isCustomizing()) {
+        if (mQs != null && mQs.isCustomizing()) {
             return getContext().getString(R.string.accessibility_desc_quick_settings_edit);
         } else if (mStatusBarState == StatusBarState.KEYGUARD) {
             return getContext().getString(R.string.accessibility_desc_lock_screen);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 31a93f0..c4fb21e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -34,7 +34,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
 import android.app.Notification;
@@ -3516,7 +3515,7 @@
                             WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
                 }
                 try {
-                    result = ActivityManagerNative.getDefault().startActivityAsUser(
+                    result = ActivityManager.getService().startActivityAsUser(
                             null, mContext.getBasePackageName(),
                             intent,
                             intent.resolveTypeIfNeeded(mContext.getContentResolver()),
@@ -4897,7 +4896,7 @@
      */
     private boolean handleLongPressBack() {
         try {
-            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            IActivityManager activityManager = ActivityManager.getService();
             if (activityManager.isInLockTaskMode()) {
                 activityManager.stopSystemLockTaskMode();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 032c86b..9ee1e8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AlarmManager.AlarmClockInfo;
 import android.app.SynchronousUserSwitchObserver;
@@ -146,7 +145,7 @@
 
         // listen for user / profile change.
         try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchListener, TAG);
+            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
         } catch (RemoteException e) {
             // Ignore
         }
@@ -380,7 +379,7 @@
         UserInfo user = null;
         if (userId == UserHandle.USER_CURRENT) {
             try {
-                user = ActivityManagerNative.getDefault().getCurrentUser();
+                user = ActivityManager.getService().getCurrentUser();
             } catch (RemoteException e) {
                 // Ignore
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 4a2d5dc..995f4dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -64,7 +64,7 @@
     public StatusBarWindowManager(Context context) {
         mContext = context;
         mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        mActivityManager = ActivityManagerNative.getDefault();
+        mActivityManager = ActivityManager.getService();
         mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
         mScreenBrightnessDoze = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
index 17b22df..c09747b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -93,7 +93,7 @@
             if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) ||
                     Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
                 try {
-                    final int currentUser = ActivityManagerNative.getDefault().getCurrentUser().id;
+                    final int currentUser = ActivityManager.getService().getCurrentUser().id;
                     final int changedUser =
                             intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId());
                     if (changedUser == currentUser) {
@@ -118,7 +118,7 @@
         Context currentUserContext;
         UserInfo userInfo;
         try {
-            userInfo = ActivityManagerNative.getDefault().getCurrentUser();
+            userInfo = ActivityManager.getService().getCurrentUser();
             currentUserContext = mContext.createPackageContextAsUser("android", 0,
                     new UserHandle(userInfo.id));
         } catch (PackageManager.NameNotFoundException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 9d9c908..bb4b91e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -19,7 +19,6 @@
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.Dialog;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -412,7 +411,7 @@
     protected void switchToUserId(int id) {
         try {
             pauseRefreshUsers();
-            ActivityManagerNative.getDefault().switchUser(id);
+            ActivityManager.getService().switchUser(id);
         } catch (RemoteException e) {
             Log.e(TAG, "Couldn't switch user.", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java
index e5bb3d5..a068172 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java
@@ -40,12 +40,13 @@
     @Override
     public void onAttached() {
         super.onAttached();
-        File file = new File("/vendor/overlay");
-        ArrayList<String> options = Lists.newArrayList(file.list());
         String def = SystemProperties.get("ro.boot.vendor.overlay.theme");
         if (TextUtils.isEmpty(def)) {
             def = getContext().getString(R.string.default_theme);
         }
+        String[] fileList = new File("/vendor/overlay").list();
+        ArrayList<String> options = fileList != null
+                ? Lists.newArrayList(fileList) : new ArrayList<>();
         if (!options.contains(def)) {
             options.add(0, def);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 8ca277e..42b06b2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -797,7 +797,7 @@
 
         // update slider
         final boolean enableSlider = !zenMuted;
-        final int vlevel = row.ss.muted && (isRingVibrate || !isRingStream && !zenMuted) ? 0
+        final int vlevel = row.ss.muted && (!isRingStream && !zenMuted) ? 0
                 : row.ss.level;
         updateVolumeRowSliderH(row, enableSlider, vlevel);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 87f6138..12a00e9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -552,8 +552,9 @@
             setToMidnight(nextAlarm);
 
             if (weekRange.compareTo(nextAlarm) >= 0) {
-                return ZenModeConfig.toNextAlarmCondition(mContext, now,
-                        nextAlarmMs, ActivityManager.getCurrentUser());
+                return ZenModeConfig.toTimeCondition(mContext, nextAlarmMs,
+                        Math.round((nextAlarmMs - now) / (float) MINUTES_MS),
+                        ActivityManager.getCurrentUser(), true);
             }
         }
         return null;
diff --git a/preloaded-classes b/preloaded-classes
index 45734b6..a79ae50 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -327,9 +327,6 @@
 android.app.ActivityManager$StackId
 android.app.ActivityManager$TaskDescription
 android.app.ActivityManager$TaskDescription$1
-android.app.ActivityManagerNative
-android.app.ActivityManagerNative$1
-android.app.ActivityManagerProxy
 android.app.ActivityOptions
 android.app.ActivityThread
 android.app.ActivityThread$1
@@ -1729,9 +1726,9 @@
 android.os.Vibrator
 android.os.ZygoteStartFailedEx
 android.os.health.SystemHealthManager
-android.os.storage.IMountService
-android.os.storage.IMountService$Stub
-android.os.storage.IMountService$Stub$Proxy
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
 android.os.storage.StorageManager
 android.os.storage.StorageVolume
 android.os.storage.StorageVolume$1
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 5cf74c7..45f2ec7 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -22,6 +22,27 @@
 // Wrapper for System UI log events
 message MetricsEvent {
 
+  // Types of events
+  enum Type {
+    // Unknown
+    TYPE_UNKNOWN = 0;
+
+    // The view became visible to the user.
+    TYPE_OPEN = 1;
+
+    // The view became hidden.
+    TYPE_CLOSE = 2;
+
+    // The view switched to detail mode (most relevant for quick settings tiles)
+    TYPE_DETAIL = 3;
+
+    // The view or control was activated.
+    TYPE_ACTION = 4;
+
+    // The view or control was dismissed.
+    TYPE_DISMISS = 5;
+  }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -2632,6 +2653,12 @@
     // OS: O
     ENTERPRISE_PRIVACY_SETTINGS = 628;
 
+    // ACTION: Longpress on a TextView.
+    //  SUBTYPE: 1 is for START_SELECTION, 2 is for START_DRAG_AND_DROP, 0 is for OTHER.
+    // CATEGORY: TEXT_CONTROLS
+    // OS: O
+    TEXT_LONGPRESS = 629;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index bf60e47..6404604 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1593,14 +1593,6 @@
 
         // Make sure the package runs under the caller uid.
         mSecurityPolicy.enforceCallFromPackage(callingPackage);
-
-        final int bitmapMemoryUsage = (views != null) ? views.estimateMemoryUsage() : 0;
-        if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
-            throw new IllegalArgumentException("RemoteViews for widget update exceeds"
-                    + " maximum bitmap memory usage (used: " + bitmapMemoryUsage
-                    + ", max: " + mMaxWidgetBitmapMemory + ")");
-        }
-
         synchronized (mLock) {
             ensureGroupStateLoadedLocked(userId);
 
@@ -1812,6 +1804,15 @@
                 // For a full update we replace the RemoteViews completely.
                 widget.views = views;
             }
+            int memoryUsage;
+            if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) &&
+                    (widget.views != null) &&
+                    ((memoryUsage = widget.views.estimateMemoryUsage()) > mMaxWidgetBitmapMemory)) {
+                widget.views = null;
+                throw new IllegalArgumentException("RemoteViews for widget update exceeds"
+                        + " maximum bitmap memory usage (used: " + memoryUsage
+                        + ", max: " + mMaxWidgetBitmapMemory + ")");
+            }
             scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 9157e83..d70c439 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -20,26 +20,32 @@
 import static android.content.Context.AUTO_FILL_MANAGER_SERVICE;
 
 import android.Manifest;
-import android.app.ActivityManager;
 import android.app.AppGlobals;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.service.autofill.IAutoFillManagerService;
 import android.text.TextUtils;
@@ -56,6 +62,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * Entry point service for auto-fill management.
@@ -88,6 +95,9 @@
                 case MSG_UNBIND:
                     removeStaleServiceForUser(msg.arg1);
                     return;
+                case MSG_SHOW_ALL_NOTIFICATIONS:
+                    showAllNotifications();
+                    return;
                 default:
                     Slog.w(TAG, "Invalid message: " + msg);
             }
@@ -131,6 +141,14 @@
         if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
             new SettingsObserver(BackgroundThread.getHandler());
         }
+        if (phase == PHASE_BOOT_COMPLETED) {
+            // TODO: if sent right away, the notification is not displayed. Since the notification
+            // mechanism is a temporary approach anyways, just delay it..
+            if (DEBUG)
+                Slog.d(TAG, "Showing notifications in " + SHOW_ALL_NOTIFICATIONS_DELAY_MS + "ms");
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ALL_NOTIFICATIONS),
+                    SHOW_ALL_NOTIFICATIONS_DELAY_MS);
+        }
     }
 
     private AutoFillManagerServiceImpl newServiceForUser(int userId) {
@@ -224,6 +242,7 @@
         }
         mServicesCache.delete(userId);
         service.stopLocked();
+
     }
 
     final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
@@ -287,7 +306,136 @@
             if (DEBUG) Slog.d(TAG, "settings (" + uri + " changed for " + userId);
             synchronized (mLock) {
                 removeCachedServiceForUserLocked(userId);
+                final ComponentName serviceComponent = getProviderForUser(userId);
+                if (serviceComponent== null) {
+                    cancelNotificationLocked(userId);
+                } else {
+                    showNotification(serviceComponent, userId);
+                }
             }
         }
     }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // TODO: temporary code using a notification to request auto-fill.        //
+    // Will be removed once UX decide the right way to present it to the user //
+    ////////////////////////////////////////////////////////////////////////////
+
+    // TODO: remove from frameworks/base/core/res/AndroidManifest.xml once it's not used anymore
+    private static final String NOTIFICATION_INTENT =
+            "com.android.internal.autofill.action.REQUEST_AUTOFILL";
+    private static final String EXTRA_USER_ID = "user_id";
+
+    private static final int MSG_SHOW_ALL_NOTIFICATIONS = 42;
+    private static final int SHOW_ALL_NOTIFICATIONS_DELAY_MS = 5000;
+
+    private BroadcastReceiver mNotificationReceiver;
+
+    final class NotificationReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final int userId = intent.getIntExtra(EXTRA_USER_ID, -1);
+            if (DEBUG) Slog.d(TAG, "Requesting autofill by notification for user " + userId);
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                if (service == null) {
+                    Slog.w(TAG, "no auto-fill service for user " + userId);
+                } else {
+                    service.requestAutoFill(null);
+                }
+            }
+        }
+    }
+
+    private ComponentName getProviderForUser(int userId) {
+        ComponentName serviceComponent = null;
+        ServiceInfo serviceInfo = null;
+        final String componentName = Settings.Secure.getStringForUser(
+                mResolver, Settings.Secure.AUTO_FILL_SERVICE, userId);
+        if (!TextUtils.isEmpty(componentName)) {
+            try {
+                serviceComponent = ComponentName.unflattenFromString(componentName);
+                serviceInfo =
+                        AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, userId);
+            } catch (RuntimeException | RemoteException e) {
+                Slog.wtf(TAG, "Bad auto-fill service name " + componentName, e);
+                return null;
+            }
+        }
+
+        if (DEBUG) Slog.d(TAG, "getServiceComponentForUser(" + userId + "): component="
+                + serviceComponent + ", info: " + serviceInfo);
+        if (serviceInfo == null) {
+            Slog.w(TAG, "no service info for " + serviceComponent);
+            return null;
+        }
+        return serviceComponent;
+    }
+
+    private void showAllNotifications() {
+        final UserManager userManager =
+                (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        final List<UserInfo> allUsers = userManager.getUsers(true);
+
+        for (UserInfo user : allUsers) {
+            final ComponentName serviceComponent = getProviderForUser(user.id);
+            if (serviceComponent != null) {
+                showNotification(serviceComponent, user.id);
+            }
+        }
+    }
+
+    private void showNotification(ComponentName serviceComponent, int userId) {
+        if (DEBUG) Log.d(TAG, "showNotification() for " + userId + ": " + serviceComponent);
+
+        synchronized (mLock) {
+            if (mNotificationReceiver == null) {
+                mNotificationReceiver = new NotificationReceiver();
+                mContext.registerReceiver(mNotificationReceiver,
+                        new IntentFilter(NOTIFICATION_INTENT));
+            }
+        }
+
+        final Intent intent = new Intent(NOTIFICATION_INTENT);
+        intent.putExtra(EXTRA_USER_ID, userId);
+        final PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        final String packageName = serviceComponent.getPackageName();
+        String providerName = null;
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            final ApplicationInfo info = pm.getApplicationInfoAsUser(packageName, 0, userId);
+            if (info != null) {
+                providerName = pm.getApplicationLabel(info).toString();
+            }
+        } catch (Exception e) {
+            providerName = packageName;
+        }
+        final String title = "AutoFill by '" + providerName + "'";
+        final String subTitle = "Tap notification to auto-fill top activity for user " + userId;
+
+        final Notification notification = new Notification.Builder(mContext)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setOngoing(true)
+                .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                .setLocalOnly(true)
+                .setColor(mContext.getColor(
+                        com.android.internal.R.color.system_notification_accent_color))
+                .setContentTitle(title)
+                .setStyle(new Notification.BigTextStyle().bigText(subTitle))
+                .setContentIntent(pi)
+                .build();
+        NotificationManager.from(mContext).notify(userId, notification);
+    }
+
+    private void cancelNotificationLocked(int userId) {
+        if (DEBUG) Log.d(TAG, "cancelNotificationLocked(): " + userId);
+        NotificationManager.from(mContext).cancel(userId);
+    }
+
+    /////////////////////////////////////////
+    // End of temporary notification code. //
+    /////////////////////////////////////////
 }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 6375e9a..8151c8a 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -18,7 +18,7 @@
 
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.ApplicationThreadConstants;
@@ -80,7 +80,7 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.os.Environment.UserEnvironment;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.system.ErrnoException;
@@ -268,7 +268,7 @@
     private IActivityManager mActivityManager;
     private PowerManager mPowerManager;
     private AlarmManager mAlarmManager;
-    private IMountService mMountService;
+    private IStorageManager mStorageManager;
     IBackupManager mBackupManagerBinder;
 
     boolean mEnabled;   // access to this is synchronized on 'this'
@@ -1075,11 +1075,11 @@
         mContext = context;
         mPackageManager = context.getPackageManager();
         mPackageManagerBinder = AppGlobals.getPackageManager();
-        mActivityManager = ActivityManagerNative.getDefault();
+        mActivityManager = ActivityManager.getService();
 
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
 
         mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
 
@@ -3982,14 +3982,14 @@
 
     boolean deviceIsEncrypted() {
         try {
-            return mMountService.getEncryptionState()
+            return mStorageManager.getEncryptionState()
                      != StorageManager.ENCRYPTION_STATE_NONE
-                && mMountService.getPasswordType()
+                && mStorageManager.getPasswordType()
                      != StorageManager.CRYPT_TYPE_DEFAULT;
         } catch (Exception e) {
-            // If we can't talk to the mount service we have a serious problem; fail
+            // If we can't talk to the storagemanager service we have a serious problem; fail
             // "secure" i.e. assuming that the device is encrypted.
-            Slog.e(TAG, "Unable to communicate with mount service: " + e.getMessage());
+            Slog.e(TAG, "Unable to communicate with storagemanager service: " + e.getMessage());
             return true;
         }
     }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 2558045..581aa05 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
@@ -505,7 +504,7 @@
             for (int i = alarms.size()-1; i >= 0; i--) {
                 Alarm alarm = alarms.get(i);
                 try {
-                    if (alarm.uid == uid && ActivityManagerNative.getDefault().getAppStartMode(
+                    if (alarm.uid == uid && ActivityManager.getService().getAppStartMode(
                             uid, alarm.packageName) == ActivityManager.APP_START_MODE_DISABLED) {
                         alarms.remove(i);
                         didRemove = true;
@@ -937,7 +936,7 @@
         }
 
         try {
-            ActivityManagerNative.getDefault().registerUidObserver(new UidObserver(),
+            ActivityManager.getService().registerUidObserver(new UidObserver(),
                     ActivityManager.UID_OBSERVER_IDLE, ActivityManager.PROCESS_STATE_UNKNOWN, null);
         } catch (RemoteException e) {
             // ignored; both services live in system_server
@@ -1090,7 +1089,7 @@
                 operation, directReceiver, listenerTag, workSource, flags, alarmClock,
                 callingUid, callingPackage);
         try {
-            if (ActivityManagerNative.getDefault().getAppStartMode(callingUid, callingPackage)
+            if (ActivityManager.getService().getAppStartMode(callingUid, callingPackage)
                     == ActivityManager.APP_START_MODE_DISABLED) {
                 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
                         + " -- package not allowed to start");
@@ -2414,11 +2413,11 @@
                 if (RECORD_ALARMS_IN_HISTORY) {
                     if (alarm.workSource != null && alarm.workSource.size() > 0) {
                         for (int wi=0; wi<alarm.workSource.size(); wi++) {
-                            ActivityManagerNative.noteAlarmStart(
+                            ActivityManager.noteAlarmStart(
                                     alarm.operation, alarm.workSource.get(wi), alarm.statsTag);
                         }
                     } else {
-                        ActivityManagerNative.noteAlarmStart(
+                        ActivityManager.noteAlarmStart(
                                 alarm.operation, alarm.uid, alarm.statsTag);
                     }
                 }
@@ -2582,7 +2581,7 @@
 
             final int uid = (knownUid >= 0)
                     ? knownUid
-                    : ActivityManagerNative.getDefault().getUidForIntentSender(pi.getTarget());
+                    : ActivityManager.getService().getUidForIntentSender(pi.getTarget());
             if (uid >= 0) {
                 mWakeLock.setWorkSource(new WorkSource(uid));
                 return;
@@ -2881,11 +2880,11 @@
             if (RECORD_ALARMS_IN_HISTORY) {
                 if (inflight.mWorkSource != null && inflight.mWorkSource.size() > 0) {
                     for (int wi=0; wi<inflight.mWorkSource.size(); wi++) {
-                        ActivityManagerNative.noteAlarmFinish(
+                        ActivityManager.noteAlarmFinish(
                                 inflight.mPendingIntent, inflight.mWorkSource.get(wi), inflight.mTag);
                     }
                 } else {
-                    ActivityManagerNative.noteAlarmFinish(
+                    ActivityManager.noteAlarmFinish(
                             inflight.mPendingIntent, inflight.mUid, inflight.mTag);
                 }
             }
@@ -3086,13 +3085,13 @@
                 if (alarm.workSource != null && alarm.workSource.size() > 0) {
                     for (int wi=0; wi<alarm.workSource.size(); wi++) {
                         final String wsName = alarm.workSource.getName(wi);
-                        ActivityManagerNative.noteWakeupAlarm(
+                        ActivityManager.noteWakeupAlarm(
                                 alarm.operation, alarm.workSource.get(wi),
                                 (wsName != null) ? wsName : alarm.packageName,
                                 alarm.statsTag);
                     }
                 } else {
-                    ActivityManagerNative.noteWakeupAlarm(
+                    ActivityManager.noteWakeupAlarm(
                             alarm.operation, alarm.uid, alarm.packageName, alarm.statsTag);
                 }
             }
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 7c2eea3f..570843e 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -54,7 +54,7 @@
 import android.os.ShellCallback;
 import android.os.ShellCommand;
 import android.os.UserHandle;
-import android.os.storage.MountServiceInternal;
+import android.os.storage.StorageManagerInternal;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -294,10 +294,10 @@
             }
         }
 
-        MountServiceInternal mountServiceInternal = LocalServices.getService(
-                MountServiceInternal.class);
-        mountServiceInternal.addExternalStoragePolicy(
-                new MountServiceInternal.ExternalStorageMountPolicy() {
+        StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                StorageManagerInternal.class);
+        storageManagerInternal.addExternalStoragePolicy(
+                new StorageManagerInternal.ExternalStorageMountPolicy() {
                     @Override
                     public int getMountMode(int uid, String packageName) {
                         if (Process.isIsolated(uid)) {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index b88a45e..573ad63 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -28,7 +28,7 @@
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -557,7 +557,7 @@
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
+                ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
             }
         });
     }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 466633a..07322fc 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -17,7 +17,7 @@
 package com.android.server;
 
 import android.Manifest;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -1572,7 +1572,7 @@
                 Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                 "No permission to change device idle whitelist");
         final int callingUid = Binder.getCallingUid();
-        userId = ActivityManagerNative.getDefault().handleIncomingUser(
+        userId = ActivityManager.getService().handleIncomingUser(
                 Binder.getCallingPid(),
                 callingUid,
                 userId,
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 74ff41c..eb2cd0b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -248,7 +248,7 @@
 51501 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
 
 # ---------------------------
-# MountService.java
+# StorageManagerService.java
 # ---------------------------
 2755 fstrim_start (time|2|3)
 2756 fstrim_finish (time|2|3)
diff --git a/services/core/java/com/android/server/InputContentUriTokenHandler.java b/services/core/java/com/android/server/InputContentUriTokenHandler.java
index 3f4972b..57cdc94 100644
--- a/services/core/java/com/android/server/InputContentUriTokenHandler.java
+++ b/services/core/java/com/android/server/InputContentUriTokenHandler.java
@@ -18,7 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Binder;
@@ -64,7 +64,7 @@
             }
 
             try {
-                mPermissionOwnerToken = ActivityManagerNative.getDefault()
+                mPermissionOwnerToken = ActivityManager.getService()
                         .newUriPermissionOwner("InputContentUriTokenHandler");
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
@@ -78,7 +78,7 @@
         long origId = Binder.clearCallingIdentity();
         try {
             try {
-                ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
+                ActivityManager.getService().grantUriPermissionFromOwner(
                         permissionOwner, mSourceUid, mTargetPackage, mUri,
                         Intent.FLAG_GRANT_READ_URI_PERMISSION, mSourceUserId, mTargetUserId);
             } catch (RemoteException e) {
@@ -96,7 +96,7 @@
                 return;
             }
             try {
-                ActivityManagerNative.getDefault().revokeUriPermissionFromOwner(
+                ActivityManager.getService().revokeUriPermissionFromOwner(
                         mPermissionOwnerToken, mUri,
                         Intent.FLAG_GRANT_READ_URI_PERMISSION, mSourceUserId);
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d1f07a5..3dfbdc3 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -49,8 +49,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -907,7 +907,7 @@
         mNotificationShown = false;
         int userId = 0;
         try {
-            userId = ActivityManagerNative.getDefault().getCurrentUser().id;
+            userId = ActivityManager.getService().getCurrentUser().id;
         } catch (RemoteException e) {
             Slog.w(TAG, "Couldn't get current user ID; guessing it's 0", e);
         }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index dd342c5..6701431 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -16,7 +16,7 @@
 
 package com.android.server;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -51,7 +51,7 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -813,7 +813,7 @@
         };
 
         try {
-            ActivityManagerNative.getDefault().unlockUser(userId, token, secret, listener);
+            ActivityManager.getService().unlockUser(userId, token, secret, listener);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -1160,10 +1160,10 @@
     private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
             throws RemoteException {
         final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId);
-        final IMountService mountService = getMountService();
+        final IStorageManager storageManager = getStorageManager();
         final long callingId = Binder.clearCallingIdentity();
         try {
-            mountService.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
+            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
@@ -1171,10 +1171,10 @@
 
     private void fixateNewestUserKeyAuth(int userId)
             throws RemoteException {
-        final IMountService mountService = getMountService();
+        final IStorageManager storageManager = getStorageManager();
         final long callingId = Binder.clearCallingIdentity();
         try {
-            mountService.fixateNewestUserKeyAuth(userId);
+            storageManager.fixateNewestUserKeyAuth(userId);
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
@@ -1488,7 +1488,7 @@
         // we should, within the first minute of decrypting the phone if this
         // service can't connect to vold, it restarts, and then the new instance
         // does successfully connect.
-        final IMountService service = getMountService();
+        final IStorageManager service = getStorageManager();
         String password;
         long identity = Binder.clearCallingIdentity();
         try {
@@ -1651,10 +1651,10 @@
         Secure.LOCK_SCREEN_OWNER_INFO
     };
 
-    private IMountService getMountService() {
+    private IStorageManager getStorageManager() {
         final IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         }
         return null;
     }
diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java
index 0efdd51..f72663a 100644
--- a/services/core/java/com/android/server/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/LockSettingsShellCommand.java
@@ -20,7 +20,7 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
 import static com.android.internal.widget.LockPatternUtils.stringToPattern;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Process;
@@ -52,7 +52,7 @@
     @Override
     public int onCommand(String cmd) {
         try {
-            mCurrentUserId = ActivityManagerNative.getDefault().getCurrentUser().id;
+            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
 
             parseArgs();
             if (!checkCredential()) {
diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java
index e0b2307..d8bd0bb 100644
--- a/services/core/java/com/android/server/MountServiceIdler.java
+++ b/services/core/java/com/android/server/MountServiceIdler.java
@@ -18,7 +18,7 @@
 
 import java.util.Calendar;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
@@ -59,7 +59,7 @@
         // is really more than just mount, some day it should be renamed to be system
         // idleer).
         try {
-            ActivityManagerNative.getDefault().performIdleMaintenance();
+            ActivityManager.getService().performIdleMaintenance();
         } catch (RemoteException e) {
         }
         // The mount service will run an fstrim operation asynchronously
@@ -67,7 +67,7 @@
         // that lets us cleanly end our idle timeslice.  It's safe to call
         // finishIdle() from any thread.
         mJobParams = params;
-        MountService ms = MountService.sSelf;
+        StorageManagerService ms = StorageManagerService.sSelf;
         if (ms != null) {
             synchronized (mFinishCallback) {
                 mStarted = true;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index e64aa16..5654096 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -46,7 +46,7 @@
 import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -958,7 +958,7 @@
                 final int uid = Integer.parseInt(cooked[1]);
                 final byte[] firstPacket = HexDump.hexStringToByteArray(cooked[2]);
                 try {
-                    ActivityManagerNative.getDefault().notifyCleartextNetwork(uid, firstPacket);
+                    ActivityManager.getService().notifyCleartextNetwork(uid, firstPacket);
                 } catch (RemoteException ignored) {
                 }
                 break;
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/StorageManagerService.java
similarity index 97%
rename from services/core/java/com/android/server/MountService.java
rename to services/core/java/com/android/server/StorageManagerService.java
index 8b7b6a0..11fabb4 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -31,7 +31,6 @@
 import android.Manifest;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
@@ -69,11 +68,11 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.DiskInfo;
-import android.os.storage.IMountService;
-import android.os.storage.IMountServiceListener;
-import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IStorageEventListener;
+import android.os.storage.IStorageShutdownObserver;
 import android.os.storage.IObbActionListener;
-import android.os.storage.MountServiceInternal;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManagerInternal;
 import android.os.storage.OnObbStateChangeListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
@@ -150,14 +149,14 @@
  * watch for and manage dynamically added storage, such as SD cards and USB mass
  * storage. Also decides how storage should be presented to users on the device.
  */
-class MountService extends IMountService.Stub
+class StorageManagerService extends IStorageManager.Stub
         implements INativeDaemonConnectorCallbacks, Watchdog.Monitor {
 
     // Static direct instance pointer for the tightly-coupled idle service to use
-    static MountService sSelf = null;
+    static StorageManagerService sSelf = null;
 
     public static class Lifecycle extends SystemService {
-        private MountService mMountService;
+        private StorageManagerService mStorageManagerService;
 
         public Lifecycle(Context context) {
             super(context);
@@ -165,33 +164,33 @@
 
         @Override
         public void onStart() {
-            mMountService = new MountService(getContext());
-            publishBinderService("mount", mMountService);
-            mMountService.start();
+            mStorageManagerService = new StorageManagerService(getContext());
+            publishBinderService("mount", mStorageManagerService);
+            mStorageManagerService.start();
         }
 
         @Override
         public void onBootPhase(int phase) {
             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
-                mMountService.systemReady();
+                mStorageManagerService.systemReady();
             } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
-                mMountService.bootCompleted();
+                mStorageManagerService.bootCompleted();
             }
         }
 
         @Override
         public void onSwitchUser(int userHandle) {
-            mMountService.mCurrentUserId = userHandle;
+            mStorageManagerService.mCurrentUserId = userHandle;
         }
 
         @Override
         public void onUnlockUser(int userHandle) {
-            mMountService.onUnlockUser(userHandle);
+            mStorageManagerService.onUnlockUser(userHandle);
         }
 
         @Override
         public void onCleanupUser(int userHandle) {
-            mMountService.onCleanupUser(userHandle);
+            mStorageManagerService.onCleanupUser(userHandle);
         }
     }
 
@@ -210,7 +209,7 @@
      */
     private static final boolean EMULATE_FBE_SUPPORTED = true;
 
-    private static final String TAG = "MountService";
+    private static final String TAG = "StorageManagerService";
 
     private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark";
     private static final String TAG_STORAGE_TRIM = "storage_trim";
@@ -501,7 +500,8 @@
     final private Map<String, ObbState> mObbPathToStateMap = new HashMap<String, ObbState>();
 
     // Not guarded by a lock.
-    private final MountServiceInternalImpl mMountServiceInternal = new MountServiceInternalImpl();
+    private final StorageManagerInternalImpl mStorageManagerInternal
+            = new StorageManagerInternalImpl();
 
     class ObbState implements IBinder.DeathRecipient {
         public ObbState(String rawPath, String canonicalPath, int callingUid,
@@ -610,8 +610,8 @@
     private static final int H_PARTITION_FORGET = 9;
     private static final int H_RESET = 10;
 
-    class MountServiceHandler extends Handler {
-        public MountServiceHandler(Looper looper) {
+    class StorageManagerServiceHandler extends Handler {
+        public StorageManagerServiceHandler(Looper looper) {
             super(looper);
         }
 
@@ -662,7 +662,7 @@
                     break;
                 }
                 case H_SHUTDOWN: {
-                    final IMountShutdownObserver obs = (IMountShutdownObserver) msg.obj;
+                    final IStorageShutdownObserver obs = (IStorageShutdownObserver) msg.obj;
                     boolean success = false;
                     try {
                         success = mConnector.execute("volume", "shutdown").isClassOk();
@@ -836,7 +836,7 @@
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                         user.id);
                 if (provider != null) {
-                    final IActivityManager am = ActivityManagerNative.getDefault();
+                    final IActivityManager am = ActivityManager.getService();
                     try {
                         am.killApplication(provider.applicationInfo.packageName,
                                 UserHandle.getAppId(provider.applicationInfo.uid),
@@ -1029,7 +1029,7 @@
         Configuration config = new Configuration();
         config.setLocale(locale);
         try {
-            ActivityManagerNative.getDefault().updatePersistentConfiguration(config);
+            ActivityManager.getService().updatePersistentConfiguration(config);
         } catch (RemoteException e) {
             Slog.e(TAG, "Error setting system locale from mount service", e);
         }
@@ -1482,11 +1482,11 @@
     }
 
     /**
-     * Constructs a new MountService instance
+     * Constructs a new StorageManagerService instance
      *
      * @param context  Binder context for this service
      */
-    public MountService(Context context) {
+    public StorageManagerService(Context context) {
         sSelf = this;
 
         mContext = context;
@@ -1498,9 +1498,9 @@
 
         HandlerThread hthread = new HandlerThread(TAG);
         hthread.start();
-        mHandler = new MountServiceHandler(hthread.getLooper());
+        mHandler = new StorageManagerServiceHandler(hthread.getLooper());
 
-        // Add OBB Action Handler to MountService thread.
+        // Add OBB Action Handler to StorageManagerService thread.
         mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
 
         // Initialize the last-fstrim tracking if necessary
@@ -1526,7 +1526,7 @@
             readSettingsLocked();
         }
 
-        LocalServices.addService(MountServiceInternal.class, mMountServiceInternal);
+        LocalServices.addService(StorageManagerInternal.class, mStorageManagerInternal);
 
         /*
          * Create the connection to vold with a maximum queue of twice the
@@ -1686,17 +1686,17 @@
      */
 
     @Override
-    public void registerListener(IMountServiceListener listener) {
+    public void registerListener(IStorageEventListener listener) {
         mCallbacks.register(listener);
     }
 
     @Override
-    public void unregisterListener(IMountServiceListener listener) {
+    public void unregisterListener(IStorageEventListener listener) {
         mCallbacks.unregister(listener);
     }
 
     @Override
-    public void shutdown(final IMountShutdownObserver observer) {
+    public void shutdown(final IStorageShutdownObserver observer) {
         enforcePermission(android.Manifest.permission.SHUTDOWN);
 
         Slog.i(TAG, "Shutting down");
@@ -3046,7 +3046,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             userKeyUnlocked = isUserKeyUnlocked(userId);
-            storagePermission = mMountServiceInternal.hasExternalStorage(uid, packageName);
+            storagePermission = mStorageManagerInternal.hasExternalStorage(uid, packageName);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -3163,7 +3163,7 @@
             for (final ObbState o : obbStates) {
                 if (o.rawPath.equals(obbState.rawPath)) {
                     throw new IllegalStateException("Attempt to add ObbState twice. "
-                            + "This indicates an error in the MountService logic.");
+                            + "This indicates an error in the StorageManagerService logic.");
                 }
             }
         }
@@ -3425,7 +3425,7 @@
             try {
                 mObbState.token.onObbResult(mObbState.rawPath, mObbState.nonce, status);
             } catch (RemoteException e) {
-                Slog.w(TAG, "MountServiceListener went away while calling onObbStateChanged");
+                Slog.w(TAG, "StorageEventListener went away while calling onObbStateChanged");
             }
         }
     }
@@ -3615,18 +3615,18 @@
         private static final int MSG_DISK_SCANNED = 5;
         private static final int MSG_DISK_DESTROYED = 6;
 
-        private final RemoteCallbackList<IMountServiceListener>
+        private final RemoteCallbackList<IStorageEventListener>
                 mCallbacks = new RemoteCallbackList<>();
 
         public Callbacks(Looper looper) {
             super(looper);
         }
 
-        public void register(IMountServiceListener callback) {
+        public void register(IStorageEventListener callback) {
             mCallbacks.register(callback);
         }
 
-        public void unregister(IMountServiceListener callback) {
+        public void unregister(IStorageEventListener callback) {
             mCallbacks.unregister(callback);
         }
 
@@ -3635,7 +3635,7 @@
             final SomeArgs args = (SomeArgs) msg.obj;
             final int n = mCallbacks.beginBroadcast();
             for (int i = 0; i < n; i++) {
-                final IMountServiceListener callback = mCallbacks.getBroadcastItem(i);
+                final IStorageEventListener callback = mCallbacks.getBroadcastItem(i);
                 try {
                     invokeCallback(callback, msg.what, args);
                 } catch (RemoteException ignored) {
@@ -3645,7 +3645,7 @@
             args.recycle();
         }
 
-        private void invokeCallback(IMountServiceListener callback, int what, SomeArgs args)
+        private void invokeCallback(IStorageEventListener callback, int what, SomeArgs args)
                 throws RemoteException {
             switch (what) {
                 case MSG_STORAGE_STATE_CHANGED: {
@@ -3830,7 +3830,7 @@
         }
     }
 
-    private final class MountServiceInternalImpl extends MountServiceInternal {
+    private final class StorageManagerInternalImpl extends StorageManagerInternal {
         // Not guarded by a lock.
         private final CopyOnWriteArrayList<ExternalStorageMountPolicy> mPolicies =
                 new CopyOnWriteArrayList<>();
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 4f02a23..cbd7be7 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -30,7 +30,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -159,7 +159,7 @@
 
         int userId = UserHandle.USER_SYSTEM;
         try {
-            userId = ActivityManagerNative.getDefault().getCurrentUser().id;
+            userId = ActivityManager.getService().getCurrentUser().id;
         } catch (RemoteException e) {
             Slog.w(TAG, "Couldn't get current user ID; guessing it's 0", e);
         }
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 6268697..6ea6fb7 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IUiModeManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -475,7 +474,7 @@
             mSetUiMode = mConfiguration.uiMode;
 
             try {
-                ActivityManagerNative.getDefault().updateConfiguration(mConfiguration);
+                ActivityManager.getService().updateConfiguration(mConfiguration);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failure communicating with activity manager", e);
             }
@@ -637,7 +636,7 @@
             Intent homeIntent = buildHomeIntent(category);
             if (Sandman.shouldStartDockApp(getContext(), homeIntent)) {
                 try {
-                    int result = ActivityManagerNative.getDefault().startActivityWithConfig(
+                    int result = ActivityManager.getService().startActivityWithConfig(
                             null, null, homeIntent, null, null, null, 0, 0,
                             mConfiguration, null, UserHandle.USER_CURRENT);
                     if (result >= ActivityManager.START_SUCCESS) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 7802576..b5fecfb 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -34,7 +34,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -3999,7 +3998,7 @@
     public AccountAndUser[] getRunningAccounts() {
         final int[] runningUserIds;
         try {
-            runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds();
+            runningUserIds = ActivityManager.getService().getRunningUserIds();
         } catch (RemoteException e) {
             // Running in system_server; should never happen
             throw new RuntimeException(e);
@@ -4940,7 +4939,7 @@
 
     private int handleIncomingUser(int userId) {
         try {
-            return ActivityManagerNative.getDefault().handleIncomingUser(
+            return ActivityManager.getService().handleIncomingUser(
                     Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "", null);
         } catch (RemoteException re) {
             // Shouldn't happen, local.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e080fd9..77d36f2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -196,8 +196,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
-import android.os.storage.IMountService;
-import android.os.storage.MountServiceInternal;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManagerInternal;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
@@ -2097,9 +2097,9 @@
                 try {
                     Locale l = (Locale) msg.obj;
                     IBinder service = ServiceManager.getService("mount");
-                    IMountService mountService = IMountService.Stub.asInterface(service);
+                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
-                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
+                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error storing locale for decryption UI", e);
                 }
@@ -3599,9 +3599,9 @@
                     final IPackageManager pm = AppGlobals.getPackageManager();
                     permGids = pm.getPackageGids(app.info.packageName,
                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
-                    MountServiceInternal mountServiceInternal = LocalServices.getService(
-                            MountServiceInternal.class);
-                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
+                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                            StorageManagerInternal.class);
+                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
                             app.info.packageName);
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
@@ -6490,11 +6490,12 @@
             // SDK can see it. Since access to the serial is now behind a
             // permission we push down the value.
             String buildSerial = Build.UNKNOWN;
-            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+            // TODO: SHTOPSHIP Uncomment the check when clients migrate
+//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
                 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
                         ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
                         .getSerial();
-            }
+//            }
 
             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 52ad72d..14b843a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -80,6 +80,7 @@
 import static android.app.ActivityManager.RESIZE_MODE_USER;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.view.Display.INVALID_DISPLAY;
 
 final class ActivityManagerShellCommand extends ShellCommand {
     public static final String NO_CLASS_ERROR_CODE = "Error type 3";
@@ -114,6 +115,7 @@
     private String mProfileFile;
     private int mSamplingInterval;
     private boolean mAutoStop;
+    private int mDisplayId;
     private int mStackId;
 
     final boolean mDumping;
@@ -249,6 +251,7 @@
         mSamplingInterval = 0;
         mAutoStop = false;
         mUserId = defUser;
+        mDisplayId = INVALID_DISPLAY;
         mStackId = INVALID_STACK_ID;
 
         return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
@@ -278,6 +281,8 @@
                     mUserId = UserHandle.parseUserArg(getNextArgRequired());
                 } else if (opt.equals("--receiver-permission")) {
                     mReceiverPermission = getNextArgRequired();
+                } else if (opt.equals("--display")) {
+                    mDisplayId = Integer.parseInt(getNextArgRequired());
                 } else if (opt.equals("--stack")) {
                     mStackId = Integer.parseInt(getNextArgRequired());
                 } else {
@@ -354,6 +359,10 @@
             int res;
             final long startTime = SystemClock.uptimeMillis();
             ActivityOptions options = null;
+            if (mDisplayId != INVALID_DISPLAY) {
+                options = ActivityOptions.makeBasic();
+                options.setLaunchDisplayId(mDisplayId);
+            }
             if (mStackId != INVALID_STACK_ID) {
                 options = ActivityOptions.makeBasic();
                 options.setLaunchStackId(mStackId);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 282ec50..539ac16 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -38,6 +38,8 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_PRIVATE;
+import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
@@ -90,6 +92,7 @@
 import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -1483,16 +1486,35 @@
             Slog.w(TAG, message);
             return false;
         }
-        if (options != null && options.getLaunchTaskId() != -1) {
-            final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
-                    callingPid, callingUid);
-            if (startInTaskPerm != PERMISSION_GRANTED) {
-                final String msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ") with launchTaskId="
-                        + options.getLaunchTaskId();
-                Slog.w(TAG, msg);
-                throw new SecurityException(msg);
+        if (options != null) {
+            if (options.getLaunchTaskId() != INVALID_STACK_ID) {
+                final int startInTaskPerm = mService.checkPermission(START_TASKS_FROM_RECENTS,
+                        callingPid, callingUid);
+                if (startInTaskPerm != PERMISSION_GRANTED) {
+                    final String msg = "Permission Denial: starting " + intent.toString()
+                            + " from " + callerApp + " (pid=" + callingPid
+                            + ", uid=" + callingUid + ") with launchTaskId="
+                            + options.getLaunchTaskId();
+                    Slog.w(TAG, msg);
+                    throw new SecurityException(msg);
+                }
+            }
+            // Check if someone tries to launch an activity on a private display with a different
+            // owner.
+            final int launchDisplayId = options.getLaunchDisplayId();
+            if (launchDisplayId != INVALID_DISPLAY) {
+                final ActivityDisplay activityDisplay = mActivityDisplays.get(launchDisplayId);
+                if (activityDisplay != null
+                        && (activityDisplay.mDisplay.getFlags() & FLAG_PRIVATE) != 0) {
+                    if (activityDisplay.mDisplay.getOwnerUid() != callingUid) {
+                        final String msg = "Permission Denial: starting " + intent.toString()
+                                + " from " + callerApp + " (pid=" + callingPid
+                                + ", uid=" + callingUid + ") with launchDisplayId="
+                                + launchDisplayId;
+                        Slog.w(TAG, msg);
+                        throw new SecurityException(msg);
+                    }
+                }
             }
         }
 
@@ -1937,7 +1959,7 @@
     }
 
     ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
-        ActivityContainer activityContainer = mActivityContainers.get(stackId);
+        final ActivityContainer activityContainer = mActivityContainers.get(stackId);
         if (activityContainer != null) {
             return activityContainer.mStack;
         }
@@ -1948,6 +1970,40 @@
         return createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
     }
 
+    /**
+     * Get a topmost stack on the display, that is a valid launch stack for specified activity.
+     * If there is no such stack, new dynamic stack can be created.
+     * @param displayId Target display.
+     * @param r Activity that should be launched there.
+     * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
+     */
+    ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r) {
+        final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
+        if (activityDisplay == null) {
+            throw new IllegalArgumentException(
+                    "Display with displayId=" + displayId + " not found.");
+        }
+
+        // Return the topmost valid stack on the display.
+        for (int i = activityDisplay.mStacks.size() - 1; i >= 0; --i) {
+            final ActivityStack stack = activityDisplay.mStacks.get(i);
+            if (mService.mActivityStarter.isValidLaunchStackId(stack.mStackId, r)) {
+                return stack;
+            }
+        }
+
+        // If there is no valid stack on the external display - check if new dynamic stack will do.
+        if (displayId != Display.DEFAULT_DISPLAY) {
+            final int newDynamicStackId = getNextStackId();
+            if (mService.mActivityStarter.isValidLaunchStackId(newDynamicStackId, r)) {
+                return createStackOnDisplay(newDynamicStackId, displayId, true /*onTop*/);
+            }
+        }
+
+        Slog.w(TAG, "getValidLaunchStackOnDisplay: can't launch on displayId " + displayId);
+        return null;
+    }
+
     ArrayList<ActivityStack> getStacks() {
         ArrayList<ActivityStack> allStacks = new ArrayList<>();
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -2326,11 +2382,15 @@
      * Restores a recent task to a stack
      * @param task The recent task to be restored.
      * @param stackId The stack to restore the task to (default launch stack will be used
-     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
+     *                if stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}
+     *                or is not a static stack).
      * @return true if the task has been restored successfully.
      */
     private boolean restoreRecentTaskLocked(TaskRecord task, int stackId) {
-        if (stackId == INVALID_STACK_ID) {
+        if (!StackId.isStaticStack(stackId)) {
+            // If stack is not static (or stack id is invalid) - use the default one.
+            // This means that tasks that were on external displays will be restored on the
+            // primary display.
             stackId = task.getLaunchStackId();
         } else if (stackId == DOCKED_STACK_ID && !task.canGoInDockedStack()) {
             // Preferred stack is the docked stack, but the task can't go in the docked stack.
@@ -3504,7 +3564,10 @@
             if (activityDisplay != null) {
                 ArrayList<ActivityStack> stacks = activityDisplay.mStacks;
                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                    stacks.get(stackNdx).mActivityContainer.removeLocked();
+                    final ActivityStack stack = stacks.get(stackNdx);
+                    // TODO: Implement proper stack removal and ability to choose the behavior -
+                    // remove stack completely or move it to other display.
+                    moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY);
                 }
                 mActivityDisplays.remove(displayId);
             }
@@ -4155,7 +4218,10 @@
             }
         }
 
-        /** Remove the stack completely. */
+        /**
+         * Remove the stack completely. Must be called only when there are no tasks left in it,
+         * as this method does not finish running activities.
+         */
         void removeLocked() {
             if (DEBUG_STACK) Slog.d(TAG_STACK, "removeLocked: " + this + " from display="
                     + mActivityDisplay + " Callers=" + Debug.getCallers(2));
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 691d6b9..ccd94cb 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -31,6 +31,7 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.isStaticStack;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -50,6 +51,8 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.view.Display.INVALID_DISPLAY;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
@@ -115,6 +118,7 @@
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
+import com.android.server.pm.EphemeralResolver;
 import com.android.server.wm.WindowManagerService;
 
 import java.util.ArrayList;
@@ -132,9 +136,6 @@
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
 
-    // TODO b/30204367 remove when the platform fully supports ephemeral applications
-    private static final boolean USE_DEFAULT_EPHEMERAL_LAUNCHER = false;
-
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
     private ActivityStartInterceptor mInterceptor;
@@ -254,11 +255,7 @@
 
         if (err == ActivityManager.START_SUCCESS) {
             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
-                    + "} from uid " + callingUid
-                    + " on display " + (container == null ? (mSupervisor.mFocusedStack == null ?
-                    Display.DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId) :
-                    (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
-                            container.mActivityDisplay.mDisplayId)));
+                    + "} from uid " + callingUid);
         }
 
         ActivityRecord sourceRecord = null;
@@ -458,13 +455,21 @@
         // Instead, launch the ephemeral installer. Once the installer is finished, it
         // starts either the intent we resolved here [on install error] or the ephemeral
         // app [on install success].
-        if (rInfo != null && rInfo.ephemeralIntentInfo != null) {
+        if (rInfo != null && rInfo.ephemeralResponse != null) {
             final String packageName =
-                    rInfo.ephemeralIntentInfo.getEphemeralResolveInfo().getPackageName();
-            final String splitName = rInfo.ephemeralIntentInfo.getSplitName();
-            intent = buildEphemeralInstallerIntent(intent, ephemeralIntent,
-                    packageName, splitName, callingPackage, resolvedType,
-                    userId);
+                    rInfo.ephemeralResponse.resolveInfo.getPackageName();
+            final String splitName = rInfo.ephemeralResponse.splitName;
+            final boolean needsPhaseTwo = rInfo.ephemeralResponse.needsPhase2;
+            final String token = rInfo.ephemeralResponse.token;
+            if (needsPhaseTwo) {
+                // request phase two resolution
+                mService.getPackageManagerInternalLocked().requestEphemeralResolutionPhaseTwo(
+                        rInfo.ephemeralResponse, ephemeralIntent, resolvedType, intent,
+                        callingPackage, userId);
+            }
+            intent = EphemeralResolver.buildEphemeralInstallerIntent(intent, ephemeralIntent,
+                    callingPackage, resolvedType, userId, packageName, splitName, token,
+                    needsPhaseTwo);
             resolvedType = null;
             callingUid = realCallingUid;
             callingPid = realCallingPid;
@@ -523,60 +528,6 @@
         return err;
     }
 
-    /**
-     * Builds and returns an intent to launch the ephemeral installer.
-     */
-    private Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent,
-            String ephemeralPackageName, String ephemeralSplitName, String callingPackage,
-            String resolvedType, int userId) {
-        final Intent nonEphemeralIntent = new Intent(origIntent);
-        nonEphemeralIntent.setFlags(nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
-        // Intent that is launched if the ephemeral package couldn't be installed
-        // for any reason.
-        final IIntentSender failureIntentTarget = mService.getIntentSenderLocked(
-                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
-                Binder.getCallingUid(), userId, null /*token*/, null /*resultWho*/, 1,
-                new Intent[]{ nonEphemeralIntent }, new String[]{ resolvedType },
-                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
-                | PendingIntent.FLAG_IMMUTABLE, null /*bOptions*/);
-
-        final Intent ephemeralIntent;
-        if (USE_DEFAULT_EPHEMERAL_LAUNCHER) {
-            // Force the intent to be directed to the ephemeral package
-            ephemeralIntent = new Intent(origIntent);
-            ephemeralIntent.setPackage(ephemeralPackageName);
-        } else {
-            // Success intent goes back to the installer
-            ephemeralIntent = new Intent(launchIntent);
-        }
-
-        // Intent that is eventually launched if the ephemeral package was
-        // installed successfully. This will actually be launched by a platform
-        // broadcast receiver.
-        final IIntentSender successIntentTarget = mService.getIntentSenderLocked(
-                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
-                Binder.getCallingUid(), userId, null /*token*/, null /*resultWho*/, 0,
-                new Intent[]{ ephemeralIntent }, new String[]{ resolvedType },
-                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
-                | PendingIntent.FLAG_IMMUTABLE, null /*bOptions*/);
-
-        // Finally build the actual intent to launch the ephemeral installer
-        int flags = launchIntent.getFlags();
-        final Intent intent = new Intent();
-        intent.setFlags(flags
-                | Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_CLEAR_TASK
-                | Intent.FLAG_ACTIVITY_NO_HISTORY
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName);
-        intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName);
-        intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, new IntentSender(failureIntentTarget));
-        intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS, new IntentSender(successIntentTarget));
-        // TODO: Remove when the platform has fully implemented ephemeral apps
-        intent.setData(origIntent.getData().buildUpon().clearQuery().build());
-        return intent;
-    }
-
     void postStartActivityUncheckedProcessing(
             ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
             ActivityStack targetStack) {
@@ -1952,12 +1903,14 @@
 
         // The fullscreen stack can contain any task regardless of if the task is resizeable
         // or not. So, we let the task go in the fullscreen task if it is the focus stack.
+        // Same also applies to dynamic stacks, as they behave similar to fullscreen stack.
         // If the freeform or docked stack has focus, and the activity to be launched is resizeable,
         // we can also put it in the focused stack.
         final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
         final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
                 || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack())
-                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced());
+                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced())
+                || !isStaticStack(focusedStackId);
         if (canUseFocusedStack && (!newTask
                 || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
@@ -1965,7 +1918,7 @@
             return mSupervisor.mFocusedStack;
         }
 
-        // We first try to put the task in the first dynamic stack.
+        // We first try to put the task in the first dynamic stack on home display.
         final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
         for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             stack = homeDisplayStacks.get(stackNdx);
@@ -1994,16 +1947,29 @@
             return mReuseTask.getStack();
         }
 
+        final int launchDisplayId =
+                (aOptions != null) ? aOptions.getLaunchDisplayId() : INVALID_DISPLAY;
+
         final int launchStackId =
                 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
 
+        if (launchStackId != INVALID_STACK_ID && launchDisplayId != INVALID_DISPLAY) {
+            throw new IllegalArgumentException(
+                    "Stack and display id can't be set at the same time.");
+        }
+
         if (isValidLaunchStackId(launchStackId, r)) {
             return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
-        } else if (launchStackId == DOCKED_STACK_ID) {
+        }
+        if (launchStackId == DOCKED_STACK_ID) {
             // The preferred launch stack is the docked stack, but it isn't a valid launch stack
             // for this activity, so we put the activity in the fullscreen stack.
             return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
         }
+        if (launchDisplayId != INVALID_DISPLAY) {
+            // Stack id has higher priority than display id.
+            return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
+        }
 
         if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
             return null;
@@ -2047,9 +2013,8 @@
         }
     }
 
-    private boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
-        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID
-                || !StackId.isStaticStack(stackId)) {
+    boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
+        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 9697855..a0a04bb 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -75,7 +75,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.IntArray;
@@ -735,8 +735,8 @@
         }
     }
 
-    private IMountService getMountService() {
-        return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+    private IStorageManager getStorageManager() {
+        return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
     }
 
     /**
@@ -980,10 +980,10 @@
             // TODO Move this block outside of synchronized if it causes lock contention
             if (!StorageManager.isUserKeyUnlocked(userId)) {
                 final UserInfo userInfo = getUserInfo(userId);
-                final IMountService mountService = getMountService();
+                final IStorageManager storageManager = getStorageManager();
                 try {
                     // We always want to unlock user storage, even user is not started yet
-                    mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
+                    storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
                 } catch (RemoteException | RuntimeException e) {
                     Slog.w(TAG, "Failed to unlock: " + e.getMessage());
                 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eb5e603..da016da 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -25,7 +25,6 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
@@ -1706,7 +1705,7 @@
     private int getCurrentUserId() {
         final long ident = Binder.clearCallingIdentity();
         try {
-            UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            UserInfo currentUser = ActivityManager.getService().getCurrentUser();
             return currentUser.id;
         } catch (RemoteException e) {
             // Activity manager not running, nothing we can do assume user 0.
@@ -5124,7 +5123,7 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
+            ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -5463,7 +5462,7 @@
             }
             try {
                 final int uid = pkg.applicationInfo.uid;
-                ActivityManagerNative.getDefault().killUid(UserHandle.getAppId(uid),
+                ActivityManager.getService().killUid(UserHandle.getAppId(uid),
                         UserHandle.getUserId(uid),
                         "killBackgroundUserProcessesWithAudioRecordPermission");
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 5772a57..8d4f0a9 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -16,7 +16,7 @@
 
 package com.android.server.clipboard;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
@@ -71,7 +71,7 @@
     public ClipboardService(Context context) {
         super(context);
 
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         mPm = getContext().getPackageManager();
         mUm = (IUserManager) ServiceManager.getService(Context.USER_SERVICE);
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 0727629..3b4cef4 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,7 +20,6 @@
 import android.accounts.Account;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.job.JobInfo;
 import android.content.BroadcastReceiver;
@@ -434,7 +433,7 @@
 
     private int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, int userHandle) {
         try {
-            return ActivityManagerNative.getDefault().checkUriPermission(
+            return ActivityManager.getService().checkUriPermission(
                     uri, pid, uid, modeFlags, userHandle, null);
         } catch (RemoteException e) {
             return PackageManager.PERMISSION_DENIED;
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 03d95b2..11a3f11 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -21,7 +21,6 @@
 import android.accounts.AccountManager;
 import android.accounts.AccountManagerInternal;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -1020,7 +1019,7 @@
         final int owningUid = syncAdapterInfo.uid;
         final String owningPackage = syncAdapterInfo.componentName.getPackageName();
         try {
-            if (ActivityManagerNative.getDefault().getAppStartMode(owningUid,
+            if (ActivityManager.getService().getAppStartMode(owningUid,
                     owningPackage) == ActivityManager.APP_START_MODE_DISABLED) {
                 Slog.w(TAG, "Not scheduling job " + syncAdapterInfo.uid + ":"
                         + syncAdapterInfo.componentName
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 49c4140..273bc64 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -19,7 +19,6 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
@@ -465,7 +464,7 @@
     private boolean isForegroundActivity(int uid, int pid) {
         try {
             List<RunningAppProcessInfo> procs =
-                    ActivityManagerNative.getDefault().getRunningAppProcesses();
+                    ActivityManager.getService().getRunningAppProcesses();
             int N = procs.size();
             for (int i = 0; i < N; i++) {
                 RunningAppProcessInfo proc = procs.get(i);
@@ -1072,7 +1071,7 @@
 
     private void listenForUserSwitches() {
         try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(
+            ActivityManager.getService().registerUserSwitchObserver(
                 new SynchronousUserSwitchObserver() {
                     @Override
                     public void onUserSwitching(int newUserId) throws RemoteException {
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index b878099..c99d8be 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -30,7 +30,6 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
 import android.app.job.JobInfo;
@@ -567,7 +566,7 @@
             String tag) {
         JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);
         try {
-            if (ActivityManagerNative.getDefault().getAppStartMode(uId,
+            if (ActivityManager.getService().getAppStartMode(uId,
                     job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) {
                 Slog.w(TAG, "Not scheduling job " + uId + ":" + job.toString()
                         + " -- package not allowed to start");
@@ -816,7 +815,7 @@
                     mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
             mPowerManager = (PowerManager)getContext().getSystemService(Context.POWER_SERVICE);
             try {
-                ActivityManagerNative.getDefault().registerUidObserver(mUidObserver,
+                ActivityManager.getService().registerUidObserver(mUidObserver,
                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
                         | ActivityManager.UID_OBSERVER_IDLE, ActivityManager.PROCESS_STATE_UNKNOWN,
                         null);
@@ -1202,7 +1201,7 @@
             public void process(JobStatus job) {
                 if (isReadyToBeExecutedLocked(job)) {
                     try {
-                        if (ActivityManagerNative.getDefault().getAppStartMode(job.getUid(),
+                        if (ActivityManager.getService().getAppStartMode(job.getUid(),
                                 job.getJob().getService().getPackageName())
                                 == ActivityManager.APP_START_MODE_DISABLED) {
                             Slog.w(TAG, "Aborting job " + job.getUid() + ":"
@@ -1376,7 +1375,7 @@
 
         int memLevel;
         try {
-            memLevel = ActivityManagerNative.getDefault().getMemoryTrimLevel();
+            memLevel = ActivityManager.getService().getMemoryTrimLevel();
         } catch (RemoteException e) {
             memLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
         }
diff --git a/services/core/java/com/android/server/media/MediaResourceMonitorService.java b/services/core/java/com/android/server/media/MediaResourceMonitorService.java
index 0eb8b55..8ed32f0 100644
--- a/services/core/java/com/android/server/media/MediaResourceMonitorService.java
+++ b/services/core/java/com/android/server/media/MediaResourceMonitorService.java
@@ -17,7 +17,6 @@
 package com.android.server.media;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.Context;
 import android.content.Intent;
 import android.media.IMediaResourceMonitor;
@@ -84,7 +83,7 @@
         private String[] getPackageNamesFromPid(int pid) {
             try {
                 for (ActivityManager.RunningAppProcessInfo proc :
-                        ActivityManagerNative.getDefault().getRunningAppProcesses()) {
+                        ActivityManager.getService().getRunningAppProcesses()) {
                     if (proc.pid == pid) {
                         return proc.pkgList;
                     }
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 3327b36..9740935 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -17,7 +17,6 @@
 package com.android.server.media;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
@@ -74,7 +73,7 @@
     private static boolean isFromMostRecentApp(MediaSessionRecord record) {
         try {
             List<ActivityManager.RecentTaskInfo> tasks =
-                    ActivityManagerNative.getDefault().getRecentTasks(1,
+                    ActivityManager.getService().getRecentTasks(1,
                             ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
                             ActivityManager.RECENT_IGNORE_UNAVAILABLE |
                             ActivityManager.RECENT_INCLUDE_PROFILES |
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 90ede6f..a530b3d 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -50,7 +50,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.AutomaticZenRule;
@@ -600,7 +599,7 @@
                     REASON_DELEGATE_ERROR, null);
             long ident = Binder.clearCallingIdentity();
             try {
-                ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
+                ActivityManager.getService().crashApplication(uid, initialPid, pkg,
                         "Bad notification posted from package " + pkg
                         + ": " + message);
             } catch (RemoteException e) {
@@ -952,7 +951,7 @@
                 Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
                 DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
 
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
         mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
         mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
diff --git a/services/core/java/com/android/server/pm/EphemeralResolver.java b/services/core/java/com/android/server/pm/EphemeralResolver.java
new file mode 100644
index 0000000..82f796dac
--- /dev/null
+++ b/services/core/java/com/android/server/pm/EphemeralResolver.java
@@ -0,0 +1,249 @@
+/*
+ * 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.pm;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.EphemeralIntentFilter;
+import android.content.pm.EphemeralRequest;
+import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.EphemeralResponse;
+import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.pm.EphemeralResolverConnection.PhaseTwoCallback;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/** @hide */
+public abstract class EphemeralResolver {
+
+    /** TODO b/30204367 remove when the platform fully supports ephemeral applications */
+    public static final boolean USE_DEFAULT_EPHEMERAL_LAUNCHER = false;
+
+    public static EphemeralResponse doEphemeralResolutionPhaseOne(Context context,
+            EphemeralResolverConnection connection, EphemeralRequest requestObj) {
+        final Intent intent = requestObj.origIntent;
+        final EphemeralDigest digest =
+                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
+        final int[] shaPrefix = digest.getDigestPrefix();
+        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
+                connection.getEphemeralResolveInfoList(shaPrefix);
+        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
+            // No hash prefix match; there are no ephemeral apps for this domain.
+            return null;
+        }
+
+        final String token = UUID.randomUUID().toString();
+        return EphemeralResolver.filterEphemeralIntent(ephemeralResolveInfoList,
+                intent, requestObj.resolvedType, requestObj.userId,
+                intent.getPackage(), digest, token);
+    }
+
+    public static void doEphemeralResolutionPhaseTwo(Context context,
+            EphemeralResolverConnection connection, EphemeralRequest requestObj,
+            ActivityInfo ephemeralInstaller, Handler callbackHandler) {
+        final Intent intent = requestObj.origIntent;
+        final EphemeralDigest digest =
+                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
+        final int[] shaPrefix = digest.getDigestPrefix();
+        final byte[][] digestBytes = digest.getDigestBytes();
+
+        final PhaseTwoCallback callback = new PhaseTwoCallback() {
+            @Override
+            void onPhaseTwoResolved(List<EphemeralResolveInfo> ephemeralResolveInfoList,
+                    int sequence) {
+                final String packageName;
+                final String splitName;
+                if (ephemeralResolveInfoList != null
+                        && ephemeralResolveInfoList.size() > 0) {
+                    final EphemeralResponse ephemeralIntentInfo =
+                            EphemeralResolver.filterEphemeralIntent(
+                                    ephemeralResolveInfoList, intent, null /*resolvedType*/,
+                                    0 /*userId*/, intent.getPackage(), digest,
+                                    requestObj.responseObj.token);
+                    if (ephemeralIntentInfo != null
+                            && ephemeralIntentInfo.resolveInfo != null) {
+                        packageName = ephemeralIntentInfo.resolveInfo.getPackageName();
+                        splitName = ephemeralIntentInfo.splitName;
+                    } else {
+                        packageName = null;
+                        splitName = null;
+                    }
+                } else {
+                    packageName = null;
+                    splitName = null;
+                }
+                final Intent installerIntent = buildEphemeralInstallerIntent(
+                        requestObj.launchIntent,
+                        requestObj.origIntent,
+                        requestObj.callingPackage,
+                        requestObj.resolvedType,
+                        requestObj.userId,
+                        packageName,
+                        splitName,
+                        requestObj.responseObj.token,
+                        false /*needsPhaseTwo*/);
+                installerIntent.setComponent(new ComponentName(
+                        ephemeralInstaller.packageName, ephemeralInstaller.name));
+                context.startActivity(installerIntent);
+            }
+        };
+        connection.getEphemeralIntentFilterList(
+                shaPrefix, callback, callbackHandler, 0 /*sequence*/);
+    }
+
+    /**
+     * Builds and returns an intent to launch the ephemeral installer.
+     */
+    public static Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent,
+            String callingPackage, String resolvedType, int userId, String ephemeralPackageName,
+            String ephemeralSplitName, String token, boolean needsPhaseTwo) {
+        // Construct the intent that launches the ephemeral installer
+        int flags = launchIntent.getFlags();
+        final Intent intent = new Intent();
+        intent.setFlags(flags
+                | Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_CLEAR_TASK
+                | Intent.FLAG_ACTIVITY_NO_HISTORY
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        // TODO: Remove when the platform has fully implemented ephemeral apps
+        intent.setData(origIntent.getData().buildUpon().clearQuery().build());
+        intent.putExtra(Intent.EXTRA_EPHEMERAL_TOKEN, token);
+        intent.putExtra(Intent.EXTRA_EPHEMERAL_HOSTNAME, origIntent.getData().getHost());
+
+        if (!needsPhaseTwo) {
+            // We have all of the data we need; just start the installer without a second phase
+            final Intent nonEphemeralIntent = new Intent(origIntent);
+            nonEphemeralIntent.setFlags(
+                    nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+            // Intent that is launched if the ephemeral package couldn't be installed
+            // for any reason.
+            try {
+                final IIntentSender failureIntentTarget = ActivityManagerNative.getDefault()
+                        .getIntentSender(
+                                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+                                null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
+                                new Intent[] { nonEphemeralIntent },
+                                new String[] { resolvedType },
+                                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+                                        | PendingIntent.FLAG_IMMUTABLE,
+                                null /*bOptions*/, userId);
+                intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE,
+                        new IntentSender(failureIntentTarget));
+            } catch (RemoteException ignore) { /* ignore; same process */ }
+
+            final Intent ephemeralIntent;
+            if (EphemeralResolver.USE_DEFAULT_EPHEMERAL_LAUNCHER) {
+                // Force the intent to be directed to the ephemeral package
+                ephemeralIntent = new Intent(origIntent);
+                ephemeralIntent.setPackage(ephemeralPackageName);
+            } else {
+                // Success intent goes back to the installer
+                ephemeralIntent = new Intent(launchIntent);
+            }
+
+            // Intent that is eventually launched if the ephemeral package was
+            // installed successfully. This will actually be launched by a platform
+            // broadcast receiver.
+            try {
+                final IIntentSender successIntentTarget = ActivityManagerNative.getDefault()
+                        .getIntentSender(
+                                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+                                null /*token*/, null /*resultWho*/, 0 /*requestCode*/,
+                                new Intent[] { ephemeralIntent },
+                                new String[] { resolvedType },
+                                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+                                        | PendingIntent.FLAG_IMMUTABLE,
+                                null /*bOptions*/, userId);
+                intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS,
+                        new IntentSender(successIntentTarget));
+            } catch (RemoteException ignore) { /* ignore; same process */ }
+
+            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName);
+            intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName);
+        }
+
+        return intent;
+    }
+
+    private static EphemeralResponse filterEphemeralIntent(
+            List<EphemeralResolveInfo> ephemeralResolveInfoList,
+            Intent intent, String resolvedType, int userId, String packageName,
+            EphemeralDigest digest, String token) {
+        final int[] shaPrefix = digest.getDigestPrefix();
+        final byte[][] digestBytes = digest.getDigestBytes();
+        // Go in reverse order so we match the narrowest scope first.
+        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
+            for (EphemeralResolveInfo ephemeralInfo : ephemeralResolveInfoList) {
+                if (!Arrays.equals(digestBytes[i], ephemeralInfo.getDigestBytes())) {
+                    continue;
+                }
+                if (packageName != null
+                        && !packageName.equals(ephemeralInfo.getPackageName())) {
+                    continue;
+                }
+                final List<EphemeralIntentFilter> ephemeralFilters =
+                        ephemeralInfo.getIntentFilters();
+                // No filters; we need to start phase two
+                if (ephemeralFilters == null || ephemeralFilters.isEmpty()) {
+                    return new EphemeralResponse(ephemeralInfo,
+                            new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
+                            null /*splitName*/, token, true /*needsPhase2*/);
+                }
+                // We have a domain match; resolve the filters to see if anything matches.
+                final PackageManagerService.EphemeralIntentResolver ephemeralResolver =
+                        new PackageManagerService.EphemeralIntentResolver();
+                for (int j = ephemeralFilters.size() - 1; j >= 0; --j) {
+                    final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j);
+                    final List<IntentFilter> splitFilters = ephemeralFilter.getFilters();
+                    if (splitFilters == null || splitFilters.isEmpty()) {
+                        continue;
+                    }
+                    for (int k = splitFilters.size() - 1; k >= 0; --k) {
+                        final EphemeralResponse intentInfo =
+                                new EphemeralResponse(ephemeralInfo,
+                                        splitFilters.get(k), ephemeralFilter.getSplitName(),
+                                        token, false /*needsPhase2*/);
+                        ephemeralResolver.addFilter(intentInfo);
+                    }
+                }
+                List<EphemeralResponse> matchedResolveInfoList = ephemeralResolver
+                        .queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
+                if (!matchedResolveInfoList.isEmpty()) {
+                    return matchedResolveInfoList.get(0);
+                }
+            }
+        }
+        // Hash or filter mis-match; no ephemeral apps for this domain.
+        return null;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index ecc03d7..20d9813 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -23,8 +23,10 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.EphemeralResponse;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -54,8 +56,6 @@
     private final Object mLock = new Object();
     private final GetEphemeralResolveInfoCaller mGetEphemeralResolveInfoCaller =
             new GetEphemeralResolveInfoCaller();
-    private final GetEphemeralIntentFilterCaller mGetEphemeralIntentFilterCaller =
-            new GetEphemeralIntentFilterCaller();
     private final ServiceConnection mServiceConnection = new MyServiceConnection();
     private final Context mContext;
     /** Intent used to bind to the service */
@@ -84,19 +84,27 @@
         return null;
     }
 
-    public final List<EphemeralResolveInfo> getEphemeralIntentFilterList(int digestPrefix[]) {
-        throwIfCalledOnMainThread();
+    public final void getEphemeralIntentFilterList(int digestPrefix[], PhaseTwoCallback callback,
+            Handler callbackHandler, final int sequence) {
+        final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
+            @Override
+            public void sendResult(Bundle data) throws RemoteException {
+                final ArrayList<EphemeralResolveInfo> ephemeralResolveInfoList =
+                        data.getParcelableArrayList(EphemeralResolverService.EXTRA_RESOLVE_INFO);
+                callbackHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onPhaseTwoResolved(ephemeralResolveInfoList, sequence);
+                    }
+                });
+            }
+        };
         try {
-            return mGetEphemeralIntentFilterCaller.getEphemeralIntentFilterList(
-                    getRemoteInstanceLazy(), digestPrefix);
+            getRemoteInstanceLazy()
+                    .getEphemeralIntentFilterList(remoteCallback, digestPrefix, sequence);
         } catch (RemoteException re) {
         } catch (TimeoutException te) {
-        } finally {
-            synchronized (mLock) {
-                mLock.notifyAll();
-            }
         }
-        return null;
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
@@ -161,6 +169,14 @@
         }
     }
 
+    /**
+     * Asynchronous callback when results come back from ephemeral resolution phase two.
+     */
+    public abstract static class PhaseTwoCallback {
+        abstract void onPhaseTwoResolved(List<EphemeralResolveInfo> ephemeralResolveInfoList,
+                int sequence);
+    }
+
     private final class MyServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -205,32 +221,4 @@
             return getResultTimed(sequence);
         }
     }
-
-    private static final class GetEphemeralIntentFilterCaller
-            extends TimedRemoteCaller<List<EphemeralResolveInfo>> {
-        private final IRemoteCallback mCallback;
-
-        public GetEphemeralIntentFilterCaller() {
-            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
-            mCallback = new IRemoteCallback.Stub() {
-                @Override
-                public void sendResult(Bundle data) throws RemoteException {
-                    final ArrayList<EphemeralResolveInfo> resolveList =
-                            data.getParcelableArrayList(
-                                    EphemeralResolverService.EXTRA_RESOLVE_INFO);
-                    int sequence =
-                            data.getInt(EphemeralResolverService.EXTRA_SEQUENCE, -1);
-                    onRemoteMethodResult(resolveList, sequence);
-                }
-            };
-        }
-
-        public List<EphemeralResolveInfo> getEphemeralIntentFilterList(
-                IEphemeralResolver target, int digestPrefix[])
-                        throws RemoteException, TimeoutException {
-            final int sequence = onBeforeRemoteCall();
-            target.getEphemeralIntentFilterList(mCallback, digestPrefix, sequence);
-            return getResultTimed(sequence);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 79ef486..ee3f42b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -101,7 +101,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.ResourcesManager;
 import android.app.admin.IDevicePolicyManager;
@@ -122,10 +121,9 @@
 import android.content.pm.AppsQueryHelper;
 import android.content.pm.ComponentInfo;
 import android.content.pm.EphemeralApplicationInfo;
-import android.content.pm.EphemeralIntentFilter;
+import android.content.pm.EphemeralRequest;
 import android.content.pm.EphemeralResolveInfo;
-import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
-import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
+import android.content.pm.EphemeralResponse;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
@@ -193,8 +191,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.os.storage.IMountService;
-import android.os.storage.MountServiceInternal;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManagerInternal;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
@@ -209,6 +207,7 @@
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Base64;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.ExceptionUtils;
@@ -234,6 +233,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.IParcelFileDescriptorFactory;
 import com.android.internal.os.InstallerConnection.InstallerException;
+import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.Zygote;
 import com.android.internal.telephony.CarrierAppUtils;
@@ -286,6 +286,7 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
@@ -337,7 +338,7 @@
  *
  * <pre>
  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
- * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
+ * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
  * </pre>
  */
 public class PackageManagerService extends IPackageManager.Stub {
@@ -1067,6 +1068,7 @@
     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
     static final int INTENT_FILTER_VERIFIED = 18;
     static final int WRITE_PACKAGE_LIST = 19;
+    static final int EPHEMERAL_RESOLUTION_PHASE_TWO = 20;
 
     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
 
@@ -1470,10 +1472,11 @@
                     }
                     if (reportStatus) {
                         try {
-                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
-                            PackageHelper.getMountService().finishMediaUpdate();
+                            if (DEBUG_SD_INSTALL) Log.i(TAG,
+                                    "Invoking StorageManagerService call back");
+                            PackageHelper.getStorageManager().finishMediaUpdate();
                         } catch (RemoteException e) {
-                            Log.e(TAG, "MountService not running?");
+                            Log.e(TAG, "StorageManagerService not running?");
                         }
                     }
                 } break;
@@ -1636,6 +1639,13 @@
 
                     break;
                 }
+                case EPHEMERAL_RESOLUTION_PHASE_TWO: {
+                    EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext,
+                            mEphemeralResolverConnection,
+                            (EphemeralRequest) msg.obj,
+                            mEphemeralInstallerActivity,
+                            mHandler);
+                }
             }
         }
     }
@@ -1878,6 +1888,11 @@
                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
+
+                    // Try very hard to release any references to this package
+                    // so we don't risk the system server being killed due to
+                    // open FDs
+                    AttributeCache.instance().removePackage(ps.name);
                 }
 
                 mSettings.onVolumeForgotten(fsUuid);
@@ -4133,9 +4148,9 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 if (sUserManager.isInitialized(userId)) {
-                    MountServiceInternal mountServiceInternal = LocalServices.getService(
-                            MountServiceInternal.class);
-                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
+                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                            StorageManagerInternal.class);
+                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -4536,7 +4551,7 @@
     private void killUid(int appId, int userId, String reason) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 try {
                     am.killUid(appId, userId, reason);
@@ -4943,60 +4958,13 @@
         return true;
     }
 
-    private static EphemeralResolveIntentInfo getEphemeralIntentInfo(
-            Context context, EphemeralResolverConnection resolverConnection, Intent intent,
-            String resolvedType, int userId, String packageName) {
-        final EphemeralDigest digest =
-                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
-        final int[] shaPrefix = digest.getDigestPrefix();
-        final byte[][] digestBytes = digest.getDigestBytes();
-        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
-                resolverConnection.getEphemeralResolveInfoList(shaPrefix);
-        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
-            // No hash prefix match; there are no ephemeral apps for this domain.
-            return null;
-        }
-
-        // Go in reverse order so we match the narrowest scope first.
-        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
-            for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
-                if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
-                    continue;
-                }
-                final List<EphemeralIntentFilter> ephemeralFilters =
-                        ephemeralApplication.getIntentFilters();
-                // No filters; this should never happen.
-                if (ephemeralFilters.isEmpty()) {
-                    continue;
-                }
-                if (packageName != null
-                        && !packageName.equals(ephemeralApplication.getPackageName())) {
-                    continue;
-                }
-                // We have a domain match; resolve the filters to see if anything matches.
-                final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
-                for (int j = ephemeralFilters.size() - 1; j >= 0; --j) {
-                    final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j);
-                    final List<IntentFilter> splitFilters = ephemeralFilter.getFilters();
-                    if (splitFilters == null || splitFilters.isEmpty()) {
-                        continue;
-                    }
-                    for (int k = splitFilters.size() - 1; k >= 0; --k) {
-                        final EphemeralResolveIntentInfo intentInfo =
-                                new EphemeralResolveIntentInfo(splitFilters.get(k),
-                                        ephemeralApplication, ephemeralFilter.getSplitName());
-                        ephemeralResolver.addFilter(intentInfo);
-                    }
-                }
-                List<EphemeralResolveIntentInfo> matchedResolveInfoList = ephemeralResolver
-                        .queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
-                if (!matchedResolveInfoList.isEmpty()) {
-                    return matchedResolveInfoList.get(0);
-                }
-            }
-        }
-        // Hash or filter mis-match; no ephemeral apps for this domain.
-        return null;
+    private void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+            Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage,
+            int userId) {
+        final Message msg = mHandler.obtainMessage(EPHEMERAL_RESOLUTION_PHASE_TWO,
+                new EphemeralRequest(responseObj, origIntent, resolvedType, launchIntent,
+                        callingPackage, userId));
+        mHandler.sendMessage(msg);
     }
 
     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
@@ -5472,15 +5440,17 @@
         }
         if (addEphemeral) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
-            final EphemeralResolveIntentInfo intentInfo = getEphemeralIntentInfo(
-                    mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
-                    matchEphemeralPackage ? pkgName : null);
+            final EphemeralRequest requestObject = new EphemeralRequest(
+                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
+                    null /*launchIntent*/, null /*callingPackage*/, userId);
+            final EphemeralResponse intentInfo = EphemeralResolver.doEphemeralResolutionPhaseOne(
+                    mContext, mEphemeralResolverConnection, requestObject);
             if (intentInfo != null) {
                 if (DEBUG_EPHEMERAL) {
                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                 }
                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
-                ephemeralInstaller.ephemeralIntentInfo = intentInfo;
+                ephemeralInstaller.ephemeralResponse = intentInfo;
                 // make sure this resolver is the default
                 ephemeralInstaller.isDefault = true;
                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7238,15 +7208,15 @@
 
         // Before everything else, see whether we need to fstrim.
         try {
-            IMountService ms = PackageHelper.getMountService();
-            if (ms != null) {
+            IStorageManager sm = PackageHelper.getStorageManager();
+            if (sm != null) {
                 boolean doTrim = false;
                 final long interval = android.provider.Settings.Global.getLong(
                         mContext.getContentResolver(),
                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
                 if (interval > 0) {
-                    final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
+                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
                     if (timeSinceLast > interval) {
                         doTrim = true;
                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
@@ -7260,19 +7230,19 @@
                     }
                     if (!isFirstBoot() && dexOptDialogShown) {
                         try {
-                            ActivityManagerNative.getDefault().showBootMessage(
+                            ActivityManager.getService().showBootMessage(
                                     mContext.getResources().getString(
                                             R.string.android_upgrading_fstrim), true);
                         } catch (RemoteException e) {
                         }
                     }
-                    ms.runMaintenance();
+                    sm.runMaintenance();
                 }
             } else {
-                Slog.e(TAG, "Mount service unavailable!");
+                Slog.e(TAG, "storageManager service unavailable!");
             }
         } catch (RemoteException e) {
-            // Can't happen; MountService is local
+            // Can't happen; StorageManagerService is local
         }
     }
 
@@ -7347,7 +7317,7 @@
 
             if (showDialog) {
                 try {
-                    ActivityManagerNative.getDefault().showBootMessage(
+                    ActivityManager.getService().showBootMessage(
                             mContext.getResources().getString(R.string.android_upgrading_apk,
                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
                 } catch (RemoteException e) {
@@ -9695,7 +9665,7 @@
         // version of the application while the new one gets installed.
         final long token = Binder.clearCallingIdentity();
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 try {
                     am.killApplication(pkgName, appId, userId, reason);
@@ -10395,14 +10365,28 @@
 
     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
             BasePermission bp, PermissionsState origPermissions) {
-        boolean allowed;
-        allowed = (compareSignatures(
+        boolean privilegedPermission = (bp.protectionLevel
+                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
+        boolean controlPrivappPermissions = RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS;
+        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
+        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
+        if (controlPrivappPermissions && privilegedPermission && pkg.isPrivilegedApp()
+                && !platformPackage && platformPermission) {
+            ArraySet<String> wlPermissions = SystemConfig.getInstance()
+                    .getPrivAppPermissions(pkg.packageName);
+            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
+            if (!whitelisted) {
+                // Log for now. TODO Enforce permissions
+                Slog.w(TAG, "Privileged permission " + perm + " for package "
+                        + pkg.packageName + " - not in privapp-permissions whitelist");
+            }
+        }
+        boolean allowed = (compareSignatures(
                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
                         == PackageManager.SIGNATURE_MATCH)
                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
                         == PackageManager.SIGNATURE_MATCH);
-        if (!allowed && (bp.protectionLevel
-                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
+        if (!allowed && privilegedPermission) {
             if (isSystemApp(pkg)) {
                 // For updated system applications, a system permission
                 // is granted only if it had been defined by the original application.
@@ -11453,8 +11437,8 @@
         private int mFlags;
     }
 
-    private static final class EphemeralIntentResolver
-            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveIntentInfo> {
+    static final class EphemeralIntentResolver
+            extends IntentResolver<EphemeralResponse, EphemeralResponse> {
         /**
          * The result that has the highest defined order. Ordering applies on a
          * per-package basis. Mapping is from package name to Pair of order and
@@ -11469,46 +11453,46 @@
         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
 
         @Override
-        protected EphemeralResolveIntentInfo[] newArray(int size) {
-            return new EphemeralResolveIntentInfo[size];
+        protected EphemeralResponse[] newArray(int size) {
+            return new EphemeralResponse[size];
         }
 
         @Override
-        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
+        protected boolean isPackageForFilter(String packageName, EphemeralResponse responseObj) {
             return true;
         }
 
         @Override
-        protected EphemeralResolveIntentInfo newResult(EphemeralResolveIntentInfo info, int match,
+        protected EphemeralResponse newResult(EphemeralResponse responseObj, int match,
                 int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
             }
-            final String packageName = info.getEphemeralResolveInfo().getPackageName();
-            final Integer order = info.getOrder();
+            final String packageName = responseObj.resolveInfo.getPackageName();
+            final Integer order = responseObj.getOrder();
             final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
                     mOrderResult.get(packageName);
             // ordering is enabled and this item's order isn't high enough
             if (lastOrderResult != null && lastOrderResult.first >= order) {
                 return null;
             }
-            final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
+            final EphemeralResolveInfo res = responseObj.resolveInfo;
             if (order > 0) {
                 // non-zero order, enable ordering
                 mOrderResult.put(packageName, new Pair<>(order, res));
             }
-            return info;
+            return responseObj;
         }
 
         @Override
-        protected void filterResults(List<EphemeralResolveIntentInfo> results) {
+        protected void filterResults(List<EphemeralResponse> results) {
             // only do work if ordering is enabled [most of the time it won't be]
             if (mOrderResult.size() == 0) {
                 return;
             }
             int resultSize = results.size();
             for (int i = 0; i < resultSize; i++) {
-                final EphemeralResolveInfo info = results.get(i).getEphemeralResolveInfo();
+                final EphemeralResolveInfo info = results.get(i).resolveInfo;
                 final String packageName = info.getPackageName();
                 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
                 if (savedInfo == null) {
@@ -11587,7 +11571,7 @@
             @Override
             public void run() {
                 try {
-                    final IActivityManager am = ActivityManagerNative.getDefault();
+                    final IActivityManager am = ActivityManager.getService();
                     if (am == null) return;
                     final int[] resolvedUserIds;
                     if (userIds == null) {
@@ -11684,7 +11668,7 @@
         }
         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (am != null) {
             try {
                 am.startService(null, intent, null, mContext.getOpPackageName(),
@@ -11834,7 +11818,7 @@
         if (!mUserManagerInternal.isUserRunning(userId)) {
             return;
         }
-        final IActivityManager am = ActivityManagerNative.getDefault();
+        final IActivityManager am = ActivityManager.getService();
         try {
             // Deliver LOCKED_BOOT_COMPLETED first
             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
@@ -13796,7 +13780,7 @@
     }
 
     /**
-     * Extract the MountService "container ID" from the full code path of an
+     * Extract the StorageManagerService "container ID" from the full code path of an
      * .apk.
      */
     static String cidFromCodePath(String fullCodePath) {
@@ -14261,11 +14245,13 @@
     }
 
     private File getNextCodePath(File targetDir, String packageName) {
-        int suffix = 1;
         File result;
+        SecureRandom random = new SecureRandom();
+        byte[] bytes = new byte[16];
         do {
+            random.nextBytes(bytes);
+            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
             result = new File(targetDir, packageName + "-" + suffix);
-            suffix++;
         } while (result.exists());
         return result;
     }
@@ -17125,7 +17111,7 @@
 
     private void postPreferredActivityChangedBroadcast(int userId) {
         mHandler.post(() -> {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             if (am == null) {
                 return;
             }
@@ -18397,10 +18383,10 @@
         mInstallerService.systemReady();
         mPackageDexOptimizer.systemReady();
 
-        MountServiceInternal mountServiceInternal = LocalServices.getService(
-                MountServiceInternal.class);
-        mountServiceInternal.addExternalStoragePolicy(
-                new MountServiceInternal.ExternalStorageMountPolicy() {
+        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
+                StorageManagerInternal.class);
+        StorageManagerInternal.addExternalStoragePolicy(
+                new StorageManagerInternal.ExternalStorageMountPolicy() {
             @Override
             public int getMountMode(int uid, String packageName) {
                 if (Process.isIsolated(uid)) {
@@ -19278,7 +19264,7 @@
     }
 
     /**
-     * Called by MountService when the initial ASECs to scan are available.
+     * Called by StorageManagerService when the initial ASECs to scan are available.
      * Should block until all the ASEC containers are finished being scanned.
      */
     public void scanAvailableAsecs() {
@@ -20790,7 +20776,7 @@
             }
             // kill any non-foreground processes so we restart them and
             // grant/revoke the GID.
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 final long token = Binder.clearCallingIdentity();
                 try {
@@ -21289,6 +21275,14 @@
         public String getNameForUid(int uid) {
             return PackageManagerService.this.getNameForUid(uid);
         }
+
+        @Override
+        public void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+                Intent origIntent, String resolvedType, Intent launchIntent,
+                String callingPackage, int userId) {
+            PackageManagerService.this.requestEphemeralResolutionPhaseTwo(
+                    responseObj, origIntent, resolvedType, launchIntent, callingPackage, userId);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 42cc3a8..eef8ce2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1415,7 +1415,6 @@
         VersionInfo ver = mVersion.get(volumeUuid);
         if (ver == null) {
             ver = new VersionInfo();
-            ver.forceCurrent();
             mVersion.put(volumeUuid, ver);
         }
         return ver;
@@ -2802,8 +2801,8 @@
                             "No settings file; creating initial state");
                     // It's enough to just touch version details to create them
                     // with default values
-                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL);
-                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL);
+                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
+                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
                     return false;
                 }
                 str = new FileInputStream(mSettingsFilename);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 5a0bee1..7b877f7 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -21,7 +21,6 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
 import android.app.usage.UsageStatsManagerInternal;
@@ -3669,7 +3668,7 @@
     @VisibleForTesting
     void injectRegisterUidObserver(IUidObserver observer, int which) {
         try {
-            ActivityManagerNative.getDefault().registerUidObserver(observer, which,
+            ActivityManager.getService().registerUidObserver(observer, which,
                     ActivityManager.PROCESS_STATE_UNKNOWN, null);
         } catch (RemoteException shouldntHappen) {
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 67488ce..5b47b6f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -26,7 +26,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
@@ -757,11 +756,11 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 if (enableQuietMode) {
-                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
+                    ActivityManager.getService().stopUser(userHandle, /* force */true, null);
                     LocalServices.getService(ActivityManagerInternal.class)
                             .killForegroundAppsForUser(userHandle);
                 } else {
-                    ActivityManagerNative.getDefault().startUserInBackground(userHandle);
+                    ActivityManager.getService().startUserInBackground(userHandle);
                 }
             } catch (RemoteException e) {
                 Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e);
@@ -1414,7 +1413,7 @@
         // First, invalidate all cached values.
         mCachedEffectiveUserRestrictions.clear();
 
-        // We don't want to call into ActivityManagerNative while taking a lock, so we'll call
+        // We don't want to call into ActivityManagerService while taking a lock, so we'll call
         // it on a handler.
         final Runnable r = new Runnable() {
             @Override
@@ -1422,9 +1421,9 @@
                 // Then get the list of running users.
                 final int[] runningUsers;
                 try {
-                    runningUsers = ActivityManagerNative.getDefault().getRunningUserIds();
+                    runningUsers = ActivityManager.getService().getRunningUserIds();
                 } catch (RemoteException e) {
-                    Log.w(LOG_TAG, "Unable to access ActivityManagerNative");
+                    Log.w(LOG_TAG, "Unable to access ActivityManagerService");
                     return;
                 }
                 // Then re-calculate the effective restrictions and apply, only for running users.
@@ -2536,7 +2535,7 @@
             if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
             int res;
             try {
-                res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true,
+                res = ActivityManager.getService().stopUser(userHandle, /* force= */ true,
                 new IStopUserCallback.Stub() {
                             @Override
                             public void userStopped(int userId) {
@@ -3259,7 +3258,7 @@
     }
 
     private int runList(PrintWriter pw) throws RemoteException {
-        final IActivityManager am = ActivityManagerNative.getDefault();
+        final IActivityManager am = ActivityManager.getService();
         final List<UserInfo> users = getUsers(false);
         if (users == null) {
             pw.println("Error: couldn't get users");
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 3df13a9..9fe0922 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -23,7 +23,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.Binder;
@@ -411,7 +410,7 @@
                         int currentUser = ActivityManager.getCurrentUser();
                         if (currentUser != userId && userId != UserHandle.USER_SYSTEM) {
                             try {
-                                ActivityManagerNative.getDefault().stopUser(userId, false, null);
+                                ActivityManager.getService().stopUser(userId, false, null);
                             } catch (RemoteException e) {
                                 throw e.rethrowAsRuntimeException();
                             }
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 3bea663..d4adcc4 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -27,7 +27,6 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -434,7 +433,7 @@
                         // Take an "interactive" bugreport.
                         MetricsLogger.action(mContext,
                                 MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE);
-                        ActivityManagerNative.getDefault().requestBugReport(
+                        ActivityManager.getService().requestBugReport(
                                 ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
                     } catch (RemoteException e) {
                     }
@@ -452,7 +451,7 @@
             try {
                 // Take a "full" bugreport.
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_FULL);
-                ActivityManagerNative.getDefault().requestBugReport(
+                ActivityManager.getService().requestBugReport(
                         ActivityManager.BUGREPORT_OPTION_FULL);
             } catch (RemoteException e) {
             }
@@ -592,7 +591,7 @@
 
     private UserInfo getCurrentUser() {
         try {
-            return ActivityManagerNative.getDefault().getCurrentUser();
+            return ActivityManager.getService().getCurrentUser();
         } catch (RemoteException re) {
             return null;
         }
@@ -620,7 +619,7 @@
                             + (isCurrentUser ? " \u2714" : "")) {
                         public void onPress() {
                             try {
-                                ActivityManagerNative.getDefault().switchUser(user.id);
+                                ActivityManager.getService().switchUser(user.id);
                             } catch (RemoteException re) {
                                 Log.e(TAG, "Couldn't switch user " + re);
                             }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 396c958..ccdda13 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -114,7 +114,6 @@
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
 import android.app.ProgressDialog;
@@ -2678,9 +2677,10 @@
     }
 
     @Override
-    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode) {
-        if (mHasNavigationBar) {
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        // TODO(multi-display): Support navigation bar on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) {
             // For a basic navigation bar, when we are in landscape mode we place
             // the navigation bar to the side.
             if (mNavigationBarCanMove && fullWidth > fullHeight) {
@@ -2699,9 +2699,10 @@
     }
 
     @Override
-    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode) {
-        if (mHasNavigationBar) {
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        // TODO(multi-display): Support navigation bar on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) {
             // For a basic navigation bar, when we are in portrait mode we place
             // the navigation bar to the bottom.
             if (!mNavigationBarCanMove || fullWidth < fullHeight) {
@@ -2712,18 +2713,24 @@
     }
 
     @Override
-    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
-        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode);
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId);
     }
 
     @Override
-    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         // There is a separate status bar at the top of the display.  We don't count that as part
         // of the fixed decor, since it can hide; however, for purposes of configurations,
         // we do want to exclude it since applications can't generally use that part
         // of the screen.
-        return getNonDecorDisplayHeight(
-                fullWidth, fullHeight, rotation, uiMode) - mStatusBarHeight;
+        // TODO(multi-display): Support status bars on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY) {
+            return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId)
+                    - mStatusBarHeight;
+        }
+        return fullHeight;
     }
 
     @Override
@@ -3943,7 +3950,7 @@
                     public void onKeyguardExitResult(boolean success) {
                         if (success) {
                             try {
-                                ActivityManagerNative.getDefault().stopAppSwitches();
+                                ActivityManager.getService().stopAppSwitches();
                             } catch (RemoteException e) {
                             }
                             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
@@ -3957,7 +3964,7 @@
 
         // no keyguard stuff to worry about, just launch home!
         try {
-            ActivityManagerNative.getDefault().stopAppSwitches();
+            ActivityManager.getService().stopAppSwitches();
         } catch (RemoteException e) {
         }
         if (mRecentsVisible) {
@@ -7340,7 +7347,7 @@
         if (false) {
             // This code always brings home to the front.
             try {
-                ActivityManagerNative.getDefault().stopAppSwitches();
+                ActivityManager.getService().stopAppSwitches();
             } catch (RemoteException e) {
             }
             sendCloseSystemWindows();
@@ -7353,11 +7360,11 @@
                     /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
                     Log.d(TAG, "UTS-TEST-MODE");
                 } else {
-                    ActivityManagerNative.getDefault().stopAppSwitches();
+                    ActivityManager.getService().stopAppSwitches();
                     sendCloseSystemWindows();
                     Intent dock = createHomeDockIntent();
                     if (dock != null) {
-                        int result = ActivityManagerNative.getDefault()
+                        int result = ActivityManager.getService()
                                 .startActivityAsUser(null, null, dock,
                                         dock.resolveTypeIfNeeded(mContext.getContentResolver()),
                                         null, null, 0,
@@ -7368,7 +7375,7 @@
                         }
                     }
                 }
-                int result = ActivityManagerNative.getDefault()
+                int result = ActivityManager.getService()
                         .startActivityAsUser(null, null, mHomeIntent,
                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                 null, null, 0,
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index ca641fb..f37f987 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,6 +1,6 @@
 package com.android.server.policy.keyguard;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -194,7 +194,7 @@
             mKeyguardState.reset();
             mHandler.post(() -> {
                 try {
-                    ActivityManagerNative.getDefault().setLockScreenShown(true);
+                    ActivityManager.getService().setLockScreenShown(true);
                 } catch (RemoteException e) {
                     // Local call.
                 }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 00700b8..b215998 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -25,7 +25,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 
-import android.app.ActivityManagerNative;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index a920d54..cd966ef 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -43,8 +43,8 @@
 import android.os.UserManager;
 import android.os.Vibrator;
 import android.os.SystemVibrator;
-import android.os.storage.IMountService;
-import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IStorageShutdownObserver;
+import android.os.storage.IStorageManager;
 import android.system.ErrnoException;
 import android.system.Os;
 
@@ -442,30 +442,30 @@
             sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);
         }
 
-        // Shutdown MountService to ensure media is in a safe state
-        IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
+        // Shutdown StorageManagerService to ensure media is in a safe state
+        IStorageShutdownObserver observer = new IStorageShutdownObserver.Stub() {
             public void onShutDownComplete(int statusCode) throws RemoteException {
-                Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown");
+                Log.w(TAG, "Result code " + statusCode + " from StorageManagerService.shutdown");
                 actionDone();
             }
         };
 
-        Log.i(TAG, "Shutting down MountService");
+        Log.i(TAG, "Shutting down StorageManagerService");
 
         // Set initial variables and time out time.
         mActionDone = false;
         final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
         synchronized (mActionDoneSync) {
             try {
-                final IMountService mount = IMountService.Stub.asInterface(
+                final IStorageManager storageManager = IStorageManager.Stub.asInterface(
                         ServiceManager.checkService("mount"));
-                if (mount != null) {
-                    mount.shutdown(observer);
+                if (storageManager != null) {
+                    storageManager.shutdown(observer);
                 } else {
-                    Log.w(TAG, "MountService unavailable for shutdown");
+                    Log.w(TAG, "StorageManagerService unavailable for shutdown");
                 }
             } catch (Exception e) {
-                Log.e(TAG, "Exception during MountService shutdown", e);
+                Log.e(TAG, "Exception during StorageManagerService shutdown", e);
             }
             while (!mActionDone) {
                 long delay = endShutTime - SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index f3b9b18..b5aa4a9 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ISearchManager;
@@ -306,7 +305,7 @@
         try {
             Intent intent = new Intent(Intent.ACTION_ASSIST);
             intent.setComponent(comp);
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
                     userHandle, args);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 62f5468..9d02940 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -26,7 +26,6 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.ITrustListener;
 import android.app.trust.ITrustManager;
@@ -868,7 +867,7 @@
                     }
                     if (locked) {
                         try {
-                            ActivityManagerNative.getDefault().notifyLockedProfile(userId);
+                            ActivityManager.getService().notifyLockedProfile(userId);
                         } catch (RemoteException e) {
                         }
                     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 96662b5..3645c24 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -26,7 +26,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IWallpaperManager;
@@ -959,7 +958,7 @@
         }, shutdownFilter);
 
         try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(
+            ActivityManager.getService().registerUserSwitchObserver(
                     new UserSwitchObserver() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 302f9f6..61319cf 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -16,7 +16,7 @@
 
 package com.android.server.webkit;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -200,7 +200,7 @@
     @Override
     public void killPackageDependents(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killPackageDependents(packageName,
+            ActivityManager.getService().killPackageDependents(packageName,
                     UserHandle.USER_ALL);
         } catch (RemoteException e) {
         }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 6d97796..0a7454f 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -36,6 +36,7 @@
 import com.android.server.SystemService;
 
 import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.Arrays;
 
 /**
@@ -259,5 +260,18 @@
                 Binder.restoreCallingIdentity(callingId);
             }
         }
+
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+
+                pw.println("Permission Denial: can't dump webviewupdate service from pid="
+                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+                return;
+            }
+
+            WebViewUpdateService.this.mImpl.dumpState(pw);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 453e745..1a77c68 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -30,6 +30,7 @@
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -673,6 +674,27 @@
             mMinimumVersionCode = minimumVersionCode;
             return mMinimumVersionCode;
         }
+
+        public void dumpState(PrintWriter pw) {
+            synchronized (mLock) {
+                if (mCurrentWebViewPackage == null) {
+                    pw.println("  Current WebView package is null");
+                } else {
+                    pw.println(String.format("  Current WebView package (name, version): (%s, %s)",
+                            mCurrentWebViewPackage.packageName,
+                            mCurrentWebViewPackage.versionName));
+                }
+                pw.println(String.format("  Minimum WebView version code: %d",
+                      mMinimumVersionCode));
+                pw.println(String.format("  Number of relros started: %d",
+                        mNumRelroCreationsStarted));
+                pw.println(String.format("  Number of relros finished: %d",
+                            mNumRelroCreationsFinished));
+                pw.println(String.format("  WebView package dirty: %b", mWebViewPackageDirty));
+                pw.println(String.format("  Any WebView package installed: %b",
+                        mAnyWebViewInstalled));
+            }
+        }
     }
 
     private static boolean providerHasValidSignature(WebViewProviderInfo provider,
@@ -741,4 +763,14 @@
             mSystemInterface.setMultiProcessEnabledFromContext(mContext);
         }
     }
+
+    /**
+     * Dump the state of this Service.
+     */
+    void dumpState(PrintWriter pw) {
+        pw.println("Current WebView Update Service state");
+        pw.println(String.format("  Fallback logic enabled: %b",
+                mSystemInterface.isFallbackLogicEnabled()));
+        mWebViewUpdater.dumpState(pw);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 05e6f96..0844d48 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -47,6 +47,7 @@
 import static com.android.server.wm.WindowManagerService.logWithStack;
 
 import android.os.Debug;
+import com.android.internal.util.ToBooleanFunction;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.wm.WindowManagerService.H;
 
@@ -66,7 +67,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.function.Consumer;
+import java.util.function.Function;
 
 class AppTokenList extends ArrayList<AppWindowToken> {
 }
@@ -1270,19 +1271,20 @@
     }
 
     @Override
-    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+    boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
         // before the non-exiting app tokens. So, we skip the exiting app tokens here.
         // TODO: Investigate if we need to continue to do this or if we can just process them
         // in-order.
         if (mIsExiting && !waitingForReplacement()) {
-            return;
+            return false;
         }
-        forAllWindowsUnchecked(callback, traverseTopToBottom);
+        return forAllWindowsUnchecked(callback, traverseTopToBottom);
     }
 
-    void forAllWindowsUnchecked(Consumer<WindowState> callback, boolean traverseTopToBottom) {
-        super.forAllWindows(callback, traverseTopToBottom);
+    boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
+            boolean traverseTopToBottom) {
+        return super.forAllWindows(callback, traverseTopToBottom);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ff39853..e73acde 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -127,6 +127,7 @@
 import android.view.WindowManagerPolicy;
 
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.ToBooleanFunction;
 import com.android.internal.view.IInputMethodClient;
 import com.android.server.input.InputWindowHandle;
 
@@ -141,6 +142,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.function.Consumer;
+import java.util.function.Function;
 
 /**
  * Utility class for keeping track of the WindowStates and other pertinent contents of a
@@ -725,7 +727,8 @@
             win.getTouchableRegion(mTmpRegion);
             mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
         }
-        if (getDockedStackLocked() != null) {
+        // TODO(multi-display): Support docked stacks on secondary displays.
+        if (mDisplayId == DEFAULT_DISPLAY && getDockedStackLocked() != null) {
             mDividerControllerLocked.getTouchRegion(mTmpRect);
             mTmpRegion.set(mTmpRect);
             mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
@@ -1407,9 +1410,7 @@
     }
 
     void adjustWallpaperWindows() {
-        if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
-            assignWindowLayers(true /*setLayoutNeeded*/);
-        }
+        mWallpaperController.adjustWallpaperWindows(this);
     }
 
     /**
@@ -3235,17 +3236,27 @@
         }
 
         @Override
-        void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+        boolean forAllWindows(ToBooleanFunction<WindowState> callback,
+                boolean traverseTopToBottom) {
             if (traverseTopToBottom) {
-                super.forAllWindows(callback, traverseTopToBottom);
-                forAllExitingAppTokenWindows(callback, traverseTopToBottom);
+                if (super.forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
+                if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             } else {
-                forAllExitingAppTokenWindows(callback, traverseTopToBottom);
-                super.forAllWindows(callback, traverseTopToBottom);
+                if (forAllExitingAppTokenWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
+                if (super.forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             }
+            return false;
         }
 
-        private void forAllExitingAppTokenWindows(Consumer<WindowState> callback,
+        private boolean forAllExitingAppTokenWindows(ToBooleanFunction<WindowState> callback,
                 boolean traverseTopToBottom) {
             // For legacy reasons we process the TaskStack.mExitingAppTokens first here before the
             // app tokens.
@@ -3255,7 +3266,10 @@
                 for (int i = mChildren.size() - 1; i >= 0; --i) {
                     final AppTokenList appTokens = mChildren.get(i).mExitingAppTokens;
                     for (int j = appTokens.size() - 1; j >= 0; --j) {
-                        appTokens.get(j).forAllWindowsUnchecked(callback, traverseTopToBottom);
+                        if (appTokens.get(j).forAllWindowsUnchecked(callback,
+                                traverseTopToBottom)) {
+                            return true;
+                        }
                     }
                 }
             } else {
@@ -3264,10 +3278,14 @@
                     final AppTokenList appTokens = mChildren.get(i).mExitingAppTokens;
                     final int appTokensCount = appTokens.size();
                     for (int j = 0; j < appTokensCount; j++) {
-                        appTokens.get(j).forAllWindowsUnchecked(callback, traverseTopToBottom);
+                        if (appTokens.get(j).forAllWindowsUnchecked(callback,
+                                traverseTopToBottom)) {
+                            return true;
+                        }
                     }
                 }
             }
+            return false;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index c56f6b8..f8b461e 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -206,10 +206,12 @@
             config.unset();
             config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
             config.screenWidthDp = (int)
-                    (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode) /
+                    (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode,
+                            mDisplayContent.getDisplayId()) /
                             mDisplayContent.getDisplayMetrics().density);
             config.screenHeightDp = (int)
-                    (mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode) /
+                    (mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode,
+                            mDisplayContent.getDisplayId()) /
                             mDisplayContent.getDisplayMetrics().density);
             final Context rotationContext = mService.mContext.createConfigurationContext(config);
             mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
diff --git a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
index 7cb6fc3..70478fe 100644
--- a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ClipData;
 import android.net.Uri;
 import android.os.Binder;
@@ -61,7 +61,7 @@
         mActivityToken = activityToken;
 
         // Will throw if Activity is not found.
-        IBinder permissionOwner = ActivityManagerNative.getDefault().
+        IBinder permissionOwner = ActivityManager.getService().
                 getUriPermissionOwnerForActivity(mActivityToken);
 
         doTake(permissionOwner);
@@ -71,7 +71,7 @@
         long origId = Binder.clearCallingIdentity();
         try {
             for (int i = 0; i < mUris.size(); i++) {
-                ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
+                ActivityManager.getService().grantUriPermissionFromOwner(
                         permissionOwner, mSourceUid, mTargetPackage, mUris.get(i), mMode,
                         mSourceUserId, mTargetUserId);
             }
@@ -85,7 +85,7 @@
         if (mActivityToken != null || mPermissionOwnerToken != null) {
             return;
         }
-        mPermissionOwnerToken = ActivityManagerNative.getDefault().newUriPermissionOwner("drop");
+        mPermissionOwnerToken = ActivityManager.getService().newUriPermissionOwner("drop");
         mTransientToken = transientToken;
         mTransientToken.linkToDeath(this, 0);
 
@@ -101,7 +101,7 @@
         IBinder permissionOwner = null;
         if (mActivityToken != null) {
             try {
-                permissionOwner = ActivityManagerNative.getDefault().
+                permissionOwner = ActivityManager.getService().
                         getUriPermissionOwnerForActivity(mActivityToken);
             } catch (Exception e) {
                 // Activity is destroyed, permissions already revoked.
@@ -117,7 +117,7 @@
         }
 
         for (int i = 0; i < mUris.size(); ++i) {
-            ActivityManagerNative.getDefault().revokeUriPermissionFromOwner(
+            ActivityManager.getService().revokeUriPermissionFromOwner(
                     permissionOwner, mUris.get(i), mMode, mSourceUserId);
         }
     }
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 4d195e8..40b737d 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -271,8 +271,9 @@
             Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
         }
 
-        mDisplayContent.forAllWindows((w) -> sendDragStartedLw(w, touchX, touchY, mDataDescription),
-                false /* traverseTopToBottom */ );
+        mDisplayContent.forAllWindows(w -> {
+            sendDragStartedLw(w, touchX, touchY, mDataDescription);
+        }, false /* traverseTopToBottom */ );
     }
 
     /* helper - send a ACTION_DRAG_STARTED event, if the
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index a8eb75c..12c72e9 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -26,7 +26,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.graphics.Rect;
 import android.os.Debug;
 import android.os.Looper;
@@ -252,7 +252,7 @@
             try {
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
-                long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
+                long timeout = ActivityManager.getService().inputDispatchingTimedOut(
                         windowState.mSession.mPid, aboveSystem, reason);
                 if (timeout >= 0) {
                     // The activity manager declined to abort dispatching.
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index 377071d..2eb186b 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -19,7 +19,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.Handler;
@@ -101,7 +101,7 @@
             if (dpm != null) {
                 try {
                     mAllowDisableKeyguard = dpm.getPasswordQuality(null,
-                            ActivityManagerNative.getDefault().getCurrentUser().id)
+                            ActivityManager.getService().getCurrentUser().id)
                             == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
                                     ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
                 } catch (RemoteException re) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index d3e8e8e..8dbf2b3 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -17,9 +17,9 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 
@@ -30,8 +30,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
-import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
-import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
 
 import android.os.Bundle;
 import android.os.Debug;
@@ -61,11 +59,8 @@
     // with the wallpaper.
     private WindowState mWallpaperTarget = null;
     // If non-null, we are in the middle of animating from one wallpaper target
-    // to another, and this is the lower one in Z-order.
-    private WindowState mLowerWallpaperTarget = null;
-    // If non-null, we are in the middle of animating from one wallpaper target
-    // to another, and this is the higher one in Z-order.
-    private WindowState mUpperWallpaperTarget = null;
+    // to another, and this is the previous wallpaper target.
+    private WindowState mPrevWallpaperTarget = null;
 
     private int mWallpaperAnimLayerAdjustment;
 
@@ -78,7 +73,7 @@
 
     // This is set when we are waiting for a wallpaper to tell us it is done
     // changing its scroll position.
-    WindowState mWaitingOnWallpaper;
+    private WindowState mWaitingOnWallpaper;
 
     // The last time we had a timeout when waiting for a wallpaper.
     private long mLastWallpaperTimeoutTime;
@@ -110,14 +105,6 @@
         return mWallpaperTarget;
     }
 
-    WindowState getLowerWallpaperTarget() {
-        return mLowerWallpaperTarget;
-    }
-
-    WindowState getUpperWallpaperTarget() {
-        return mUpperWallpaperTarget;
-    }
-
     boolean isWallpaperTarget(WindowState win) {
         return win == mWallpaperTarget;
     }
@@ -145,13 +132,11 @@
                 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
                 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
                 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
-                + " upper=" + mUpperWallpaperTarget
-                + " lower=" + mLowerWallpaperTarget);
+                + " prev=" + mPrevWallpaperTarget);
         return (wallpaperTarget != null
                 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
                 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
-                || mUpperWallpaperTarget != null
-                || mLowerWallpaperTarget != null;
+                || mPrevWallpaperTarget != null;
     }
 
     boolean isWallpaperTargetAnimating() {
@@ -177,7 +162,7 @@
 
     void hideWallpapers(final WindowState winGoingAway) {
         if (mWallpaperTarget != null
-                && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
+                && (mWallpaperTarget != winGoingAway || mPrevWallpaperTarget != null)) {
             return;
         }
         if (mService.mAppTransition.isRunning()) {
@@ -192,8 +177,8 @@
             final WallpaperWindowToken token = mWallpaperTokens.get(i);
             token.hideWallpaperToken(wasDeferred, "hideWallpapers");
             if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
-                    + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
-                    + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, "  "));
+                    + " from " + winGoingAway + " target=" + mWallpaperTarget + " prev="
+                    + mPrevWallpaperTarget + "\n" + Debug.getCallers(5, "  "));
         }
     }
 
@@ -299,9 +284,7 @@
 
     Bundle sendWindowWallpaperCommand(
             WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
-        if (window == mWallpaperTarget
-                || window == mLowerWallpaperTarget
-                || window == mUpperWallpaperTarget) {
+        if (window == mWallpaperTarget || window == mPrevWallpaperTarget) {
             boolean doWait = sync;
             for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
                 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
@@ -388,51 +371,52 @@
         return mWallpaperAnimLayerAdjustment;
     }
 
-    private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
+    private void findWallpaperTarget(DisplayContent dc , FindWallpaperTargetResult result) {
         final WindowAnimator winAnimator = mService.mAnimator;
         result.reset();
-        WindowState w = null;
-        int windowDetachedI = -1;
-        boolean resetTopWallpaper = false;
-        boolean inFreeformSpace = false;
-        boolean replacing = false;
-        boolean keyguardGoingAwayWithWallpaper = false;
-        boolean needsShowWhenLockedWallpaper = false;
+        if (mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
+            // In freeform mode we set the wallpaper as its own target, so we don't need an
+            // additional window to make it visible.
+            result.setUseTopWallpaperAsTarget(true);
+        }
 
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            w = windows.get(i);
+        dc.forAllWindows(w -> {
             if ((w.mAttrs.type == TYPE_WALLPAPER)) {
-                if (result.topWallpaper == null || resetTopWallpaper) {
-                    result.setTopWallpaper(w, i);
-                    resetTopWallpaper = false;
+                if (result.topWallpaper == null || result.resetTopWallpaper) {
+                    result.setTopWallpaper(w);
+                    result.resetTopWallpaper = false;
                 }
-                continue;
+                return false;
             }
-            resetTopWallpaper = true;
+
+            result.resetTopWallpaper = true;
             if (w != winAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
                 // If this window's app token is hidden and not animating,
                 // it is of no interest to us.
                 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
                     if (DEBUG_WALLPAPER) Slog.v(TAG,
                             "Skipping hidden and not animating token: " + w);
-                    continue;
+                    return false;
                 }
             }
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
-                    + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
+                    + " mDrawState=" + w.mWinAnimator.mDrawState);
 
-            if (!inFreeformSpace) {
-                TaskStack stack = w.getStack();
-                inFreeformSpace = stack != null && stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+            if (w.mWillReplaceWindow && mWallpaperTarget == null
+                    && !result.useTopWallpaperAsTarget) {
+                // When we are replacing a window and there was wallpaper before replacement, we
+                // want to keep the window until the new windows fully appear and can determine the
+                // visibility, to avoid flickering.
+                result.setUseTopWallpaperAsTarget(true);
             }
 
-            replacing |= w.mWillReplaceWindow;
-            keyguardGoingAwayWithWallpaper |= (w.mAppToken != null
+            final boolean keyguardGoingAwayWithWallpaper = (w.mAppToken != null
                     && AppTransition.isKeyguardGoingAwayTransit(
                             w.mAppToken.mAppAnimator.getTransit())
                     && (w.mAppToken.mAppAnimator.getTransitFlags()
                             & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
 
+            boolean needsShowWhenLockedWallpaper = false;
             if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
                     && mService.mPolicy.isKeyguardLocked()
                     && mService.mPolicy.isKeyguardOccluded()) {
@@ -442,248 +426,147 @@
                         || (w.mAppToken != null && !w.mAppToken.fillsParent());
             }
 
+            if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
+                // Keep the wallpaper during Keyguard exit but also when it's needed for a
+                // non-fullscreen show when locked activity.
+                result.setUseTopWallpaperAsTarget(true);
+            }
+
             final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
             if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
-                if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
-                result.setWallpaperTarget(w, i);
+                if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
+                result.setWallpaperTarget(w);
                 if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
                     // The current wallpaper target is animating, so we'll look behind it for
                     // another possible target and figure out what is going on later.
                     if (DEBUG_WALLPAPER) Slog.v(TAG,
                             "Win " + w + ": token animating, looking behind.");
-                    continue;
                 }
-                break;
+                // Found a target! End search.
+                return true;
             } else if (w == winAnimator.mWindowDetachedWallpaper) {
-                windowDetachedI = i;
+                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                        "Found animating detached wallpaper target win: " + w);
+                result.setUseTopWallpaperAsTarget(true);
             }
-        }
+            return false;
+        }, true /* traverseTopToBottom */);
 
-        if (result.wallpaperTarget != null) {
-            return;
-        }
-
-        if (windowDetachedI >= 0) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Found animating detached wallpaper activity: #" + windowDetachedI + "=" + w);
-            result.setWallpaperTarget(w, windowDetachedI);
-        } else if (inFreeformSpace || (replacing && mWallpaperTarget != null)) {
-            // In freeform mode we set the wallpaper as its own target, so we don't need an
-            // additional window to make it visible. When we are replacing a window and there was
-            // wallpaper before replacement, we want to keep the window until the new windows fully
-            // appear and can determine the visibility, to avoid flickering.
-            result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
-
-        } else if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
-            // Keep the wallpaper during Keyguard exit but also when it's needed for a
-            // non-fullscreen show when locked activity.
-            result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
+        if (result.wallpaperTarget == null && result.useTopWallpaperAsTarget) {
+            result.setWallpaperTarget(result.topWallpaper);
         }
     }
 
     private boolean isFullscreen(WindowManager.LayoutParams attrs) {
         return attrs.x == 0 && attrs.y == 0
-                && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
-                && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
+                && attrs.width == MATCH_PARENT && attrs.height == MATCH_PARENT;
     }
 
     /** Updates the target wallpaper if needed and returns true if an update happened. */
-    private boolean updateWallpaperWindowsTarget(
-            WindowList windows, FindWallpaperTargetResult result) {
+    private void updateWallpaperWindowsTarget(DisplayContent dc,
+            FindWallpaperTargetResult result) {
 
         WindowState wallpaperTarget = result.wallpaperTarget;
-        int wallpaperTargetIndex = result.wallpaperTargetIndex;
 
         if (mWallpaperTarget == wallpaperTarget
-                || (mLowerWallpaperTarget != null && mLowerWallpaperTarget == wallpaperTarget)) {
+                || (mPrevWallpaperTarget != null && mPrevWallpaperTarget == wallpaperTarget)) {
 
-            if (mLowerWallpaperTarget != null) {
-                // Is it time to stop animating?
-                if (!mLowerWallpaperTarget.isAnimatingLw()
-                        || !mUpperWallpaperTarget.isAnimatingLw()) {
-                    if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                            "No longer animating wallpaper targets!");
-                    mLowerWallpaperTarget = null;
-                    mUpperWallpaperTarget = null;
-                    mWallpaperTarget = wallpaperTarget;
-                    return true;
-                }
+            if (mPrevWallpaperTarget == null) {
+                return;
             }
 
-            return false;
+            // Is it time to stop animating?
+            if (!mPrevWallpaperTarget.isAnimatingLw()) {
+                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
+                mPrevWallpaperTarget = null;
+                mWallpaperTarget = wallpaperTarget;
+            }
+            return;
         }
 
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
+                "New wallpaper target: " + wallpaperTarget + " prevTarget: " + mWallpaperTarget);
 
-        mLowerWallpaperTarget = null;
-        mUpperWallpaperTarget = null;
+        mPrevWallpaperTarget = null;
 
-        WindowState oldW = mWallpaperTarget;
+        final WindowState prevWallpaperTarget = mWallpaperTarget;
         mWallpaperTarget = wallpaperTarget;
 
-        if (wallpaperTarget == null || oldW == null) {
-            return true;
+        if (wallpaperTarget == null || prevWallpaperTarget == null) {
+            return;
         }
 
         // Now what is happening...  if the current and new targets are animating,
         // then we are in our super special mode!
-        boolean oldAnim = oldW.isAnimatingLw();
+        boolean oldAnim = prevWallpaperTarget.isAnimatingLw();
         boolean foundAnim = wallpaperTarget.isAnimatingLw();
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
                 "New animation: " + foundAnim + " old animation: " + oldAnim);
 
         if (!foundAnim || !oldAnim) {
-            return true;
+            return;
         }
 
-        int oldI = windows.indexOf(oldW);
-        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                "New i: " + wallpaperTargetIndex + " old i: " + oldI);
-
-        if (oldI < 0) {
-            return true;
+        if (dc.getWindow(w -> w == prevWallpaperTarget) == null) {
+            return;
         }
 
         final boolean newTargetHidden = wallpaperTarget.mAppToken != null
                 && wallpaperTarget.mAppToken.hiddenRequested;
-        final boolean oldTargetHidden = oldW.mAppToken != null
-                && oldW.mAppToken.hiddenRequested;
+        final boolean oldTargetHidden = prevWallpaperTarget.mAppToken != null
+                && prevWallpaperTarget.mAppToken.hiddenRequested;
 
-        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old#" + oldI + "="
-                + oldW + " hidden=" + oldTargetHidden + " new#" + wallpaperTargetIndex + "="
-                + wallpaperTarget + " hidden=" + newTargetHidden);
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old: "
+                + prevWallpaperTarget + " hidden=" + oldTargetHidden + " new: " + wallpaperTarget
+                + " hidden=" + newTargetHidden);
 
-        // Set the upper and lower wallpaper targets correctly,
-        // and make sure that we are positioning the wallpaper below the lower.
-        if (wallpaperTargetIndex > oldI) {
-            // The new target is on top of the old one.
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target above old target.");
-            mUpperWallpaperTarget = wallpaperTarget;
-            mLowerWallpaperTarget = oldW;
-
-            wallpaperTarget = oldW;
-            wallpaperTargetIndex = oldI;
-        } else {
-            // The new target is below the old one.
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target below old target.");
-            mUpperWallpaperTarget = oldW;
-            mLowerWallpaperTarget = wallpaperTarget;
-        }
+        mPrevWallpaperTarget = prevWallpaperTarget;
 
         if (newTargetHidden && !oldTargetHidden) {
             if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Old wallpaper still the target.");
             // Use the old target if new target is hidden but old target
             // is not. If they're both hidden, still use the new target.
-            mWallpaperTarget = oldW;
+            mWallpaperTarget = prevWallpaperTarget;
         } else if (newTargetHidden == oldTargetHidden
                 && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken)
-                && (mService.mOpeningApps.contains(oldW.mAppToken)
-                || mService.mClosingApps.contains(oldW.mAppToken))) {
+                && (mService.mOpeningApps.contains(prevWallpaperTarget.mAppToken)
+                || mService.mClosingApps.contains(prevWallpaperTarget.mAppToken))) {
             // If they're both hidden (or both not hidden), prefer the one that's currently in
             // opening or closing app list, this allows transition selection logic to better
             // determine the wallpaper status of opening/closing apps.
-            mWallpaperTarget = oldW;
+            mWallpaperTarget = prevWallpaperTarget;
         }
 
-        result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
-        return true;
+        result.setWallpaperTarget(wallpaperTarget);
     }
 
-    private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
-            FindWallpaperTargetResult result) {
-
-        WindowState wallpaperTarget = result.wallpaperTarget;
-        int wallpaperTargetIndex = result.wallpaperTargetIndex;
-        boolean visible = wallpaperTarget != null;
-
-        if (visible) {
-            // The window is visible to the compositor...but is it visible to the user?
-            // That is what the wallpaper cares about.
-            visible = isWallpaperVisible(wallpaperTarget);
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
-
-            // If the wallpaper target is animating, we may need to copy its layer adjustment.
-            // Only do this if we are not transferring between two wallpaper targets.
-            mWallpaperAnimLayerAdjustment =
-                    (mLowerWallpaperTarget == null && wallpaperTarget.mAppToken != null)
-                            ? wallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
-
-            final int maxLayer = (mService.mPolicy.getMaxWallpaperLayer() * TYPE_LAYER_MULTIPLIER)
-                    + TYPE_LAYER_OFFSET;
-
-            // Now w is the window we are supposed to be behind...  but we
-            // need to be sure to also be behind any of its attached windows,
-            // AND any starting window associated with it, AND below the
-            // maximum layer the policy allows for wallpapers.
-            while (wallpaperTargetIndex > 0) {
-                final WindowState wb = windows.get(wallpaperTargetIndex - 1);
-                final WindowState wbParentWindow = wb.getParentWindow();
-                final WindowState wallpaperParentWindow = wallpaperTarget.getParentWindow();
-                if (wb.mBaseLayer < maxLayer
-                        && wbParentWindow != wallpaperTarget
-                        && (wallpaperParentWindow == null || wbParentWindow != wallpaperParentWindow)
-                        && (wb.mAttrs.type != TYPE_APPLICATION_STARTING
-                                || wallpaperTarget.mToken == null
-                                || wb.mToken != wallpaperTarget.mToken)) {
-                    // This window is not related to the previous one in any
-                    // interesting way, so stop here.
-                    break;
-                }
-                wallpaperTarget = wb;
-                wallpaperTargetIndex--;
-            }
-        } else {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
-        }
-
-        result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
-        return visible;
-    }
-
-    private boolean updateWallpaperWindowsPlacement(WindowList windows,
-            WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
-
-        // TODO(multidisplay): Wallpapers on main screen only.
-        final DisplayInfo displayInfo = mService.getDefaultDisplayContentLocked().getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        // Start stepping backwards from here, ensuring that our wallpaper windows are correctly placed.
-        boolean changed = false;
+    private void updateWallpaperTokens(boolean visible) {
         for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
             final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
-            changed |= token.updateWallpaperWindowsPlacement(windows, wallpaperTarget,
-                    wallpaperTargetIndex, visible, dw, dh, mWallpaperAnimLayerAdjustment);
+            token.updateWallpaperWindows(visible, mWallpaperAnimLayerAdjustment);
         }
-
-        return changed;
     }
 
-    boolean adjustWallpaperWindows(WindowList windows) {
+    void adjustWallpaperWindows(DisplayContent dc) {
         mService.mRoot.mWallpaperMayChange = false;
 
         // First find top-most window that has asked to be on top of the wallpaper;
         // all wallpapers go behind it.
-        findWallpaperTarget(windows, mFindResults);
-        final boolean targetChanged = updateWallpaperWindowsTarget(windows, mFindResults);
-        final boolean visible = updateWallpaperWindowsTargetByLayer(windows, mFindResults);
-        WindowState wallpaperTarget = mFindResults.wallpaperTarget;
-        int wallpaperTargetIndex = mFindResults.wallpaperTargetIndex;
+        findWallpaperTarget(dc, mFindResults);
+        updateWallpaperWindowsTarget(dc, mFindResults);
 
-        if (wallpaperTarget == null && mFindResults.topWallpaper != null) {
-            // There is no wallpaper target, so it goes at the bottom.
-            // We will assume it is the same place as last time, if known.
-            wallpaperTarget = mFindResults.topWallpaper;
-            wallpaperTargetIndex = mFindResults.topWallpaperIndex + 1;
-        } else {
-            // Okay i is the position immediately above the wallpaper.
-            // Look at what is below it for later.
-            wallpaperTarget = wallpaperTargetIndex > 0
-                    ? windows.get(wallpaperTargetIndex - 1) : null;
-        }
+        // The window is visible to the compositor...but is it visible to the user?
+        // That is what the wallpaper cares about.
+        final boolean visible = mWallpaperTarget != null && isWallpaperVisible(mWallpaperTarget);
+        if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
 
         if (visible) {
+            // If the wallpaper target is animating, we may need to copy its layer adjustment.
+            // Only do this if we are not transferring between two wallpaper targets.
+            mWallpaperAnimLayerAdjustment =
+                    (mPrevWallpaperTarget == null && mWallpaperTarget.mAppToken != null)
+                            ? mWallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
+
             if (mWallpaperTarget.mWallpaperX >= 0) {
                 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
                 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
@@ -700,14 +583,10 @@
             }
         }
 
-        final boolean changed = updateWallpaperWindowsPlacement(
-                windows, wallpaperTarget, wallpaperTargetIndex, visible);
+        updateWallpaperTokens(visible);
 
-        if (targetChanged && DEBUG_WALLPAPER_LIGHT)  Slog.d(TAG, "New wallpaper: target="
-                + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
-                + mUpperWallpaperTarget);
-
-        return changed;
+        if (DEBUG_WALLPAPER_LIGHT)  Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
+                + " prev=" + mPrevWallpaperTarget);
     }
 
     boolean processWallpaperDrawPendingTimeout() {
@@ -773,7 +652,7 @@
         }
 
         if (adjust) {
-            dc.adjustWallpaperWindows();
+            adjustWallpaperWindows(dc);
         }
     }
 
@@ -787,9 +666,8 @@
 
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
-        if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
-            pw.print(prefix); pw.print("mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
-            pw.print(prefix); pw.print("mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
+        if (mPrevWallpaperTarget != null) {
+            pw.print(prefix); pw.print("mPrevWallpaperTarget="); pw.println(mPrevWallpaperTarget);
         }
         pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
         pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
@@ -825,26 +703,28 @@
 
     /** Helper class for storing the results of a wallpaper target find operation. */
     final private static class FindWallpaperTargetResult {
-        int topWallpaperIndex = 0;
         WindowState topWallpaper = null;
-        int wallpaperTargetIndex = 0;
+        boolean useTopWallpaperAsTarget = false;
         WindowState wallpaperTarget = null;
+        boolean resetTopWallpaper = false;
 
-        void setTopWallpaper(WindowState win, int index) {
+        void setTopWallpaper(WindowState win) {
             topWallpaper = win;
-            topWallpaperIndex = index;
         }
 
-        void setWallpaperTarget(WindowState win, int index) {
+        void setWallpaperTarget(WindowState win) {
             wallpaperTarget = win;
-            wallpaperTargetIndex = index;
+        }
+
+        void setUseTopWallpaperAsTarget(boolean topWallpaperAsTarget) {
+            useTopWallpaperAsTarget = topWallpaperAsTarget;
         }
 
         void reset() {
-            topWallpaperIndex = 0;
             topWallpaper = null;
-            wallpaperTargetIndex = 0;
             wallpaperTarget = null;
+            useTopWallpaperAsTarget = false;
+            resetTopWallpaper = false;
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 3a76cd4..8ea1b3b 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -119,11 +119,8 @@
         }
     }
 
-    boolean updateWallpaperWindowsPlacement(WindowList windowList,
-            WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
-            int wallpaperAnimLayerAdj) {
+    void updateWallpaperWindows(boolean visible, int animLayerAdj) {
 
-        boolean changed = false;
         if (hidden == visible) {
             if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
                     "Wallpaper token " + token + " hidden=" + !visible);
@@ -132,6 +129,9 @@
             mDisplayContent.setLayoutNeeded();
         }
 
+        final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
         final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
             final WindowState wallpaper = mChildren.get(wallpaperNdx);
@@ -142,66 +142,11 @@
 
             // First, make sure the client has the current visibility state.
             wallpaper.dispatchWallpaperVisibility(visible);
-            wallpaper.adjustAnimLayer(wallpaperAnimLayerAdj);
+            wallpaper.adjustAnimLayer(animLayerAdj);
 
             if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
                     + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
-
-            // First, if this window is at the current index, then all is well.
-            if (wallpaper == wallpaperTarget) {
-                wallpaperTargetIndex--;
-                wallpaperTarget = wallpaperTargetIndex > 0
-                        ? windowList.get(wallpaperTargetIndex - 1) : null;
-                continue;
-            }
-
-            // The window didn't match...  the current wallpaper window,
-            // wherever it is, is in the wrong place, so make sure it is not in the list.
-            int oldIndex = windowList.indexOf(wallpaper);
-            if (oldIndex >= 0) {
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
-                        "Wallpaper removing at " + oldIndex + ": " + wallpaper);
-                mDisplayContent.removeFromWindowList(wallpaper);
-                if (oldIndex < wallpaperTargetIndex) {
-                    wallpaperTargetIndex--;
-                }
-            }
-
-            // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
-            // layer. For keyguard over wallpaper put the wallpaper under the lowest window that
-            // is currently on screen, i.e. not hidden by policy.
-            int insertionIndex = 0;
-            if (visible && wallpaperTarget != null) {
-                final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
-                if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                    insertionIndex = Math.min(windowList.indexOf(wallpaperTarget),
-                            findLowestWindowOnScreen(windowList));
-                }
-            }
-            if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT
-                    || (DEBUG_ADD_REMOVE && oldIndex != insertionIndex)) Slog.v(TAG,
-                    "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + insertionIndex);
-
-            mDisplayContent.addToWindowList(wallpaper, insertionIndex);
-            changed = true;
         }
-
-        return changed;
-    }
-
-    /**
-     * @return The index in {@param windows} of the lowest window that is currently on screen and
-     *         not hidden by the policy.
-     */
-    private int findLowestWindowOnScreen(WindowList windowList) {
-        final int size = windowList.size();
-        for (int index = 0; index < size; index++) {
-            final WindowState win = windowList.get(index);
-            if (win.isOnScreen()) {
-                return index;
-            }
-        }
-        return Integer.MAX_VALUE;
     }
 
     boolean hasVisibleNotDrawnWallpaper() {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 150160c..a6a907c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -19,10 +19,12 @@
 import android.annotation.CallSuper;
 import android.content.res.Configuration;
 import android.view.animation.Animation;
+import com.android.internal.util.ToBooleanFunction;
 
 import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.function.Consumer;
+import java.util.function.Function;
 import java.util.function.Predicate;
 
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -496,17 +498,38 @@
         return addIndex;
     }
 
-    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+    /**
+     * For all windows at or below this container call the callback.
+     * @param   callback Calls the {@link ToBooleanFunction#apply} method for each window found and
+     *                   stops the search if {@link ToBooleanFunction#apply} returns true.
+     * @param   traverseTopToBottom If true traverses the hierarchy from top-to-bottom in terms of
+     *                              z-order, else from bottom-to-top.
+     * @return  True if the search ended before we reached the end of the hierarchy due to
+     *          {@link Function#apply} returning true.
+     */
+    boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         if (traverseTopToBottom) {
             for (int i = mChildren.size() - 1; i >= 0; --i) {
-                mChildren.get(i).forAllWindows(callback, traverseTopToBottom);
+                if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             }
         } else {
             final int count = mChildren.size();
             for (int i = 0; i < count; i++) {
-                mChildren.get(i).forAllWindows(callback, traverseTopToBottom);
+                if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             }
         }
+        return false;
+    }
+
+    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+        forAllWindows(w -> {
+            callback.accept(w);
+            return false;
+        }, traverseTopToBottom);
     }
 
     WindowState getWindow(Predicate<WindowState> callback) {
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index c06e5cc..32373f9 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -23,6 +23,7 @@
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -63,17 +64,19 @@
     private int mCurBaseLayer;
     private int mCurLayer;
     private boolean mAnyLayerChanged;
+    private int mHighestLayerInImeTargetBaseLayer;
+    private WindowState mImeTarget;
 
     final void assignWindowLayers(DisplayContent dc) {
         if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based",
                 new RuntimeException("here").fillInStackTrace());
 
-        clear();
+        reset();
         dc.forAllWindows((w) -> {
             boolean layerChanged = false;
 
             int oldLayer = w.mLayer;
-            if (w.mBaseLayer == mCurBaseLayer || w.mIsImWindow) {
+            if (w.mBaseLayer == mCurBaseLayer) {
                 mCurLayer += WINDOW_LAYER_MULTIPLIER;
             } else {
                 mCurBaseLayer = mCurLayer = w.mBaseLayer;
@@ -92,6 +95,11 @@
                 mHighestApplicationLayer = Math.max(mHighestApplicationLayer,
                         w.mWinAnimator.mAnimLayer);
             }
+            if (mImeTarget != null && w.mBaseLayer == mImeTarget.mBaseLayer) {
+                mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
+                        w.mWinAnimator.mAnimLayer);
+            }
+
             collectSpecialWindows(w);
 
             if (layerChanged) {
@@ -103,7 +111,7 @@
 
         //TODO (multidisplay): Magnification is supported only for the default display.
         if (mService.mAccessibilityController != null && mAnyLayerChanged
-                && dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                && dc.getDisplayId() == DEFAULT_DISPLAY) {
             mService.mAccessibilityController.onWindowLayersChangedLocked();
         }
 
@@ -120,7 +128,7 @@
         }, false /* traverseTopToBottom */);
     }
 
-    private void clear() {
+    private void reset() {
         mHighestApplicationLayer = 0;
         mPinnedWindows.clear();
         mInputMethodWindows.clear();
@@ -132,6 +140,9 @@
         mCurBaseLayer = 0;
         mCurLayer = 0;
         mAnyLayerChanged = false;
+
+        mImeTarget = mService.mInputMethodTarget;
+        mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
     }
 
     private void collectSpecialWindows(WindowState w) {
@@ -174,22 +185,10 @@
 
         layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
 
-        boolean onTopLauncherVisible = !mOnTopLauncherWindows.isEmpty();
         while (!mOnTopLauncherWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mOnTopLauncherWindows.remove(), layer);
         }
 
-        // Make sure IME windows are showing above the dock divider and on-top launcher windows.
-        if ((mDockDivider != null && mDockDivider.isVisibleLw()) || onTopLauncherVisible) {
-            while (!mInputMethodWindows.isEmpty()) {
-                final WindowState w = mInputMethodWindows.remove();
-                // Only ever move IME windows up, else we brake IME for windows above the divider.
-                if (layer > w.mLayer) {
-                    layer = assignAndIncreaseLayerIfNeeded(w, layer);
-                }
-            }
-        }
-
         // We know that we will be animating a relaunching window in the near future, which will
         // receive a z-order increase. We want the replaced window to immediately receive the same
         // treatment, e.g. to be above the dock divider.
@@ -200,12 +199,26 @@
         while (!mPinnedWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
         }
+
+        // Make sure IME is the highest window in the base layer of it's target.
+        if (mImeTarget != null) {
+            if (mImeTarget.mAppToken == null) {
+                // For non-app ime targets adjust the layer we start from to match what we found
+                // when assigning layers. Otherwise, just use the highest app layer we have some far.
+                layer = mHighestLayerInImeTargetBaseLayer + WINDOW_LAYER_MULTIPLIER;
+            }
+
+            while (!mInputMethodWindows.isEmpty()) {
+                layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer);
+            }
+        }
+
     }
 
     private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
         if (win != null) {
             assignAnimLayer(win, layer);
-            // Make sure we leave space inbetween normal windows for dims and such.
+            // Make sure we leave space in-between normal windows for dims and such.
             layer += WINDOW_LAYER_MULTIPLIER;
         }
         return layer;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c4c4bcd..00d8fba 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -23,7 +23,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.Notification;
@@ -1018,7 +1017,7 @@
         mBoundsAnimationController =
                 new BoundsAnimationController(mAppTransition, UiThread.getHandler());
 
-        mActivityManager = ActivityManagerNative.getDefault();
+        mActivityManager = ActivityManager.getService();
         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
         AppOpsManager.OnOpChangedInternalListener opListener =
@@ -4906,9 +4905,9 @@
             }
 
             if (rotateSeamlessly) {
-                dc.forAllWindows((w) ->
-                        w.mWinAnimator.seamlesslyRotateWindow(oldRotation, mRotation),
-                        true /* traverseTopToBottom */);
+                dc.forAllWindows(w -> {
+                        w.mWinAnimator.seamlesslyRotateWindow(oldRotation, mRotation);
+                }, true /* traverseTopToBottom */);
             }
 
             mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
@@ -4921,7 +4920,7 @@
             }
         }
 
-        dc.forAllWindows((w) -> {
+        dc.forAllWindows(w -> {
             // Discard surface after orientation change, these can't be reused.
             if (w.mAppToken != null) {
                 w.mAppToken.destroySavedSurfaces();
@@ -5184,7 +5183,9 @@
 
         final WindowList windows = new WindowList();
         synchronized (mWindowMap) {
-            mRoot.forAllWindows(windows::add, false /* traverseTopToBottom */);
+            mRoot.forAllWindows(w -> {
+                windows.add(w);
+            }, false /* traverseTopToBottom */);
         }
 
         BufferedWriter out = null;
@@ -5457,17 +5458,16 @@
         return config;
     }
 
-    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int uiMode,
-            int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
-        final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode);
+    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int displayId, int rotation,
+            int uiMode, int dw, int dh) {
+        final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode, displayId);
         if (width < displayInfo.smallestNominalAppWidth) {
             displayInfo.smallestNominalAppWidth = width;
         }
         if (width > displayInfo.largestNominalAppWidth) {
             displayInfo.largestNominalAppWidth = width;
         }
-        final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode);
+        final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode, displayId);
         if (height < displayInfo.smallestNominalAppHeight) {
             displayInfo.smallestNominalAppHeight = height;
         }
@@ -5477,11 +5477,10 @@
     }
 
     private int reduceConfigLayout(int curLayout, int rotation, float density,
-            int dw, int dh, int uiMode) {
-        // TODO: Multidisplay: for now only use with default display.
+            int dw, int dh, int uiMode, int displayId) {
         // Get the app screen size at this rotation.
-        int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode);
-        int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode);
+        int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId);
+        int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId);
 
         // Compute the screen layout size class for this rotation.
         int longSize = w;
@@ -5496,9 +5495,8 @@
         return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
     }
 
-    private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
-                  int uiMode, int dw, int dh, float density, Configuration outConfig) {
-        // TODO: Multidisplay: for now only use with default display.
+    private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, int displayId,
+            boolean rotated, int uiMode, int dw, int dh, float density, Configuration outConfig) {
 
         // We need to determine the smallest width that will occur under normal
         // operation.  To this, start with the base screen size and compute the
@@ -5516,24 +5514,33 @@
         displayInfo.smallestNominalAppHeight = 1<<30;
         displayInfo.largestNominalAppWidth = 0;
         displayInfo.largestNominalAppHeight = 0;
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, uiMode, unrotDw, unrotDh);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_0, uiMode, unrotDw,
+                unrotDh);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_90, uiMode, unrotDh,
+                unrotDw);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_180, uiMode, unrotDw,
+                unrotDh);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_270, uiMode, unrotDh,
+                unrotDw);
         int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
+                displayId);
         outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
         outConfig.screenLayout = sl;
     }
 
     private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
-            DisplayMetrics dm, int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
-        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode);
-        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode);
+            DisplayMetrics dm, int dw, int dh, int displayId) {
+        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
+                displayId);
+        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
+                displayId);
         float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
         int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
         if (curSize == 0 || size < curSize) {
@@ -5542,8 +5549,8 @@
         return curSize;
     }
 
-    private int computeCompatSmallestWidth(boolean rotated, int uiMode, DisplayMetrics dm, int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
+    private int computeCompatSmallestWidth(boolean rotated, int uiMode, DisplayMetrics dm, int dw,
+            int dh, int displayId) {
         mTmpDisplayMetrics.setTo(dm);
         final DisplayMetrics tmpDm = mTmpDisplayMetrics;
         final int unrotDw, unrotDh;
@@ -5554,10 +5561,14 @@
             unrotDw = dw;
             unrotDh = dh;
         }
-        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw);
+        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
+                displayId);
         return sw;
     }
 
@@ -5592,8 +5603,9 @@
         }
 
         // Update application display metrics.
-        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode);
-        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode);
+        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode, displayId);
+        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode,
+                displayId);
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         displayInfo.rotation = mRotation;
         displayInfo.logicalWidth = dw;
@@ -5632,15 +5644,15 @@
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
         config.screenWidthDp =
-                (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation, config.uiMode) /
+                (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation, config.uiMode, displayId) /
                         mDisplayMetrics.density);
         config.screenHeightDp =
-                (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation, config.uiMode) /
+                (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation, config.uiMode, displayId) /
                         mDisplayMetrics.density);
         final boolean rotated = (mRotation == Surface.ROTATION_90
                 || mRotation == Surface.ROTATION_270);
 
-        computeSizeRangesAndScreenLayout(displayInfo, rotated, config.uiMode, dw, dh,
+        computeSizeRangesAndScreenLayout(displayInfo, displayId, rotated, config.uiMode, dw, dh,
                 mDisplayMetrics.density, config);
 
         config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
@@ -5651,7 +5663,7 @@
         config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
         config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
         config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode,
-                mDisplayMetrics, dw, dh);
+                mDisplayMetrics, dw, dh, displayId);
         config.densityDpi = displayInfo.logicalDensityDpi;
 
         // Update the configuration based on available input devices, lid switch,
@@ -8261,7 +8273,7 @@
                     mRoot.dumpChildrenNames(output, " ");
                     pw.println(output.toString());
                     pw.println(" ");
-                    mRoot.forAllWindows(pw::println, true /* traverseTopToBottom */);
+                    mRoot.forAllWindows(w -> {pw.println(w);}, true /* traverseTopToBottom */);
                 }
                 return;
             } else {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5e65aec..661df9cd 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -53,6 +53,7 @@
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
 
+import com.android.internal.util.ToBooleanFunction;
 import com.android.server.input.InputWindowHandle;
 
 import java.io.PrintWriter;
@@ -60,6 +61,7 @@
 import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.function.Consumer;
+import java.util.function.Function;
 import java.util.function.Predicate;
 
 import static android.app.ActivityManager.StackId;
@@ -1355,7 +1357,7 @@
      * being visible.
      */
     boolean isOnScreen() {
-        if (!mHasSurface || mDestroying) {
+        if (!mHasSurface || mDestroying || !mPolicyVisibility) {
             return false;
         }
         final AppWindowToken atoken = mAppToken;
@@ -1903,9 +1905,7 @@
     }
 
     int getAnimLayerAdjustment() {
-        final boolean isImeType =
-                mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
-        if (isImeType && mService.mInputMethodTarget != null) {
+        if (mIsImWindow && mService.mInputMethodTarget != null) {
             final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
             if (appToken != null) {
                 return appToken.mAppAnimator.animLayerAdjustment;
@@ -3833,21 +3833,20 @@
     }
 
     @Override
-    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+    boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         if (mChildren.isEmpty()) {
             // The window has no children so we just return it.
-            callback.accept(this);
-            return;
+            return callback.apply(this);
         }
 
         if (traverseTopToBottom) {
-            forAllWindowTopToBottom(callback);
+            return forAllWindowTopToBottom(callback);
         } else {
-            forAllWindowBottomToTop(callback);
+            return forAllWindowBottomToTop(callback);
         }
     }
 
-    private void forAllWindowBottomToTop(Consumer<WindowState> callback) {
+    private boolean forAllWindowBottomToTop(ToBooleanFunction<WindowState> callback) {
         // We want to consumer the negative sublayer children first because they need to appear
         // below the parent, then this window (the parent), and then the positive sublayer children
         // because they need to appear above the parent.
@@ -3856,7 +3855,9 @@
         WindowState child = mChildren.get(i);
 
         while (i < count && child.mSubLayer < 0) {
-            callback.accept(child);
+            if (callback.apply(child)) {
+                return true;
+            }
             i++;
             if (i >= count) {
                 break;
@@ -3864,19 +3865,25 @@
             child = mChildren.get(i);
         }
 
-        callback.accept(this);
+        if (callback.apply(this)) {
+            return true;
+        }
 
         while (i < count) {
-            callback.accept(child);
+            if (callback.apply(child)) {
+                return true;
+            }
             i++;
             if (i >= count) {
                 break;
             }
             child = mChildren.get(i);
         }
+
+        return false;
     }
 
-    private void forAllWindowTopToBottom(Consumer<WindowState> callback) {
+    private boolean forAllWindowTopToBottom(ToBooleanFunction<WindowState> callback) {
         // We want to consumer the positive sublayer children first because they need to appear
         // above the parent, then this window (the parent), and then the negative sublayer children
         // because they need to appear above the parent.
@@ -3884,7 +3891,9 @@
         WindowState child = mChildren.get(i);
 
         while (i >= 0 && child.mSubLayer >= 0) {
-            callback.accept(child);
+            if (callback.apply(child)) {
+                return true;
+            }
             --i;
             if (i < 0) {
                 break;
@@ -3892,16 +3901,22 @@
             child = mChildren.get(i);
         }
 
-        callback.accept(this);
+        if (callback.apply(this)) {
+            return true;
+        }
 
         while (i >= 0) {
-            callback.accept(child);
+            if (callback.apply(child)) {
+                return true;
+            }
             --i;
             if (i < 0) {
                 break;
             }
             child = mChildren.get(i);
         }
+
+        return false;
     }
 
     WindowState getWindow(Predicate<WindowState> callback) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index f2682ba..7e1880f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -266,21 +266,9 @@
         mWallpaperControllerLocked.adjustWallpaperWindowsForAppTransitionIfNeeded(displayContent,
                 mService.mOpeningApps);
 
-        final WindowState lowerWallpaperTarget =
-                mWallpaperControllerLocked.getLowerWallpaperTarget();
-        final WindowState upperWallpaperTarget =
-                mWallpaperControllerLocked.getUpperWallpaperTarget();
-
+        final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
         boolean openingAppHasWallpaper = false;
         boolean closingAppHasWallpaper = false;
-        final AppWindowToken lowerWallpaperAppToken;
-        final AppWindowToken upperWallpaperAppToken;
-        if (lowerWallpaperTarget == null) {
-            lowerWallpaperAppToken = upperWallpaperAppToken = null;
-        } else {
-            lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
-            upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
-        }
 
         // Do a first pass through the tokens for two things:
         // (1) Determine if both the closing and opening app token sets are wallpaper targets, in
@@ -294,12 +282,12 @@
             final AppWindowToken wtoken;
             if (i < closingAppsCount) {
                 wtoken = mService.mClosingApps.valueAt(i);
-                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
                     closingAppHasWallpaper = true;
                 }
             } else {
                 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
-                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
+                if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
                     openingAppHasWallpaper = true;
                 }
             }
@@ -307,14 +295,14 @@
             voiceInteraction |= wtoken.voiceInteraction;
 
             if (wtoken.fillsParent()) {
-                WindowState ws = wtoken.findMainWindow();
+                final WindowState ws = wtoken.findMainWindow();
                 if (ws != null) {
                     animLp = ws.mAttrs;
                     bestAnimLayer = ws.mLayer;
                     fullscreenAnim = true;
                 }
             } else if (!fullscreenAnim) {
-                WindowState ws = wtoken.findMainWindow();
+                final WindowState ws = wtoken.findMainWindow();
                 if (ws != null) {
                     if (ws.mLayer > bestAnimLayer) {
                         animLp = ws.mAttrs;
@@ -325,7 +313,7 @@
         }
 
         transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
-                closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
+                closingAppHasWallpaper);
 
         // If all closing windows are obscured, then there is no need to do an animation. This is
         // the case, for example, when this transition is being done behind the lock screen.
@@ -578,8 +566,7 @@
     }
 
     private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
-            boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
-            WindowState upperWallpaperTarget) {
+            boolean closingAppHasWallpaper) {
         // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
         final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
         final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
@@ -590,8 +577,6 @@
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "New wallpaper target=" + wallpaperTarget
                         + ", oldWallpaper=" + oldWallpaper
-                        + ", lower target=" + lowerWallpaperTarget
-                        + ", upper target=" + upperWallpaperTarget
                         + ", openingApps=" + openingApps
                         + ", closingApps=" + closingApps);
         mService.mAnimateWallpaperWithTarget = false;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 402bcfb..a2eebc3 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -176,21 +176,6 @@
     }
 
     /**
-     * Recursive search through a WindowList and all of its windows' children.
-     * @param target The window to search for.
-     * @return The index of win in windows or of the window that is an ancestor of win.
-     */
-    int getWindowIndex(WindowState target) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState w = mChildren.get(i);
-            if (w == target || w.hasChild(target)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
      * Returns true if the new window is considered greater than the existing window in terms of
      * z-order.
      */
diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
index 640fd0e..2f20ecd 100644
--- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
+++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
@@ -30,7 +30,7 @@
 static jclass appFuseClass;
 static jmethodID appFuseOnMount;
 
-class Callback : public FuseBridgeLoop::Callback {
+class Callback : public fuse::FuseBridgeLoopCallback {
     JNIEnv* mEnv;
     jobject mSelf;
 
@@ -47,9 +47,8 @@
 
 jboolean com_android_server_storage_AppFuseBridge_start_loop(
         JNIEnv* env, jobject self, jint devJavaFd, jint proxyJavaFd) {
-    FuseBridgeLoop loop;
     Callback callback(env, self);
-    return loop.Start(devJavaFd, proxyJavaFd, &callback);
+    return fuse::StartFuseBridgeLoop(devJavaFd, proxyJavaFd, &callback);
 }
 
 const JNINativeMethod methods[] = {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7e68447..883d2d8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -38,7 +38,6 @@
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -1460,7 +1459,7 @@
         }
 
         IActivityManager getIActivityManager() {
-            return ActivityManagerNative.getDefault();
+            return ActivityManager.getService();
         }
 
         IPackageManager getIPackageManager() {
@@ -5524,7 +5523,7 @@
 
         final long callingIdentity = mInjector.binderClearCallingIdentity();
         try {
-            ActivityManagerNative.getDefault().requestBugReport(
+            ActivityManager.getService().requestBugReport(
                     ActivityManager.BUGREPORT_OPTION_REMOTE);
 
             mRemoteBugreportServiceIsActive.set(true);
@@ -6042,6 +6041,7 @@
     }
 
     private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) {
+        disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
         if (admin != null) {
             admin.disableCamera = false;
             admin.userRestrictions = null;
@@ -6053,7 +6053,6 @@
         mOwners.clearDeviceOwner();
         mOwners.writeDeviceOwner();
         updateDeviceOwnerLocked();
-        disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
         try {
             if (mInjector.getIBackupManager() != null) {
                 // Reactivate backup service.
@@ -8700,9 +8699,11 @@
                 // Managed user cannot have a managed profile.
                 return false;
             }
+            boolean canRemoveProfile
+                    = !mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
             final long ident = mInjector.binderClearCallingIdentity();
             try {
-                if (!mUserManager.canAddMoreManagedProfiles(callingUserId, true)) {
+                if (!mUserManager.canAddMoreManagedProfiles(callingUserId, canRemoveProfile)) {
                     return false;
                 }
             } finally {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3db24fa..ba23f21 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -42,7 +42,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -52,6 +52,7 @@
 
 import com.android.internal.R;
 import com.android.internal.app.NightDisplayController;
+import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 import com.android.internal.os.ZygoteInit;
@@ -167,8 +168,8 @@
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
             "com.android.server.LockSettingsService$Lifecycle";
-    private static final String MOUNT_SERVICE_CLASS =
-            "com.android.server.MountService$Lifecycle";
+    private static final String STORAGE_MANAGER_SERVICE_CLASS =
+            "com.android.server.StorageManagerService$Lifecycle";
     private static final String SEARCH_MANAGER_SERVICE_CLASS =
             "com.android.server.search.SearchManagerService$Lifecycle";
     private static final String THERMAL_OBSERVER_CLASS =
@@ -275,7 +276,9 @@
 
             // Here we go!
             Slog.i(TAG, "Entered the Android system server!");
-            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
+            int uptimeMillis = (int) SystemClock.uptimeMillis();
+            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
+            MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
 
             // In case the runtime switched since last boot (such as when
             // the old runtime was removed in an OTA), set the system
@@ -364,6 +367,7 @@
         if (StrictMode.conditionallyEnableDebugLogging()) {
             Slog.i(TAG, "Enabled StrictMode for system server main thread.");
         }
+        MetricsLogger.histogram(null, "boot_system_server_ready", (int) SystemClock.uptimeMillis());
 
         // Loop forever.
         Looper.loop();
@@ -492,13 +496,16 @@
         }
 
         // Start the package manager.
+        MetricsLogger.histogram(null, "boot_package_manager_init_start",
+                (int) SystemClock.uptimeMillis());
         traceBeginAndSlog("StartPackageManagerService");
         mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
         mFirstBoot = mPackageManagerService.isFirstBoot();
         mPackageManager = mSystemContext.getPackageManager();
         traceEnd();
-
+        MetricsLogger.histogram(null, "boot_package_manager_init_ready",
+                (int) SystemClock.uptimeMillis());
         // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
         // A/B artifacts after boot, before anything else might touch/need them.
         // Note: this isn't needed during decryption (we don't have /data anyways).
@@ -572,7 +579,7 @@
     private void startOtherServices() {
         final Context context = mSystemContext;
         VibratorService vibrator = null;
-        IMountService mountService = null;
+        IStorageManager storageManager = null;
         NetworkManagementService networkManagement = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
@@ -784,17 +791,17 @@
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
             if (!disableStorage &&
                 !"0".equals(SystemProperties.get("system_init.startmountservice"))) {
-                traceBeginAndSlog("StartMountService");
+                traceBeginAndSlog("StartStorageManagerService");
                 try {
                     /*
-                     * NotificationManagerService is dependant on MountService,
-                     * (for media / usb notifications) so we must start MountService first.
+                     * NotificationManagerService is dependant on StorageManagerService,
+                     * (for media / usb notifications) so we must start StorageManagerService first.
                      */
-                    mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
-                    mountService = IMountService.Stub.asInterface(
+                    mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
+                    storageManager = IStorageManager.Stub.asInterface(
                             ServiceManager.getService("mount"));
                 } catch (Throwable e) {
-                    reportWtf("starting Mount Service", e);
+                    reportWtf("starting StorageManager Service", e);
                 }
                 traceEnd();
             }
@@ -993,14 +1000,14 @@
             }
 
             /*
-             * MountService has a few dependencies: Notification Manager and
-             * AppWidget Provider. Make sure MountService is completely started
+             * StorageManagerService has a few dependencies: Notification Manager and
+             * AppWidget Provider. Make sure StorageManagerService is completely started
              * first before continuing.
              */
-            if (mountService != null && !mOnlyCore) {
+            if (storageManager != null && !mOnlyCore) {
                 traceBeginAndSlog("WaitForAsecScan");
                 try {
-                    mountService.waitForAsecScan();
+                    storageManager.waitForAsecScan();
                 } catch (RemoteException ignored) {
                 }
                 traceEnd();
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 6558b6e..d7666d9 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -22,7 +22,6 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -915,7 +914,7 @@
 
         private int resolveCallingUserEnforcingPermissions(int userId) {
             try {
-                return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+                return ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(),
                         Binder.getCallingUid(), userId, true, true, "", null);
             } catch (RemoteException re) {
                 // Shouldn't happen, local.
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index 7c7c299..785c3fa 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -17,8 +17,8 @@
 package com.android.server.retaildemo;
 
 import android.Manifest;
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -591,7 +591,7 @@
 
         void switchUser(int userId) {
             if (mAms == null) {
-                mAms = (ActivityManagerService) ActivityManagerNative.getDefault();
+                mAms = (ActivityManagerService) ActivityManager.getService();
             }
             mAms.switchUser(userId);
         }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index bd9e6d1..ba25b16 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -32,7 +31,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        service = ActivityManagerNative.getDefault();
+        service = ActivityManager.getService();
     }
 
     public void testTaskIdsForRunningUsers() throws RemoteException {
@@ -52,4 +51,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index c9c691d..0359096 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -22,8 +22,8 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.ITaskStackListener;
 import android.app.Instrumentation.ActivityMonitor;
@@ -63,7 +63,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mService = ActivityManagerNative.getDefault();
+        mService = ActivityManager.getService();
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 56ff621..71379b8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2178,6 +2178,26 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
     }
 
+    public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
+            throws Exception {
+        setDeviceOwner();
+
+        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+                .thenReturn(true);
+        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(mContext.userManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER))
+                .thenReturn(true);
+        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+                false /* we can't remove a managed profile*/)).thenReturn(false);
+        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+                true)).thenReturn(true);
+        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
+
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+
+        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
+    }
+
     public void testForceUpdateUserSetupComplete_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
         try {
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 772b2a2..207939f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -45,16 +45,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class AppWindowTokenTests {
-
-    private static WindowManagerService sWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
-    }
+public class AppWindowTokenTests extends WindowTestsBase {
 
     @Test
     public void testAddWindow_Order() throws Exception {
@@ -62,10 +53,11 @@
 
         assertEquals(0, token.getWindowsCount());
 
-        final WindowState win1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token);
-        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token);
-        final WindowState win4 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, token, "win1");
+        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token,
+                "startingWin");
+        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token, "baseWin");
+        final WindowState win4 = createWindow(null, TYPE_APPLICATION, token, "win4");
 
         token.addWindow(win1);
         token.addWindow(startingWin);
@@ -92,24 +84,18 @@
 
         assertNull(token.findMainWindow());
 
-        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
+        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
         token.addWindow(window1);
         assertEquals(window1, token.findMainWindow());
         window1.mAnimatingExit = true;
         assertEquals(window1, token.findMainWindow());
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token);
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token, "window2");
         token.addWindow(window2);
         assertEquals(window2, token.findMainWindow());
     }
 
-    private WindowState createWindow(WindowState parent, int type, WindowToken token) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(sWm, null, mIWindow, token, parent, 0, 0, attrs, 0, 0);
-    }
-
     /* Used so we can gain access to some protected members of the {@link AppWindowToken} class */
     private class TestAppWindowToken extends AppWindowToken {
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 0533efc..0801a88 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,28 +16,15 @@
 
 package com.android.server.wm;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.WindowManager;
 
 import java.util.ArrayList;
 
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.AppOpsManager.OP_NONE;
-import static android.content.res.Configuration.EMPTY;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -47,7 +34,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
 
 /**
  * Tests for the {@link DisplayContent} class.
@@ -58,21 +44,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class DisplayContentTests {
-
-    private static WindowManagerService sWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-    private final Session mMockSession = mock(Session.class);
-    private Display mDisplay;
-    private int mNextStackId = FIRST_DYNAMIC_STACK_ID;
-    private int mNextTaskId = 0;
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
-        mDisplay = context.getDisplay();
-    }
+public class DisplayContentTests extends WindowTestsBase {
 
     @Test
     public void testForAllWindows() throws Exception {
@@ -98,7 +70,7 @@
         final ArrayList<WindowState> windows = new ArrayList();
 
         // Test forward traversal.
-        dc.forAllWindows(windows::add, false /* traverseTopToBottom */);
+        dc.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
 
         assertEquals(wallpaperWindow, windows.get(0));
         assertEquals(exitingAppWindow, windows.get(1));
@@ -112,7 +84,7 @@
 
         // Test backward traversal.
         windows.clear();
-        dc.forAllWindows(windows::add, true /* traverseTopToBottom */);
+        dc.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
 
         assertEquals(wallpaperWindow, windows.get(8));
         assertEquals(exitingAppWindow, windows.get(7));
@@ -124,36 +96,4 @@
         assertEquals(imeWindow, windows.get(1));
         assertEquals(imeDialogWindow, windows.get(0));
     }
-
-    private WindowToken createWindowToken(DisplayContent dc, int type) {
-        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
-            return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
-        }
-
-        final int stackId = mNextStackId++;
-        dc.addStackToDisplay(stackId, true);
-        final TaskStack stack = sWm.mStackIdToStack.get(stackId);
-        final Task task = new Task(mNextTaskId++, stack, 0, sWm, null, EMPTY, false);
-        stack.addTask(task, true);
-        final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
-        task.addAppToken(0, token, 0, false);
-        return token;
-    }
-
-    private WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
-        final WindowToken token = createWindowToken(dc, type);
-        return createWindow(parent, type, token, name);
-    }
-
-    private WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-        attrs.setTitle(name);
-
-        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0);
-        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
-        // adding it to the token...
-        token.addWindow(w);
-        return w;
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 38a98b2..ed4c79f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -272,22 +272,26 @@
     }
 
     @Override
-    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
new file mode 100644
index 0000000..5a035d6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
@@ -0,0 +1,149 @@
+/*
+ * 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.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+/**
+ * Tests for the {@link WindowLayersController} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowLayersControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowLayersControllerTests extends WindowTestsBase {
+
+    private static boolean sOneTimeSetupDone = false;
+    private static WindowLayersController sLayersController;
+    private static DisplayContent sDisplayContent;
+    private static WindowState sImeWindow;
+    private static WindowState sImeDialogWindow;
+    private static WindowState sStatusBarWindow;
+    private static WindowState sDockedDividerWindow;
+    private static WindowState sNavBarWindow;
+    private static WindowState sAppWindow;
+    private static WindowState sChildAppWindow;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        if (sOneTimeSetupDone) {
+            return;
+        }
+        sOneTimeSetupDone = true;
+        sLayersController = new WindowLayersController(sWm);
+        sDisplayContent =
+                new DisplayContent(mDisplay, sWm, sLayersController, new WallpaperController(sWm));
+        final WindowState wallpaperWindow =
+                createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
+        sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
+        sImeDialogWindow =
+                createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
+        sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
+        sNavBarWindow =
+                createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow");
+        sDockedDividerWindow =
+                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
+        sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
+        sChildAppWindow = createWindow(sAppWindow,
+                TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindow");
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
+        sWm.mInputMethodTarget = null;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // The Ime has an higher base layer than app windows and lower base layer than system
+        // windows, so it should be above app windows and below system windows if there isn't an IME
+        // target.
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
+        final WindowState imeAppTarget =
+                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+        sWm.mInputMethodTarget = imeAppTarget;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // Ime should be above all app windows and below system windows if it is targeting an app
+        // window.
+        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
+        final WindowState imeSystemOverlayTarget =
+                createWindow(null, TYPE_SYSTEM_OVERLAY, sDisplayContent, "imeSystemOverlayTarget");
+
+        sWm.mInputMethodTarget = imeSystemOverlayTarget;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // The IME target base layer is higher than all window except for the nav bar window, so the
+        // IME should be above all windows except for the nav bar.
+        assertWindowLayerGreaterThan(sImeWindow, imeSystemOverlayTarget);
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sStatusBarWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    private void assertWindowLayerGreaterThan(WindowState first, WindowState second)
+            throws Exception {
+        assertGreaterThan(first.mWinAnimator.mAnimLayer, second.mWinAnimator.mAnimLayer);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 3df1df9..50e5a22 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -41,32 +41,30 @@
 /**
  * Tests for the {@link WindowState} class.
  *
- * Build: mmma -j32 frameworks/base/services/tests/servicestests
- * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -w -e class com.android.server.wm.WindowStateTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * runtest frameworks-services -c com.android.server.wm.WindowStateTests
  */
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class WindowStateTests {
+public class WindowStateTests extends WindowTestsBase {
 
-    private static WindowManagerService sWm = null;
     private WindowToken mWindowToken;
-    private final IWindow mIWindow = new TestIWindow();
 
     @Before
     public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        super.setUp();
         mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
                 sWm.getDefaultDisplayContentLocked());
     }
 
     @Test
     public void testIsParentWindowHidden() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertFalse(parentWindow.mHidden);
         assertFalse(parentWindow.isParentWindowHidden());
@@ -81,10 +79,14 @@
 
     @Test
     public void testIsChildWindow() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
+        final WindowState randomWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow");
 
         assertFalse(parentWindow.isChildWindow());
         assertTrue(child1.isChildWindow());
@@ -94,12 +96,13 @@
 
     @Test
     public void testHasChild() throws Exception {
-        final WindowState win1 = createWindow(null, TYPE_APPLICATION);
-        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW);
-        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW);
-        final WindowState win2 = createWindow(null, TYPE_APPLICATION);
-        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW);
-        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win1");
+        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win11");
+        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win12");
+        final WindowState win2 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win2");
+        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, mWindowToken, "win21");
+        final WindowState randomWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow");
 
         assertTrue(win1.hasChild(win11));
         assertTrue(win1.hasChild(win12));
@@ -115,23 +118,28 @@
 
     @Test
     public void testGetBottomChild() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
         assertNull(parentWindow.getBottomChild());
 
-        final WindowState child1 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
+        final WindowState child1 =
+                createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child1");
         assertEquals(child1, parentWindow.getBottomChild());
 
-        final WindowState child2 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
+        final WindowState child2 =
+                createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child2");
         // Since child1 and child2 are at the same layer, then child2 is expect to be added on top
         // on child1
         assertEquals(child1, parentWindow.getBottomChild());
 
-        final WindowState child3 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
+        final WindowState child3 =
+                createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child3");
         // Since child3 is a negative layer, we would expect it to be added below current children
         // with positive layers.
         assertEquals(child3, parentWindow.getBottomChild());
 
-        final WindowState child4 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
+        final WindowState child4 =
+                createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child4");
         // We would also expect additional negative layers to be added below existing negative
         // layers.
         assertEquals(child4, parentWindow.getBottomChild());
@@ -139,9 +147,12 @@
 
     @Test
     public void testGetParentWindow() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertNull(parentWindow.getParentWindow());
         assertEquals(parentWindow, child1.getParentWindow());
@@ -150,9 +161,9 @@
 
     @Test
     public void testGetTopParentWindow() throws Exception {
-        final WindowState root = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW);
+        final WindowState root = createWindow(null, TYPE_APPLICATION, mWindowToken, "root");
+        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertEquals(root, root.getTopParentWindow());
         assertEquals(root, child1.getTopParentWindow());
@@ -160,9 +171,12 @@
         assertEquals(root, child2.getTopParentWindow());
     }
 
-    private WindowState createWindow(WindowState parent, int type) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(sWm, null, mIWindow, mWindowToken, parent, 0, 0, attrs, 0, 0);
+    @Test
+    public void testIsOnScreen_hiddenByPolicy() {
+        final WindowState window = createWindow(null, TYPE_APPLICATION, mWindowToken, "window");
+        window.setHasSurface(true);
+        assertTrue(window.isOnScreen());
+        window.hideLw(false /* doAnimation */);
+        assertFalse(window.isOnScreen());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
new file mode 100644
index 0000000..9681bd2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -0,0 +1,90 @@
+/*
+ * 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.wm;
+
+import org.junit.Assert;
+import org.junit.Before;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.support.test.InstrumentationRegistry;
+import android.view.Display;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.res.Configuration.EMPTY;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Common base class for window manager unit test classes.
+ */
+public class WindowTestsBase {
+    static WindowManagerService sWm = null;
+    private final IWindow mIWindow = new TestIWindow();
+    private final Session mMockSession = mock(Session.class);
+    Display mDisplay;
+    private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
+    private static int sNextTaskId = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        mDisplay = context.getDisplay();
+    }
+
+    /** Asserts that the first entry is greater than the second entry. */
+    void assertGreaterThan(int first, int second) throws Exception {
+        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
+    }
+
+    WindowToken createWindowToken(DisplayContent dc, int type) {
+        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
+            return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
+        }
+
+        final int stackId = sNextStackId++;
+        dc.addStackToDisplay(stackId, true);
+        final TaskStack stack = sWm.mStackIdToStack.get(stackId);
+        final Task task = new Task(sNextTaskId++, stack, 0, sWm, null, EMPTY, false);
+        stack.addTask(task, true);
+        final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
+        task.addAppToken(0, token, 0, false);
+        return token;
+    }
+
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
+        final WindowToken token = createWindowToken(dc, type);
+        return createWindow(parent, type, token, name);
+    }
+
+    WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
+        attrs.setTitle(name);
+
+        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
+                0, attrs, 0, 0);
+        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
+        // adding it to the token...
+        token.addWindow(w);
+        return w;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index d12d672a..d6bfa17 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -47,17 +47,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class WindowTokenTests {
-
-    private WindowManagerService mWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-    private final Session mMockSession = mock(Session.class);
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mWm = TestWindowManagerPolicy.getWindowManagerService(context);
-    }
+public class WindowTokenTests extends WindowTestsBase {
 
     @Test
     public void testAddWindow() throws Exception {
@@ -65,11 +55,11 @@
 
         assertEquals(0, token.getWindowsCount());
 
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
 
         token.addWindow(window1);
         // NOTE: Child windows will not be added to the token as window containers can only
@@ -91,12 +81,12 @@
     @Test
     public void testChildRemoval() throws Exception {
         final TestWindowToken token = new TestWindowToken();
-        final DisplayContent dc = mWm.getDefaultDisplayContentLocked();
+        final DisplayContent dc = sWm.getDefaultDisplayContentLocked();
 
         assertEquals(token, dc.getWindowToken(token.token));
 
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
         token.addWindow(window1);
         token.addWindow(window2);
 
@@ -113,11 +103,11 @@
     @Test
     public void testAdjustAnimLayer() throws Exception {
         final TestWindowToken token = new TestWindowToken();
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
 
         token.addWindow(window1);
         token.addWindow(window2);
@@ -136,60 +126,11 @@
         assertEquals(window3StartLayer + adj, highestLayer);
     }
 
-    @Test
-    public void testGetTopWindow() throws Exception {
-        final TestWindowToken token = new TestWindowToken();
-
-        assertNull(token.getTopWindow());
-
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        token.addWindow(window1);
-        assertEquals(window1, token.getTopWindow());
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        assertEquals(window12, token.getTopWindow());
-
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        token.addWindow(window2);
-        // Since new windows are added to the bottom of the token, we would still expect the
-        // previous one to the top.
-        assertEquals(window12, token.getTopWindow());
-    }
-
-    @Test
-    public void testGetWindowIndex() throws Exception {
-        final TestWindowToken token = new TestWindowToken();
-
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        assertEquals(-1, token.getWindowIndex(window1));
-        token.addWindow(window1);
-        assertEquals(0, token.getWindowIndex(window1));
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        // Child windows should report the same index as their parents.
-        assertEquals(0, token.getWindowIndex(window11));
-        assertEquals(0, token.getWindowIndex(window12));
-
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        assertEquals(-1, token.getWindowIndex(window2));
-        token.addWindow(window2);
-        // Since new windows are added to the bottom of the token, we would expect the added window
-        // to be at index 0.
-        assertEquals(0, token.getWindowIndex(window2));
-        assertEquals(1, token.getWindowIndex(window1));
-    }
-
-    private WindowState createWindow(WindowState parent, int type, WindowToken token) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(mWm, mMockSession, mIWindow, token, parent, OP_NONE, 0, attrs, 0, 0);
-    }
-
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
     private class TestWindowToken extends WindowToken {
 
         TestWindowToken() {
-            super(mWm, mock(IBinder.class), 0, false, mWm.getDefaultDisplayContentLocked());
+            super(sWm, mock(IBinder.class), 0, false, sWm.getDefaultDisplayContentLocked());
         }
 
         int getWindowsCount() {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 04104b5..7217c3b 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -17,7 +17,7 @@
 package com.android.server.usage;
 
 import android.Manifest;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
@@ -462,7 +462,7 @@
 
         final int[] runningUserIds;
         try {
-            runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds();
+            runningUserIds = ActivityManager.getService().getRunningUserIds();
             if (checkUserId != UserHandle.USER_ALL
                     && !ArrayUtils.contains(runningUserIds, checkUserId)) {
                 return false;
@@ -1311,7 +1311,7 @@
         @Override
         public boolean isAppInactive(String packageName, int userId) {
             try {
-                userId = ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+                userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(),
                         Binder.getCallingUid(), userId, false, true, "isAppInactive", null);
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
@@ -1329,7 +1329,7 @@
         public void setAppInactive(String packageName, boolean idle, int userId) {
             final int callingUid = Binder.getCallingUid();
             try {
-                userId = ActivityManagerNative.getDefault().handleIncomingUser(
+                userId = ActivityManager.getService().handleIncomingUser(
                         Binder.getCallingPid(), callingUid, userId, false, true,
                         "setAppIdle", null);
             } catch (RemoteException re) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 3daa87c..0544fae 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -362,11 +362,6 @@
                             UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP));
                 }
 
-                String buildType = SystemProperties.get(BUILD_TYPE_PROPERTY);
-                if (buildType.equals(BUILD_TYPE_USERDEBUG) || buildType.equals(BUILD_TYPE_ENG)) {
-                    setAdbEnabled(true);
-                }
-
                 setEnabledFunctions(null, false, false);
 
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
@@ -483,7 +478,7 @@
                 SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction);
 
                 // Remove mtp from the config if file transfer is not enabled
-                if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) && 
+                if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) &&
                         !mUsbDataUnlocked && enable) {
                     oldFunctions = UsbManager.USB_FUNCTION_NONE;
                 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index a46ccee..4357dca 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -117,7 +116,7 @@
         mServiceStub = stub;
         mUser = userHandle;
         mComponent = service;
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         VoiceInteractionServiceInfo info;
         try {
             info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 7dacf16..4267ec4 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -17,7 +17,6 @@
 package com.android.server.voiceinteraction;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.assist.AssistContent;
@@ -182,7 +181,7 @@
         mCallback = callback;
         mCallingUid = callingUid;
         mHandler = handler;
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         mAppOps = context.getSystemService(AppOpsManager.class);
diff --git a/telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl b/telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl
index 5b71149..2ae424f 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl
+++ b/telephony/java/com/android/ims/internal/uce/presence/IPresenceListener.aidl
@@ -89,4 +89,11 @@
      */
     void listCapInfoReceived(in PresRlmiInfo rlmiInfo,
                              in PresResInfo [] resInfo);
+
+    /**
+     * Callback function to be invoked to inform the client when Unpublish message
+     * is sent to network.
+     */
+    void unpublishMessageSent();
+
 }
\ No newline at end of file
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index f5f7ea3..0aa20ef 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -19,7 +19,6 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.app.ActivityManagerNative;
 import android.app.ActivityManager;
 import android.app.ActivityManager.ProcessErrorStateInfo;
 import android.content.Context;
@@ -144,7 +143,7 @@
         InstrumentationTestRunner instrumentation =
                 (InstrumentationTestRunner)getInstrumentation();
         Bundle args = instrumentation.getArguments();
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         String launchDirectory = args.getString(KEY_LAUNCH_DIRECTORY);
         mTraceDirectoryStr = args.getString(KEY_TRACE_DIRECTORY);
         mDropCache = Boolean.parseBoolean(args.getString(KEY_DROP_CACHE));
diff --git a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
index b659135..7a4fddf 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
@@ -17,7 +17,6 @@
 package com.android.imftest.samples;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.provider.MediaStore;
diff --git a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
index a7e3bec..1ae318a 100644
--- a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
+++ b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
@@ -18,7 +18,6 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.ProcessErrorStateInfo;
 import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
 import android.content.Context;
@@ -84,7 +83,7 @@
         MemoryUsageInstrumentation instrumentation =
                 (MemoryUsageInstrumentation) getInstrumentation();
         Bundle args = instrumentation.getBundle();
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
 
         createMappings();
         parseArgs(args);
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index d7f4a38..89bd8d8 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -16,7 +16,7 @@
 
 package com.android.framework.permission.tests;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.res.Configuration;
 import android.os.RemoteException;
@@ -33,7 +33,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
     }
 
     @SmallTest
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
index eb52b64..819103d 100644
--- a/tools/layoutlib/.gitignore
+++ b/tools/layoutlib/.gitignore
@@ -1,3 +1,4 @@
 bin
 /.idea/workspace.xml
 /out
+/bridge/out
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
index 57d08cb..fbaed52 100644
--- a/tools/layoutlib/bridge/bridge.iml
+++ b/tools/layoutlib/bridge/bridge.iml
@@ -7,6 +7,7 @@
       <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
       <excludeFolder url="file://$MODULE_DIR$/.settings" />
       <excludeFolder url="file://$MODULE_DIR$/bin" />
       <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
diff --git a/tools/layoutlib/bridge/tests/res/empty.xml b/tools/layoutlib/bridge/tests/res/empty.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/empty.xml
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
index 4561e1b..4781660 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
@@ -19,12 +19,12 @@
 apply plugin: 'com.android.application'
 
 android {
-    compileSdkVersion 22
-    buildToolsVersion '21.1.2'
+    compileSdkVersion 25
+    buildToolsVersion '25.0.0'
     defaultConfig {
         applicationId 'com.android.layoutlib.test.myapplication'
         minSdkVersion 21
-        targetSdkVersion 22
+        targetSdkVersion 25
         versionCode 1
         versionName '1.0'
     }
@@ -34,6 +34,9 @@
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+    lintOptions {
+        abortOnError false
+    }
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_6
         targetCompatibility JavaVersion.VERSION_1_6
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
index e0373cb..f73528a 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomCalendar.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomCalendar.class
deleted file mode 100644
index c363055..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomCalendar.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomDate.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomDate.class
deleted file mode 100644
index edda3de..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/CustomDate.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
index ec42017..5bb04fc 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
new file mode 100644
index 0000000..ff699d1
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
index 0e208f2..a3931b8 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
index 2b77af3..e293677 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
index fd01b44..d6268bf 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
index 91cf5b6..08b98fb 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
index 6c351da..f9be1ca 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
index aecbff6..6874b49 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
index fc3f236..a4205a8 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
index 83ad35b..4fb3b61 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
index 6d7c719..dba67fd 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
index 7b58539..f274dbf 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
index 41d75de..e7f22bf 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
@@ -1,3 +1,19 @@
+/*
+ * 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.layoutlib.test.myapplication;
 
 import android.content.Context;
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomCalendar.java
deleted file mode 100644
index 5c53af9..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomCalendar.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CalendarView;
-
-public class CustomCalendar extends CalendarView {
-    public CustomCalendar(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        setDate(871732800000L, false, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java
deleted file mode 100644
index cb750f4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.DatePicker;
-
-public class CustomDate extends DatePicker {
-    public CustomDate(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        init(2015, 0, 20, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
new file mode 100644
index 0000000..3b819e5
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
@@ -0,0 +1,47 @@
+/*
+ * 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.layoutlib.test.myapplication.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CalendarView;
+
+public class CustomCalendar extends CalendarView {
+    public CustomCalendar(Context context) {
+        super(context);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        setDate(871732800000L, false, true);
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
new file mode 100644
index 0000000..f3877f1
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
@@ -0,0 +1,47 @@
+/*
+ * 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.layoutlib.test.myapplication.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.DatePicker;
+
+public class CustomDate extends DatePicker {
+    public CustomDate(Context context) {
+        super(context);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        init(2015, 0, 20, null);
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
new file mode 100644
index 0000000..58ad46d
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * This package contains custom widgets used to set a specific time for the DayTimePicker during
+ * testing.
+ * The classes here are both used from the Android project and from the Bridge test project.
+ */
+package com.android.layoutlib.test.myapplication.widgets;
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
index 50646ab..e9aa9e1 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<com.android.layoutlib.test.myapplication.ArraysCheckWidget xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.layoutlib.test.myapplication.ArraysCheckWidget
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical" android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml
deleted file mode 100644
index 5322411..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
-  ~ 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.
-  -->
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
index c1f663e..ff14ce0 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
@@ -15,10 +15,10 @@
         android:checked="true"
         android:layout_gravity="center"
         />
-    <com.android.layoutlib.test.myapplication.CustomDate
+    <com.android.layoutlib.test.myapplication.widgets.CustomDate
         android:layout_width="100dp"
         android:layout_height="wrap_content"/>
-    <com.android.layoutlib.test.myapplication.CustomCalendar
+    <com.android.layoutlib.test.myapplication.widgets.CustomCalendar
         android:layout_width="200dp"
         android:layout_gravity="center_horizontal"
         android:layout_height="200dp"/>
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 55cfd6d..5423e87 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -39,6 +39,7 @@
 import com.android.resources.Density;
 import com.android.resources.Navigation;
 import com.android.resources.ResourceType;
+import com.android.tools.layoutlib.java.System_Delegate;
 import com.android.utils.ILogger;
 
 import org.junit.AfterClass;
@@ -51,6 +52,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.PackageInstaller.Session;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -58,11 +60,28 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.CopyOption;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 import com.google.android.collect.Lists;
 
@@ -105,6 +124,8 @@
     private static final String APP_TEST_DIR = "/testApp/MyApplication";
     /** Location of the app's res dir inside {@link #TEST_RES_DIR}*/
     private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
+    private static final String APP_CLASSES_LOCATION =
+            APP_TEST_DIR + "/build/intermediates/classes/debug/";
 
     private static LayoutLog sLayoutLibLog;
     private static FrameworkResources sFrameworkRepo;
@@ -115,6 +136,11 @@
     /** List of log messages generated by a render call. It can be used to find specific errors */
     private static ArrayList<String> sRenderMessages = Lists.newArrayList();
 
+    // Default class loader with access to the app classes
+    private ClassLoader mDefaultClassLoader =
+            new URLClassLoader(new URL[]{this.getClass().getResource(APP_CLASSES_LOCATION)},
+                    getClass().getClassLoader());
+
     @Rule
     public TestWatcher sRenderMessageWatcher = new TestWatcher() {
         @Override
@@ -192,6 +218,7 @@
         }
         File[] hosts = host.listFiles(path -> path.isDirectory() &&
                 (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
+        assert hosts != null;
         for (File hostOut : hosts) {
             String platformDir = getPlatformDirFromHostOut(hostOut);
             if (platformDir != null) {
@@ -213,6 +240,7 @@
             // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
             return path.isDirectory() && path.getName().startsWith("sdk");
         });
+        assert sdkDirs != null;
         for (File dir : sdkDirs) {
             String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
             if (platformDir != null) {
@@ -225,6 +253,7 @@
     private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
         File[] possibleSdks = sdkDir.listFiles(
                 path -> path.isDirectory() && path.getName().contains("android-sdk"));
+        assert possibleSdks != null;
         for (File possibleSdk : possibleSdks) {
             File platformsDir = new File(possibleSdk, "platforms");
             File[] platforms = platformsDir.listFiles(
@@ -312,10 +341,48 @@
         renderAndVerify("activity.xml", "activity.png");
     }
 
+    private static void gc() {
+        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
+        Object obj = new Object();
+        WeakReference ref = new WeakReference<>(obj);
+        //noinspection UnusedAssignment
+        obj = null;
+        while(ref.get() != null) {
+            System.gc();
+            System.runFinalization();
+        }
+
+        System.gc();
+        System.runFinalization();
+    }
+
+    /** Test allwidgets.xml */
+    @Test
+    public void testAllWidgets() throws ClassNotFoundException {
+        renderAndVerify("allwidgets.xml", "allwidgets.png");
+
+        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
+    }
+
+    @Test
+    public void testArrayCheck() throws ClassNotFoundException {
+        renderAndVerify("array_check.xml", "array_check.png");
+    }
+
+    @Test
+    public void testAllWidgetsTablet() throws ClassNotFoundException {
+        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
+
+        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
+    }
+
     @Test
     public void testActivityActionBar() throws ClassNotFoundException {
         LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -341,42 +408,6 @@
         renderAndVerify(params, "simple_activity.png");
     }
 
-    /** Test allwidgets.xml */
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets.png");
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testArrayCheck() throws ClassNotFoundException {
-        renderAndVerify("array_check.xml", "array_check.png");
-    }
-
-    @Test
-    public void testAllWidgetsTablet() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    private static void gc() {
-        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
-        Object obj = new Object();
-        WeakReference ref = new WeakReference<Object>(obj);
-        obj = null;
-        while(ref.get() != null) {
-            System.gc();
-            System.runFinalization();
-        }
-
-        System.gc();
-        System.runFinalization();
-    }
-
     @AfterClass
     public static void tearDown() {
         sLayoutLibLog = null;
@@ -397,7 +428,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("expand_vert_layout.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         ConfigGenerator customConfigGenerator = new ConfigGenerator()
@@ -431,7 +463,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("indeterminate_progressbar.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -456,7 +489,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -474,7 +508,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("vector_drawable_android.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -490,7 +525,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -501,6 +537,7 @@
 
         RenderResult result = renderAndVerify(params, "scrolled.png");
         assertNotNull(result);
+        assertNotNull(result.getResult());
         assertTrue(result.getResult().isSuccess());
 
         ViewInfo rootLayout = result.getRootViews().get(0);
@@ -520,7 +557,15 @@
     @Test
     public void testGetResourceNameVariants() throws Exception {
         // Setup
-        SessionParams params = createSessionParams("empty.xml", ConfigGenerator.NEXUS_4);
+        // Create the layout pull parser for our resources (empty.xml can not be part of the test
+        // app as it won't compile).
+        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
+        // Create LayoutLibCallback.
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+        layoutLibCallback.initResources();
+        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
+                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
         AssetManager assetManager = AssetManager.getSystem();
         DisplayMetrics metrics = new DisplayMetrics();
         Configuration configuration = RenderAction.getConfiguration(params);
@@ -562,6 +607,8 @@
             throws ClassNotFoundException {
         // TODO: Set up action bar handler properly to test menu rendering.
         // Create session params.
+        System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
+        System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
         RenderSession session = sBridge.createSession(params);
 
         if (frameTimeNanos != -1) {
@@ -629,7 +676,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser(layoutFileName);
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
         // TODO: Set up action bar handler properly to test menu rendering.
         // Create session params.
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 96ae523..bae2dc0c 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -42,6 +42,9 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Map;
 
 import com.google.android.collect.Maps;
@@ -59,10 +62,11 @@
     private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
     private final ILogger mLog;
     private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
-    private final ClassLoader mModuleClassLoader = new ModuleClassLoader(PROJECT_CLASSES_LOCATION);
+    private final ClassLoader mModuleClassLoader;
 
-    public LayoutLibTestCallback(ILogger logger) {
+    public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
         mLog = logger;
+        mModuleClassLoader = classLoader;
     }
 
     public void initResources() throws ClassNotFoundException {
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
deleted file mode 100644
index 110f4c8..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 com.android.layoutlib.bridge.intensive.setup;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-
-/**
- * The ClassLoader to load the project's classes.
- */
-public class ModuleClassLoader extends ClassLoader {
-
-    private final Map<String, Class<?>> mClasses = Maps.newHashMap();
-    private final String mClassLocation;
-
-    public ModuleClassLoader(String classLocation) {
-        mClassLocation = classLocation;
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        Class<?> aClass = mClasses.get(name);
-        if (aClass != null) {
-            return aClass;
-        }
-        String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class");
-        InputStream classInputStream = getClass().getResourceAsStream(pathName);
-        if (classInputStream == null) {
-            throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
-        }
-        byte[] data;
-        try {
-            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-            int nRead;
-            data = new byte[16384];  // 16k
-            while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
-                buffer.write(data, 0, nRead);
-            }
-            buffer.flush();
-            data = buffer.toByteArray();
-        } catch (IOException e) {
-            // Wrap the exception with ClassNotFoundException so that caller can deal with it.
-            throw new ClassNotFoundException("Unable to load class " + name, e);
-        }
-        aClass = defineClass(name, data, 0, data.length);
-        mClasses.put(name, aClass);
-        return aClass;
-    }
-}
diff --git a/tools/preload2/Android.mk b/tools/preload2/Android.mk
index ce877b3..09d95ff 100644
--- a/tools/preload2/Android.mk
+++ b/tools/preload2/Android.mk
@@ -5,7 +5,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 
 # To connect to devices (and take hprof dumps).
-LOCAL_STATIC_JAVA_LIBRARIES := ddmlib-prebuilt
+LOCAL_STATIC_JAVA_LIBRARIES := ddmlib-prebuilt tools-common-prebuilt
 
 # To process hprof dumps.
 LOCAL_STATIC_JAVA_LIBRARIES += perflib-prebuilt trove-prebuilt guavalib
diff --git a/wifi/java/android/net/wifi/EAPConstants.java b/wifi/java/android/net/wifi/EAPConstants.java
new file mode 100644
index 0000000..b5f7c94
--- /dev/null
+++ b/wifi/java/android/net/wifi/EAPConstants.java
@@ -0,0 +1,57 @@
+/**
+ * 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 android.net.wifi;
+
+/**
+ * Utility class containing EAP (Extensible Authentication Protocol) Related constants.
+ *
+ * @hide
+ */
+public final class EAPConstants {
+    // Constant definition for EAP types. Refer to
+    // http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info.
+    public static final int EAP_MD5 = 4;
+    public static final int EAP_OTP = 5;
+    public static final int EAP_RSA = 9;
+    public static final int EAP_KEA = 11;
+    public static final int EAP_KEA_VALIDATE = 12;
+    public static final int EAP_TLS = 13;
+    public static final int EAP_LEAP = 17;
+    public static final int EAP_SIM = 18;
+    public static final int EAP_TTLS = 21;
+    public static final int EAP_AKA = 23;
+    public static final int EAP_3Com = 24;
+    public static final int EAP_MSCHAPv2 = 26;
+    public static final int EAP_PEAP = 29;
+    public static final int EAP_POTP = 32;
+    public static final int EAP_ActiontecWireless = 35;
+    public static final int EAP_HTTPDigest = 38;
+    public static final int EAP_SPEKE = 41;
+    public static final int EAP_MOBAC = 42;
+    public static final int EAP_FAST = 43;
+    public static final int EAP_ZLXEAP = 44;
+    public static final int EAP_Link = 45;
+    public static final int EAP_PAX = 46;
+    public static final int EAP_PSK = 47;
+    public static final int EAP_SAKE = 48;
+    public static final int EAP_IKEv2 = 49;
+    public static final int EAP_AKA_PRIME = 50;
+    public static final int EAP_GPSK = 51;
+    public static final int EAP_PWD = 52;
+    public static final int EAP_EKE = 53;
+    public static final int EAP_TEAP = 55;
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index bc38284..9e897bf 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -59,11 +59,6 @@
 
     int addOrUpdateNetwork(in WifiConfiguration config);
 
-    int addPasspointManagementObject(String mo);
-
-    int modifyPasspointManagementObject(String fqdn,
-                                        in List<PasspointManagementObjectDefinition> mos);
-
     boolean addPasspointConfiguration(in PasspointConfiguration config);
 
     boolean removePasspointConfiguration(in String fqdn);
@@ -132,8 +127,6 @@
 
     WifiConfiguration getWifiApConfiguration();
 
-    WifiConfiguration buildWifiConfig(String uriString, String mimeType, in byte[] data);
-
     void setWifiApConfiguration(in WifiConfiguration wifiConfig);
 
     Messenger getWifiServiceMessenger();
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 465addf..da87135 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -66,6 +66,93 @@
      * supported by the access point.
      */
     public String capabilities;
+
+    /**
+     * @hide
+     * No security protocol.
+     */
+    public static final int PROTOCOL_NONE = 0;
+    /**
+     * @hide
+     * Security protocol type: WPA version 1.
+     */
+    public static final int PROTOCOL_WPA = 1;
+    /**
+     * @hide
+     * Security protocol type: WPA version 2, also called RSN.
+     */
+    public static final int PROTOCOL_WPA2 = 2;
+    /**
+     * @hide
+     * Security protocol type:
+     * OSU Server-only authenticated layer 2 Encryption Network.
+     * Used for Hotspot 2.0.
+     */
+    public static final int PROTOCOL_OSEN = 3;
+
+    /**
+     * @hide
+     * No security key management scheme.
+     */
+    public static final int KEY_MGMT_NONE = 0;
+    /**
+     * @hide
+     * Security key management scheme: PSK.
+     */
+    public static final int KEY_MGMT_PSK = 1;
+    /**
+     * @hide
+     * Security key management scheme: EAP.
+     */
+    public static final int KEY_MGMT_EAP = 2;
+    /**
+     * @hide
+     * Security key management scheme: FT_PSK.
+     */
+    public static final int KEY_MGMT_FT_PSK = 3;
+    /**
+     * @hide
+     * Security key management scheme: FT_EAP.
+     */
+    public static final int KEY_MGMT_FT_EAP = 4;
+    /**
+     * @hide
+     * Security key management scheme: PSK_SHA256
+     */
+    public static final int KEY_MGMT_PSK_SHA256 = 5;
+    /**
+     * @hide
+     * Security key management scheme: EAP_SHA256.
+     */
+    public static final int KEY_MGMT_EAP_SHA256 = 6;
+    /**
+     * @hide
+     * Security key management scheme: OSEN.
+     * Used for Hotspot 2.0.
+     */
+    public static final int KEY_MGMT_OSEN = 7;
+
+    /**
+     * @hide
+     * No cipher suite.
+     */
+    public static final int CIPHER_NONE = 0;
+    /**
+     * @hide
+     * No group addressed, only used for group data cipher.
+     */
+    public static final int CIPHER_NO_GROUP_ADDRESSED = 1;
+    /**
+     * @hide
+     * Cipher suite: TKIP
+     */
+    public static final int CIPHER_TKIP = 2;
+    /**
+     * @hide
+     * Cipher suite: CCMP
+     */
+    public static final int CIPHER_CCMP = 3;
+
     /**
      * The detected signal level in dBm, also known as the RSSI.
      *
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 98a6ca5..674c161 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -842,36 +842,6 @@
     }
 
     /**
-     * Add a Hotspot 2.0 release 2 Management Object
-     * @param mo The MO in XML form
-     * @return -1 for failure
-     * @hide
-     */
-    public int addPasspointManagementObject(String mo) {
-        try {
-            return mService.addPasspointManagementObject(mo);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Modify a Hotspot 2.0 release 2 Management Object
-     * @param fqdn The FQDN of the service provider
-     * @param mos A List of MO definitions to be updated
-     * @return the number of nodes updated, or -1 for failure
-     * @hide
-     */
-    public int modifyPasspointManagementObject(String fqdn,
-                                               List<PasspointManagementObjectDefinition> mos) {
-        try {
-            return mService.modifyPasspointManagementObject(fqdn, mos);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Add a Passpoint configuration.  The configuration provides a credential
      * for connecting to Passpoint networks that are operated by the Passpoint
      * service provider specified in the configuration.
@@ -1628,20 +1598,6 @@
     }
 
     /**
-     * Builds a WifiConfiguration from Hotspot 2.0 MIME file.
-     * @return AP details in WifiConfiguration
-     *
-     * @hide Dont open yet
-     */
-    public WifiConfiguration buildWifiConfig(String uriString, String mimeType, byte[] data) {
-        try {
-            return mService.buildWifiConfig(uriString, mimeType, data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Sets the Wi-Fi AP Configuration.
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      *