Merge "Fix disabling DO single user features when clearDeviceOwner() is called"
diff --git a/Android.mk b/Android.mk
index 466a7d9..552103d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -245,12 +245,13 @@
 	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 \
+	core/java/android/service/autofill/IAutoFillCallback.aidl \
 	core/java/android/service/autofill/IAutoFillManagerService.aidl \
 	core/java/android/service/autofill/IAutoFillService.aidl \
 	core/java/android/service/carrier/ICarrierService.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 873957b..f585901 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";
@@ -5983,6 +5985,7 @@
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
     method public void addUserRestriction(android.content.ComponentName, java.lang.String);
+    method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
     method public void clearCrossProfileIntentFilters(android.content.ComponentName);
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
@@ -6265,6 +6268,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
+    method public int getAutoFillId();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -7904,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);
@@ -8037,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);
@@ -32190,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";
@@ -34641,13 +34648,26 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure);
-    method public void onReady();
-    method public void onSessionFinished(java.lang.String);
-    method public void onShutdown();
+    method public void onConnected();
+    method public void onDisconnected();
+    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillCallback.FillData);
+  }
+
+  public static final class FillCallback.FillData {
+  }
+
+  public static class FillCallback.FillData.Builder {
+    ctor public FillCallback.FillData.Builder();
+    method public android.service.autofill.FillCallback.FillData build();
+    method public android.service.autofill.FillCallback.FillData.Builder setTextField(int, java.lang.String);
+  }
+
 }
 
 package android.service.carrier {
diff --git a/api/system-current.txt b/api/system-current.txt
index 88f25a8..0314b54 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";
@@ -6154,6 +6156,7 @@
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
     method public void addUserRestriction(android.content.ComponentName, java.lang.String);
+    method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
     method public void clearCrossProfileIntentFilters(android.content.ComponentName);
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
@@ -6456,6 +6459,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
+    method public int getAutoFillId();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -8236,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);
@@ -8369,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);
@@ -34878,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";
@@ -37434,13 +37441,26 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure);
-    method public void onReady();
-    method public void onSessionFinished(java.lang.String);
-    method public void onShutdown();
+    method public void onConnected();
+    method public void onDisconnected();
+    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillCallback.FillData);
+  }
+
+  public static final class FillCallback.FillData {
+  }
+
+  public static class FillCallback.FillData.Builder {
+    ctor public FillCallback.FillData.Builder();
+    method public android.service.autofill.FillCallback.FillData build();
+    method public android.service.autofill.FillCallback.FillData.Builder setTextField(int, java.lang.String);
+  }
+
 }
 
 package android.service.carrier {
diff --git a/api/test-current.txt b/api/test-current.txt
index 5d08832..092affc 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);
@@ -5999,6 +6001,7 @@
     method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
     method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
     method public void addUserRestriction(android.content.ComponentName, java.lang.String);
+    method public boolean bindDeviceAdminServiceAsUser(android.content.ComponentName, android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle);
     method public void clearCrossProfileIntentFilters(android.content.ComponentName);
     method public void clearDeviceOwnerApp(java.lang.String);
     method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
@@ -6281,6 +6284,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
+    method public int getAutoFillId();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -7920,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);
@@ -8054,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);
@@ -32276,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";
@@ -34731,13 +34738,26 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
-    method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure);
-    method public void onReady();
-    method public void onSessionFinished(java.lang.String);
-    method public void onShutdown();
+    method public void onConnected();
+    method public void onDisconnected();
+    method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
+  public final class FillCallback {
+    method public void onFailure(java.lang.CharSequence);
+    method public void onSuccess(android.service.autofill.FillCallback.FillData);
+  }
+
+  public static final class FillCallback.FillData {
+  }
+
+  public static class FillCallback.FillData.Builder {
+    ctor public FillCallback.FillData.Builder();
+    method public android.service.autofill.FillCallback.FillData build();
+    method public android.service.autofill.FillCallback.FillData.Builder setTextField(int, java.lang.String);
+  }
+
 }
 
 package android.service.carrier {
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/annotation/HalfFloat.java b/core/java/android/annotation/HalfFloat.java
new file mode 100644
index 0000000..d3e9f08
--- /dev/null
+++ b/core/java/android/annotation/HalfFloat.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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * <p>Denotes that the annotated element represents a half-precision floating point
+ * value. Such values are stored in short data types and can be manipulated with
+ * the {@link android.util.Half} class. If applied to an array of short, every
+ * element in the array represents a half-precision float.</p>
+ *
+ * <p>Example:</p>
+ *
+ * <pre>{@code
+ * public abstract void setPosition(@HalfFloat short x, @HalfFloat short y, @HalfFloat short z);
+ * }</pre>
+ *
+ * @see android.util.Half
+ * @see android.util.Half#valueOf(float)
+ * @see android.util.Half#toFloat(short)
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
+public @interface HalfFloat {
+}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b381339..64e5dfc 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -53,7 +53,6 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
-import android.hardware.input.InputManager;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.net.Uri;
@@ -70,6 +69,9 @@
 import android.os.StrictMode;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.service.autofill.FillableInputField;
+import android.service.autofill.AutoFillService;
+import android.service.autofill.IAutoFillCallback;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
@@ -90,8 +92,6 @@
 import android.view.ContextThemeWrapper;
 import android.view.DragAndDropPermissions;
 import android.view.DragEvent;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
@@ -113,9 +113,11 @@
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.EditText;
 import android.widget.Toast;
 import android.widget.Toolbar;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.app.WindowDecorActionBar;
@@ -802,11 +804,13 @@
         private boolean mReleased;
         private boolean mUpdated;
     }
-    private final ArrayList<ManagedCursor> mManagedCursors =
-        new ArrayList<ManagedCursor>();
 
-    // protected by synchronized (this)
+    @GuardedBy("mManagedCursors")
+    private final ArrayList<ManagedCursor> mManagedCursors = new ArrayList<>();
+
+    @GuardedBy("this")
     int mResultCode = RESULT_CANCELED;
+    @GuardedBy("this")
     Intent mResultData = null;
 
     private TranslucentConversionListener mTranslucentCallback;
@@ -837,6 +841,9 @@
     private boolean mHasCurrentPermissionsRequest;
     private boolean mEatKeyUpEvent;
 
+    @GuardedBy("this")
+    private IAutoFillCallback mAutoFillCallback;
+
     private static native String getDlWarning();
 
     /** Return the intent that started this activity. */
@@ -1306,7 +1313,7 @@
     public boolean isVoiceInteractionRoot() {
         try {
             return mVoiceInteractor != null
-                    && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken);
+                    && ActivityManager.getService().isRootVoiceInteraction(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1329,7 +1336,7 @@
      */
     public boolean isLocalVoiceInteractionSupported() {
         try {
-            return ActivityManagerNative.getDefault().supportsLocalVoiceInteraction();
+            return ActivityManager.getService().supportsLocalVoiceInteraction();
         } catch (RemoteException re) {
         }
         return false;
@@ -1343,7 +1350,7 @@
      */
     public void startLocalVoiceInteraction(Bundle privateOptions) {
         try {
-            ActivityManagerNative.getDefault().startLocalVoiceInteraction(mToken, privateOptions);
+            ActivityManager.getService().startLocalVoiceInteraction(mToken, privateOptions);
         } catch (RemoteException re) {
         }
     }
@@ -1372,7 +1379,7 @@
      */
     public void stopLocalVoiceInteraction() {
         try {
-            ActivityManagerNative.getDefault().stopLocalVoiceInteraction(mToken);
+            ActivityManager.getService().stopLocalVoiceInteraction(mToken);
         } catch (RemoteException re) {
         }
     }
@@ -1688,6 +1695,53 @@
     }
 
     /**
+     * Lazily gets the {@code IAutoFillCallback} for this activitity.
+     *
+     * <p>This callback is used by the {@link AutoFillService} app to auto-fill the activity fields.
+     */
+    IAutoFillCallback getAutoFillCallback() {
+        synchronized (this) {
+            if (mAutoFillCallback == null) {
+                mAutoFillCallback = new IAutoFillCallback.Stub() {
+                    @Override
+                    public void autofill(@SuppressWarnings("rawtypes") List fields)
+                            throws RemoteException {
+                        runOnUiThread(() -> {
+                            final View root = getWindow().getDecorView().getRootView();
+                            for (Object field : fields) {
+                                if (!(field instanceof FillableInputField)) {
+                                    Slog.w(TAG,  "autofill(): invalid type " + field.getClass());
+                                    continue;
+                                }
+                                FillableInputField autoFillField = (FillableInputField) field;
+                                final int viewId = autoFillField.getId();
+                                final View view = root.findViewByAccessibilityIdTraversal(viewId);
+                                // TODO: should handle other types of view as well, but that will
+                                // require:
+                                // - a new interface like AutoFillable
+                                // - a way for the views to define the type of the autofield value
+                                if ((view instanceof EditText)) {
+                                    ((EditText) view).setText(autoFillField.getValue());
+                                }
+                            }
+                        });
+                    }
+
+                    @Override
+                    public void showError(String message) {
+                        runOnUiThread(() -> {
+                            // TODO: temporary show a toast until it uses the Snack bar.
+                            Toast.makeText(Activity.this, "Auto-fill request failed: " + message,
+                                    Toast.LENGTH_LONG).show();
+                        });
+                    }
+                };
+            }
+        }
+        return mAutoFillCallback;
+    }
+
+    /**
      * Request the Keyboard Shortcuts screen to show up. This will trigger
      * {@link #onProvideKeyboardShortcuts} to retrieve the shortcuts for the foreground activity.
      */
@@ -1744,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;
@@ -1860,7 +1914,7 @@
         if (mDoReportFullyDrawn) {
             mDoReportFullyDrawn = false;
             try {
-                ActivityManagerNative.getDefault().reportActivityFullyDrawn(mToken);
+                ActivityManager.getService().reportActivityFullyDrawn(mToken);
             } catch (RemoteException e) {
             }
         }
@@ -1886,7 +1940,7 @@
      */
     public boolean isInMultiWindowMode() {
         try {
-            return ActivityManagerNative.getDefault().isInMultiWindowMode(mToken);
+            return ActivityManager.getService().isInMultiWindowMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1911,7 +1965,7 @@
      */
     public boolean isInPictureInPictureMode() {
         try {
-            return ActivityManagerNative.getDefault().isInPictureInPictureMode(mToken);
+            return ActivityManager.getService().isInPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1923,7 +1977,7 @@
      */
     public void enterPictureInPictureMode() {
         try {
-            ActivityManagerNative.getDefault().enterPictureInPictureMode(mToken);
+            ActivityManager.getService().enterPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -2983,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.
@@ -2991,7 +3045,7 @@
      */
     @Override
     public int getWindowStackId() throws RemoteException {
-        return ActivityManagerNative.getDefault().getActivityStackId(mToken);
+        return ActivityManager.getService().getActivityStackId(mToken);
     }
 
     /**
@@ -4479,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);
@@ -4709,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,
@@ -4780,7 +4834,7 @@
             try {
                 intent.migrateExtraStreamToClipData();
                 intent.prepareToLeaveProcess(this);
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                     .startNextMatchingActivity(mToken, intent, options);
             } catch (RemoteException e) {
                 // Empty
@@ -4978,7 +5032,7 @@
      */
     public void overridePendingTransition(int enterAnim, int exitAnim) {
         try {
-            ActivityManagerNative.getDefault().overridePendingTransition(
+            ActivityManager.getService().overridePendingTransition(
                     mToken, getPackageName(), enterAnim, exitAnim);
         } catch (RemoteException e) {
         }
@@ -5103,7 +5157,7 @@
     @Nullable
     public String getCallingPackage() {
         try {
-            return ActivityManagerNative.getDefault().getCallingPackage(mToken);
+            return ActivityManager.getService().getCallingPackage(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5126,7 +5180,7 @@
     @Nullable
     public ComponentName getCallingActivity() {
         try {
-            return ActivityManagerNative.getDefault().getCallingActivity(mToken);
+            return ActivityManager.getService().getCallingActivity(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5211,7 +5265,7 @@
             throw new IllegalStateException("Must be called from main thread");
         }
         try {
-            ActivityManagerNative.getDefault().requestActivityRelaunch(mToken);
+            ActivityManager.getService().requestActivityRelaunch(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -5233,7 +5287,7 @@
                 if (resultData != null) {
                     resultData.prepareToLeaveProcess(this);
                 }
-                if (ActivityManagerNative.getDefault()
+                if (ActivityManager.getService()
                         .finishActivity(mToken, resultCode, resultData, finishTask)) {
                     mFinished = true;
                 }
@@ -5276,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) {
@@ -5322,7 +5376,7 @@
     public void finishActivity(int requestCode) {
         if (mParent == null) {
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishSubActivity(mToken, mEmbeddedID, requestCode);
             } catch (RemoteException e) {
                 // Empty
@@ -5342,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
@@ -5370,7 +5424,7 @@
      */
     public boolean releaseInstance() {
         try {
-            return ActivityManagerNative.getDefault().releaseActivityInstance(mToken);
+            return ActivityManager.getService().releaseActivityInstance(mToken);
         } catch (RemoteException e) {
             // Empty
         }
@@ -5460,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,
@@ -5485,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
@@ -5508,7 +5562,7 @@
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                         .getRequestedOrientation(mToken);
             } catch (RemoteException e) {
                 // Empty
@@ -5527,7 +5581,7 @@
      */
     public int getTaskId() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getTaskForActivity(mToken, false);
         } catch (RemoteException e) {
             return -1;
@@ -5542,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;
         }
@@ -5561,7 +5615,7 @@
      */
     public boolean moveTaskToBack(boolean nonRoot) {
         try {
-            return ActivityManagerNative.getDefault().moveActivityTaskToBack(
+            return ActivityManager.getService().moveActivityTaskToBack(
                     mToken, nonRoot);
         } catch (RemoteException e) {
             // Empty
@@ -5732,7 +5786,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().setTaskDescription(mToken, mTaskDescription);
+            ActivityManager.getService().setTaskDescription(mToken, mTaskDescription);
         } catch (RemoteException e) {
         }
     }
@@ -5974,6 +6028,11 @@
             getWindow().peekDecorView().getViewRootImpl().dump(prefix, fd, writer, args);
         }
 
+        if (mAutoFillCallback != null) {
+            writer.print(prefix); writer.print("mAutoFillCallback: " );
+                    writer.println(mAutoFillCallback);
+        }
+
         mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
     }
 
@@ -5990,7 +6049,7 @@
      */
     public boolean isImmersive() {
         try {
-            return ActivityManagerNative.getDefault().isImmersive(mToken);
+            return ActivityManager.getService().isImmersive(mToken);
         } catch (RemoteException e) {
             return false;
         }
@@ -6008,7 +6067,7 @@
             return false;
         }
         try {
-            return ActivityManagerNative.getDefault().isTopOfTask(getActivityToken());
+            return ActivityManager.getService().isTopOfTask(getActivityToken());
         } catch (RemoteException e) {
             return false;
         }
@@ -6034,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) {
@@ -6073,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;
@@ -6119,7 +6178,7 @@
     ActivityOptions getActivityOptions() {
         try {
             return ActivityOptions.fromBundle(
-                    ActivityManagerNative.getDefault().getActivityOptions(mToken));
+                    ActivityManager.getService().getActivityOptions(mToken));
         } catch (RemoteException e) {
         }
         return null;
@@ -6163,7 +6222,7 @@
             visible = false;
         }
         try {
-            mVisibleBehind = ActivityManagerNative.getDefault()
+            mVisibleBehind = ActivityManager.getService()
                     .requestVisibleBehind(mToken, visible) && visible;
         } catch (RemoteException e) {
             mVisibleBehind = false;
@@ -6204,7 +6263,7 @@
     @SystemApi
     public boolean isBackgroundVisibleBehind() {
         try {
-            return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken);
+            return ActivityManager.getService().isBackgroundVisibleBehind(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -6261,7 +6320,7 @@
      */
     public void setImmersive(boolean i) {
         try {
-            ActivityManagerNative.getDefault().setImmersive(mToken, i);
+            ActivityManager.getService().setImmersive(mToken, i);
         } catch (RemoteException e) {
             // pass
         }
@@ -6325,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());
@@ -6446,7 +6505,7 @@
             if (info.taskAffinity == null) {
                 return false;
             }
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .shouldUpRecreateTask(mToken, info.taskAffinity);
         } catch (RemoteException e) {
             return false;
@@ -6499,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;
@@ -7015,7 +7074,7 @@
      */
     public void startLockTask() {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeByToken(mToken);
+            ActivityManager.getService().startLockTaskModeByToken(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -7039,7 +7098,7 @@
      */
     public void stopLockTask() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            ActivityManager.getService().stopLockTaskMode();
         } catch (RemoteException e) {
         }
     }
@@ -7051,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 4a39e4a..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;
 
@@ -447,6 +450,9 @@
     /** @hide requestType for assist context: generate full AssistStructure. */
     public static final int ASSIST_CONTEXT_FULL = 1;
 
+    /** @hide requestType for assist context: generate full AssistStructure for auto-fill. */
+    public static final int ASSIST_CONTEXT_AUTOFILL = 2;
+
     /** @hide Flag for registerUidObserver: report changes in process state. */
     public static final int UID_OBSERVER_PROCSTATE = 1<<0;
 
@@ -823,7 +829,7 @@
     /** @hide */
     public int getFrontActivityScreenCompatMode() {
         try {
-            return ActivityManagerNative.getDefault().getFrontActivityScreenCompatMode();
+            return getService().getFrontActivityScreenCompatMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -832,7 +838,7 @@
     /** @hide */
     public void setFrontActivityScreenCompatMode(int mode) {
         try {
-            ActivityManagerNative.getDefault().setFrontActivityScreenCompatMode(mode);
+            getService().setFrontActivityScreenCompatMode(mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -841,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();
         }
@@ -850,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();
         }
@@ -859,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();
         }
@@ -868,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();
         }
@@ -1163,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();
@@ -1552,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();
@@ -1577,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();
@@ -1723,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();
         }
@@ -1748,7 +1754,7 @@
     private void ensureAppTaskThumbnailSizeLocked() {
         if (mAppTaskThumbnailSize == null) {
             try {
-                mAppTaskThumbnailSize = ActivityManagerNative.getDefault().getAppTaskThumbnailSize();
+                mAppTaskThumbnailSize = getService().getAppTaskThumbnailSize();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1813,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();
@@ -1856,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();
         }
@@ -1872,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();
         }
@@ -2040,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();
         }
@@ -2049,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();
         }
@@ -2098,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();
         }
@@ -2283,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();
@@ -2298,7 +2304,7 @@
     public PendingIntent getRunningServiceControlPanel(ComponentName service)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault()
+            return getService()
                     .getRunningServiceControlPanel(service);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2403,7 +2409,7 @@
      */
     public void getMemoryInfo(MemoryInfo outInfo) {
         try {
-            ActivityManagerNative.getDefault().getMemoryInfo(outInfo);
+            getService().getMemoryInfo(outInfo);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2542,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();
@@ -2576,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();
@@ -2594,7 +2600,7 @@
      */
     public void clearGrantedUriPermissions(String packageName) {
         try {
-            ActivityManagerNative.getDefault().clearGrantedUriPermissions(packageName,
+            getService().clearGrantedUriPermissions(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2715,7 +2721,7 @@
      */
     public List<ProcessErrorStateInfo> getProcessesInErrorState() {
         try {
-            return ActivityManagerNative.getDefault().getProcessesInErrorState();
+            return getService().getProcessesInErrorState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3052,7 +3058,7 @@
      */
     public List<ApplicationInfo> getRunningExternalApplications() {
         try {
-            return ActivityManagerNative.getDefault().getRunningExternalApplications();
+            return getService().getRunningExternalApplications();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3068,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();
@@ -3087,7 +3093,7 @@
      */
     public List<RunningAppProcessInfo> getRunningAppProcesses() {
         try {
-            return ActivityManagerNative.getDefault().getRunningAppProcesses();
+            return getService().getRunningAppProcesses();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3205,7 +3211,7 @@
      */
     static public void getMyMemoryState(RunningAppProcessInfo outState) {
         try {
-            ActivityManagerNative.getDefault().getMyMemoryState(outState);
+            getService().getMyMemoryState(outState);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3224,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();
         }
@@ -3257,7 +3263,7 @@
      */
     public void killBackgroundProcesses(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killBackgroundProcesses(packageName,
+            getService().killBackgroundProcesses(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3275,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();
@@ -3303,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();
         }
@@ -3322,7 +3328,7 @@
      */
     public ConfigurationInfo getDeviceConfigurationInfo() {
         try {
-            return ActivityManagerNative.getDefault().getDeviceConfigurationInfo();
+            return getService().getDeviceConfigurationInfo();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3412,7 +3418,7 @@
      */
     public static boolean isUserAMonkey() {
         try {
-            return ActivityManagerNative.getDefault().isUserAMonkey();
+            return getService().isUserAMonkey();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3534,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();
@@ -3549,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();
@@ -3562,7 +3568,7 @@
      */
     public boolean switchUser(int userid) {
         try {
-            return ActivityManagerNative.getDefault().switchUser(userid);
+            return getService().switchUser(userid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3577,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();
             }
@@ -3605,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();
         }
@@ -3614,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();
         }
@@ -3659,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);
     }
@@ -3768,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();
@@ -3788,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();
         }
@@ -3799,7 +3822,7 @@
      */
     public void startLockTaskMode(int taskId) {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeById(taskId);
+            getService().startLockTaskModeById(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3810,7 +3833,7 @@
      */
     public void stopLockTaskMode() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            getService().stopLockTaskMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3838,7 +3861,7 @@
      */
     public int getLockTaskModeState() {
         try {
-            return ActivityManagerNative.getDefault().getLockTaskModeState();
+            return getService().getLockTaskModeState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3856,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 199fda4..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.
      */
@@ -109,4 +91,4 @@
     static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
         ActivityManager.noteAlarmFinish(ps, sourceUid, tag);
     }
-}
\ No newline at end of file
+}
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 78204a0..1aa13a9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -88,6 +88,8 @@
 import android.provider.Settings;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
+import android.service.autofill.IAutoFillCallback;
+import android.service.voice.VoiceInteractionSession;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -1798,7 +1800,7 @@
             }
             if (a != null) {
                 mNewActivities = null;
-                IActivityManager am = ActivityManagerNative.getDefault();
+                IActivityManager am = ActivityManager.getService();
                 ActivityClientRecord prev;
                 do {
                     if (localLOGV) Slog.v(
@@ -2710,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();
         }
@@ -2790,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) {
@@ -2820,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();
@@ -2881,16 +2883,24 @@
                 mLastAssistStructures.remove(i);
             }
         }
+        // Filling for auto-fill has a few differences:
+        // - it does not need an AssistContent
+        // - it does not call onProvideAssistData()
+        // - it needs an IAutoFillCallback
+        boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL;
+
         Bundle data = new Bundle();
         AssistStructure structure = null;
-        AssistContent content = new AssistContent();
+        AssistContent content = forAutofill ? null : new AssistContent();
         ActivityClientRecord r = mActivities.get(cmd.activityToken);
         Uri referrer = null;
         if (r != null) {
             r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
-            r.activity.onProvideAssistData(data);
+            if (!forAutofill) {
+                r.activity.onProvideAssistData(data);
+            }
             referrer = r.activity.onProvideReferrer();
-            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
+            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) {
                 structure = new AssistStructure(r.activity);
                 Intent activityIntent = r.activity.getIntent();
                 if (activityIntent != null && (r.window == null ||
@@ -2900,18 +2910,28 @@
                     intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                             | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
                     intent.removeUnsafeExtras();
-                    content.setDefaultIntent(intent);
+                    if (forAutofill) {
+                        IAutoFillCallback autoFillCallback = r.activity.getAutoFillCallback();
+                        data.putBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK,
+                                autoFillCallback.asBinder());
+                    } else {
+                        content.setDefaultIntent(intent);
+                    }
                 } else {
-                    content.setDefaultIntent(new Intent());
+                    if (!forAutofill) {
+                        content.setDefaultIntent(new Intent());
+                    }
                 }
-                r.activity.onProvideAssistContent(content);
+                if (!forAutofill) {
+                    r.activity.onProvideAssistContent(content);
+                }
             }
         }
         if (structure == null) {
             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) {
@@ -2950,7 +2970,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
+            ActivityManager.getService().backgroundResourcesReleased(token);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3049,7 +3069,7 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
 
-        IActivityManager mgr = ActivityManagerNative.getDefault();
+        IActivityManager mgr = ActivityManager.getService();
 
         BroadcastReceiver receiver;
         try {
@@ -3175,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();
             }
@@ -3232,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();
@@ -3261,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();
@@ -3291,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) {
@@ -3377,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();
@@ -3408,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();
@@ -3530,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();
@@ -3618,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();
                 }
@@ -3628,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) {
@@ -3717,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();
                 }
@@ -3815,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
@@ -4070,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();
             }
@@ -4324,7 +4344,7 @@
         }
         if (finishing) {
             try {
-                ActivityManagerNative.getDefault().activityDestroyed(token);
+                ActivityManager.getService().activityDestroyed(token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -4366,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();
                         }
@@ -4492,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();
                 }
@@ -4565,7 +4585,7 @@
 
         if (!tmp.onlyLocalRequest) {
             try {
-                ActivityManagerNative.getDefault().activityRelaunched(r.token);
+                ActivityManager.getService().activityRelaunched(r.token);
                 if (r.window != null) {
                     r.window.reportActivityRelaunched();
                 }
@@ -4930,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();
         }
@@ -5222,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 =
@@ -5274,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) {
@@ -5468,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);
@@ -5504,7 +5531,7 @@
         }
 
         try {
-            ActivityManagerNative.getDefault().publishContentProviders(
+            ActivityManager.getService().publishContentProviders(
                 getApplicationThread(), results);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -5526,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();
@@ -5572,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
@@ -5601,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
@@ -5675,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
@@ -5699,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
@@ -5763,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
@@ -5800,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
@@ -5814,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();
@@ -5972,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
@@ -6009,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/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 cf794c5..e222fee 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -349,7 +349,9 @@
 
     public BackStackRecord(FragmentManagerImpl manager) {
         mManager = manager;
-        mAllowOptimization = Build.isAtLeastO();
+        int targetSdkVersion = manager.mHost.getContext().getApplicationInfo().targetSdkVersion;
+        // TODO: make the check N_MR1 or O
+        mAllowOptimization = targetSdkVersion > Build.VERSION_CODES.N;
     }
 
     public int getId() {
@@ -762,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);
         }
     }
 
@@ -808,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 f1d0e10..827e026 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProvider;
@@ -60,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;
@@ -797,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,
@@ -859,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);
@@ -878,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());
@@ -895,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());
@@ -910,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());
@@ -927,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());
@@ -944,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());
@@ -961,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());
@@ -1024,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());
@@ -1038,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) {
@@ -1060,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());
@@ -1077,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());
@@ -1128,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());
@@ -1144,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());
@@ -1180,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());
@@ -1199,7 +1200,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1212,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());
@@ -1227,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());
@@ -1262,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());
@@ -1281,7 +1282,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1328,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) {
@@ -1347,7 +1348,7 @@
             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
                     getOuterContext(), receiver);
             try {
-                ActivityManagerNative.getDefault().unregisterReceiver(rd);
+                ActivityManager.getService().unregisterReceiver(rd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1390,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) {
@@ -1419,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) {
@@ -1457,8 +1458,22 @@
         return bindServiceCommon(service, conn, flags, handler, user);
     }
 
+    /** @hide */
+    @Override
+    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
+            int flags) {
+        return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
+    }
+
+    /** @hide */
+    @Override
+    public IApplicationThread getIApplicationThread() {
+        return mMainThread.getApplicationThread();
+    }
+
     private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
             handler, UserHandle user) {
+        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
         IServiceConnection sd;
         if (conn == null) {
             throw new IllegalArgumentException("connection is null");
@@ -1477,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());
@@ -1500,7 +1515,7 @@
             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                     getOuterContext(), conn);
             try {
-                ActivityManagerNative.getDefault().unbindService(sd);
+                ActivityManager.getService().unbindService(sd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1516,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) {
@@ -1541,7 +1556,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermission(
+            return ActivityManager.getService().checkPermission(
                     permission, pid, uid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1556,7 +1571,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermissionWithToken(
+            return ActivityManager.getService().checkPermissionWithToken(
                     permission, pid, uid, callerToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1641,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) {
@@ -1652,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) {
@@ -1663,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) {
@@ -1675,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) {
@@ -2141,7 +2156,8 @@
         return mOuterContext;
     }
 
-    final IBinder getActivityToken() {
+    @Override
+    public IBinder getActivityToken() {
         return mActivityToken;
     }
 
@@ -2197,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/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 5a2c5e7..07ef136 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1445,11 +1445,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 +2037,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 +2130,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 +2704,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;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 9fe34c0..d63d37b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -564,6 +564,8 @@
     void moveStackToDisplay(int stackId, int displayId) = 403;
     void enterPictureInPictureModeWithAspectRatio(in IBinder token, float aspectRatio) = 404;
     void setPictureInPictureAspectRatio(in IBinder token, float aspectRatio) = 405;
+    boolean requestAutoFillData(in IResultReceiver receiver, in Bundle receiverExtras,
+            in IBinder activityToken) = 406;
 
     // Please keep these transaction codes the same -- they are also
     // sent by C++ code. when a new method is added, use the next available transaction id.
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/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1ab809d..5ca39b0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -20,19 +20,21 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.app.Activity;
-import android.app.admin.NetworkEvent;
 import android.app.admin.PasswordMetrics;
+import android.app.IServiceConnection;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
@@ -45,10 +47,8 @@
 import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.ServiceManager.ServiceNotFoundException;
 import android.provider.ContactsContract.Directory;
 import android.provider.Settings;
 import android.security.Credentials;
@@ -6713,4 +6713,40 @@
             throw re.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Called by device owner/ profile owner in managed profile to bind the service with each other.
+     * The service must be unexported. Note that the {@link Context} used to obtain this
+     * {@link DevicePolicyManager} instance via {@link Context#getSystemService(Class)} will be used
+     * to bind to the {@link android.app.Service}.
+     * STOPSHIP (b/31952368): Update the javadoc after we policy to control which packages can talk.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param serviceIntent Identifies the service to connect to.  The Intent must specify either an
+     *        explicit component name or a package name to match an
+     *        {@link IntentFilter} published by a service.
+     * @param conn Receives information as the service is started and stopped. This must be a
+     *        valid {@link ServiceConnection} object; it must not be {@code null}.
+     * @param flags Operation options for the binding operation. See
+     *        {@link Context#bindService(Intent, ServiceConnection, int)}.
+     * @param targetUser Which user to bind to.
+     * @return If you have successfully bound to the service, {@code true} is returned;
+     *         {@code false} is returned if the connection is not made and you will not
+     *         receive the service object.
+     * @see Context#bindService(Intent, ServiceConnection, int)
+     */
+    public boolean bindDeviceAdminServiceAsUser(
+            @NonNull ComponentName admin,  Intent serviceIntent, @NonNull ServiceConnection conn,
+            @Context.BindServiceFlags int flags, @NonNull UserHandle targetUser) {
+        throwIfParentInstance("bindDeviceAdminServiceAsUser");
+        // Keep this in sync with ContextImpl.bindServiceCommon.
+        try {
+            final IServiceConnection sd = mContext.getServiceDispatcher(conn, null, flags);
+            serviceIntent.prepareToLeaveProcess(mContext);
+            return mService.bindDeviceAdminServiceAsUser(admin,
+                    mContext.getIApplicationThread(), mContext.getActivityToken(), serviceIntent,
+                    sd, flags, targetUser.getIdentifier());
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 729d12b..a2546c0 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -18,6 +18,8 @@
 package android.app.admin;
 
 import android.app.admin.NetworkEvent;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.admin.PasswordMetrics;
 import android.content.ComponentName;
@@ -319,4 +321,8 @@
     void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled);
     boolean isNetworkLoggingEnabled(in ComponentName admin);
     List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin, long batchToken);
+
+    boolean bindDeviceAdminServiceAsUser(in ComponentName admin,
+        IApplicationThread caller, IBinder token, in Intent service,
+        IServiceConnection connection, int flags, int targetUserId);
 }
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 6b720c0..a6f2366 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -515,6 +515,7 @@
         String mIdPackage;
         String mIdType;
         String mIdEntry;
+        int mAutoFillId = View.NO_ID;
         int mX;
         int mY;
         int mScrollX;
@@ -539,6 +540,7 @@
         static final int FLAGS_ACTIVATED = 0x00002000;
         static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
 
+        static final int FLAGS_HAS_AUTO_FILL_ID = 0x80000000;
         static final int FLAGS_HAS_MATRIX = 0x40000000;
         static final int FLAGS_HAS_ALPHA = 0x20000000;
         static final int FLAGS_HAS_ELEVATION = 0x10000000;
@@ -582,6 +584,9 @@
                     }
                 }
             }
+            if ((flags&FLAGS_HAS_AUTO_FILL_ID) != 0) {
+                mAutoFillId = in.readInt();
+            }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 mX = in.readInt();
                 mY = in.readInt();
@@ -637,6 +642,9 @@
             if (mId != View.NO_ID) {
                 flags |= FLAGS_HAS_ID;
             }
+            if (mAutoFillId != View.NO_ID) {
+                flags |= FLAGS_HAS_AUTO_FILL_ID;
+            }
             if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
                     || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
                 flags |= FLAGS_HAS_LARGE_COORDS;
@@ -681,6 +689,9 @@
                     }
                 }
             }
+            if ((flags&FLAGS_HAS_AUTO_FILL_ID) != 0) {
+                out.writeInt(mAutoFillId);
+            }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 out.writeInt(mX);
                 out.writeInt(mY);
@@ -751,6 +762,16 @@
         }
 
         /**
+         * Returns the id that can be used to auto-fill the view.
+         *
+         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+         * for assist.
+         */
+        public int getAutoFillId() {
+            return mAutoFillId;
+        }
+
+        /**
          * Returns the left edge of this view, in pixels, relative to the left edge of its parent.
          */
         public int getLeft() {
@@ -1322,6 +1343,11 @@
         public Rect getTempRect() {
             return mAssist.mTmpRect;
         }
+
+        @Override
+        public void setAutoFillId(int autoFillId) {
+            mNode.mAutoFillId = autoFillId;
+        }
     }
 
     /** @hide */
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/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 3964e0a..821b0f8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -32,6 +32,10 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
+import android.app.LoadedApk;
+import android.app.admin.DevicePolicyManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -4363,4 +4367,27 @@
     public boolean isCredentialEncryptedStorage() {
         return isCredentialProtectedStorage();
     }
+
+    /**
+     * @hide
+     */
+    public IBinder getActivityToken() {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
+
+    /**
+     * @hide
+     */
+    @Nullable
+    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
+            int flags) {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
+
+    /**
+     * @hide
+     */
+    public IApplicationThread getIApplicationThread() {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
 }
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index edc8d82..7533655 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -16,7 +16,10 @@
 
 package android.content;
 
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -857,4 +860,29 @@
     public boolean isCredentialProtectedStorage() {
         return mBase.isCredentialProtectedStorage();
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public IBinder getActivityToken() {
+        return mBase.getActivityToken();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
+            int flags) {
+        return mBase.getServiceDispatcher(conn, handler, flags);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public IApplicationThread getIApplicationThread() {
+        return mBase.getIApplicationThread();
+    }
 }
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..0e2b396 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1219,5 +1219,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/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/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/os/Build.java b/core/java/android/os/Build.java
index e5832c8..0d6d369 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -924,16 +924,4 @@
             return -1;
         }
     }
-
-    /**
-     * Check if the device is running on the Android O release or newer.
-     *
-     * @return {@code true} if O APIs are available for use
-     *
-     * @hide
-     */
-    public static boolean isAtLeastO() {
-        return !"REL".equals(VERSION.CODENAME)
-                && "O".compareTo(VERSION.CODENAME) <= 0;
-    }
 }
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/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index 14ce009b..3734831 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -16,26 +16,32 @@
 package android.service.autofill;
 
 import android.annotation.SdkConstant;
+import android.app.Activity;
 import android.app.Service;
 import android.app.assist.AssistStructure;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
+import android.service.voice.VoiceInteractionSession;
 import android.util.Log;
 
 import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.os.SomeArgs;
 
 /**
  * Top-level service of the current auto-fill service for a given user.
+ *
+ * <p>Apps providing auto-fill capabilities must extend this service.
  */
-// TODO: expand documentation
 public abstract class AutoFillService extends Service {
 
-    private static final String TAG = "AutoFillService";
-    private static final boolean DEBUG = true; // TODO: set to false once stable
+    static final String TAG = "AutoFillService";
+    static final boolean DEBUG = true; // TODO: set to false once stable
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -46,34 +52,39 @@
     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
     public static final String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
 
-    private static final int MSG_READY = 1;
-    private static final int MSG_NEW_SESSION = 2;
-    private static final int MSG_SESSION_FINISHED = 3;
-    private static final int MSG_SHUTDOWN = 4;
+    private static final int MSG_CONNECT = 1;
+    private static final int MSG_AUTO_FILL_ACTIVITY = 2;
+    private static final int MSG_DISCONNECT = 3;
 
-    // TODO: add metadata?
+    private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
+        @Override
+        public void send(int resultCode, Bundle resultData) throws RemoteException {
+            final AssistStructure structure = resultData
+                    .getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
+
+            final IBinder binder = resultData
+                    .getBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK);
+
+            mHandlerCaller
+                .obtainMessageOO(MSG_AUTO_FILL_ACTIVITY, structure, binder).sendToTarget();
+        }
+
+    };
 
     private final IAutoFillService mInterface = new IAutoFillService.Stub() {
         @Override
-        public void ready() {
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_READY));
+        public void onConnected() {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_CONNECT));
         }
 
         @Override
-        public void newSession(String token, Bundle data, int flags,
-                AssistStructure structure) {
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOOO(MSG_NEW_SESSION,
-                    flags, token, data, structure));
+        public IResultReceiver getAssistReceiver() {
+            return mAssistReceiver;
         }
 
         @Override
-        public void finishSession(String token) {
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_SESSION_FINISHED, token));
-        }
-
-        @Override
-        public void shutdown() {
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_SHUTDOWN));
+        public void onDisconnected() {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DISCONNECT));
         }
     };
 
@@ -82,23 +93,17 @@
         @Override
         public void executeMessage(Message msg) {
             switch (msg.what) {
-                case MSG_READY: {
-                    onReady();
+                case MSG_CONNECT: {
+                    onConnected();
                     break;
-                } case MSG_NEW_SESSION: {
+                } case MSG_AUTO_FILL_ACTIVITY: {
                     final SomeArgs args = (SomeArgs) msg.obj;
-                    final int flags = args.argi1;
-                    final String token = (String) args.arg1;
-                    final Bundle data = (Bundle) args.arg2;
-                    final AssistStructure assistStructure = (AssistStructure) args.arg3;
-                    onNewSession(token, data, flags, assistStructure);
+                    final AssistStructure structure = (AssistStructure) args.arg1;
+                    final IBinder binder = (IBinder) args.arg2;
+                    requestAutoFill(structure, binder);
                     break;
-                } case MSG_SESSION_FINISHED: {
-                    final String token = (String) msg.obj;
-                    onSessionFinished(token);
-                    break;
-                } case MSG_SHUTDOWN: {
-                    onShutdown();
+                } case MSG_DISCONNECT: {
+                    onDisconnected();
                     break;
                 } default: {
                     Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
@@ -121,58 +126,41 @@
         if (SERVICE_INTERFACE.equals(intent.getAction())) {
             return mInterface.asBinder();
         }
+        Log.w(TAG, "Tried to bind to wrong intent: " + intent);
         return null;
     }
 
     /**
-     * Called during service initialization to tell you when the system is ready
-     * to receive interaction from it.
+     * Called when the Android System connects to service.
      *
      * <p>You should generally do initialization here rather than in {@link #onCreate}.
+     */
+    public void onConnected() {
+        if (DEBUG) Log.d(TAG, "onConnected()");
+    }
+
+    /**
+     * Handles an auto-fill request.
      *
-     * <p>Sub-classes should call it first, since it sets the reference to the sytem-server service.
+     * @param structure {@link Activity}'s view structure .
+     * @param cancellationSignal signal for observing cancel requests.
+     * @param callback object used to fulllfill the request.
      */
-    // TODO: rename to onConnected() / add onDisconnected()?
-    public void onReady() {
-        if (DEBUG) Log.d(TAG, "onReady()");
+    public abstract void onFillRequest(AssistStructure structure,
+            CancellationSignal cancellationSignal, FillCallback callback);
+
+    private void requestAutoFill(AssistStructure structure, IBinder binder) {
+        final FillCallback callback = new FillCallback(binder);
+        // TODO: hook up the cancelationSignal
+        onFillRequest(structure, new CancellationSignal(), callback);
     }
 
     /**
-     * Called to receive data from the application that the user was requested auto-fill for.
-     *
-     * @param token unique token identifying the auto-fill session, it should be used when providing
-     * the auto-filled fields.
-     * @param data Arbitrary data supplied by the app through
-     * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
-     * May be {@code null} if data has been disabled by the user or device policy.
-     * @param startFlags currently always 0.
-     * @param structure If available, the structure definition of all windows currently
-     * displayed by the app.  May be {@code null} if auto-fill data has been disabled by the user
-     * or device policy; will be an empty stub if the application has disabled auto-fill
-     * by marking its window as secure.
-     */
-    @SuppressWarnings("unused")
-    // TODO: take the factory approach where this method return a session, and move the callback
-    // methods (like autofill()) to the session.
-    public void onNewSession(String token, Bundle data, int startFlags, AssistStructure structure) {
-        if (DEBUG) Log.d(TAG, "onNewSession(): token=" + token);
-    }
-
-    /**
-     * Called when an auto-fill session is finished.
-     */
-    @SuppressWarnings("unused")
-    public void onSessionFinished(String token) {
-        if (DEBUG) Log.d(TAG, "onSessionFinished(): token=" + token);
-    }
-
-    /**
-     * Called during service de-initialization to tell you when the system is shutting the
-     * service down.
+     * Called when the Android System disconnects from the service.
      *
      * <p> At this point this service may no longer be an active {@link AutoFillService}.
      */
-    public void onShutdown() {
-        if (DEBUG) Log.d(TAG, "onShutdown()");
+    public void onDisconnected() {
+        if (DEBUG) Log.d(TAG, "onDisconnected()");
     }
 }
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
new file mode 100644
index 0000000..2308440
--- /dev/null
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -0,0 +1,143 @@
+/*
+ * 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.service.autofill;
+
+import static android.service.autofill.AutoFillService.DEBUG;
+import static android.service.autofill.AutoFillService.TAG;
+
+import android.app.Activity;
+import android.app.assist.AssistStructure.ViewNode;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Handles auto-fill requests from the {@link AutoFillService} into the {@link Activity} being
+ * auto-filled.
+ */
+public final class FillCallback {
+
+    private final IAutoFillCallback mCallback;
+
+    /** @hide */
+    FillCallback(IBinder binder) {
+        mCallback = IAutoFillCallback.Stub.asInterface(binder);
+    }
+
+    /**
+     * Auto-fills the {@link Activity}.
+     *
+     * @throws RuntimeException if an error occurred while auto-filling it.
+     */
+    public void onSuccess(FillData data) {
+        if (DEBUG) Log.d(TAG, "onSuccess(): data=" + data);
+
+        Preconditions.checkArgument(data != null, "data cannot be null");
+
+        try {
+            mCallback.autofill(data.asList());
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    public void onFailure(CharSequence message) {
+        if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
+
+        Preconditions.checkArgument(message != null, "message cannot be null");
+
+        try {
+            mCallback.showError(message.toString());
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Data used to fill the fields of an {@link Activity}.
+     *
+     * <p>This class is immutable.
+     */
+    public static final class FillData {
+
+        private final List<FillableInputField> mList;
+
+        private FillData(Builder builder) {
+            final int size = builder.mFields.size();
+            final List<FillableInputField> list = new ArrayList<>(size);
+            for (int i = 0; i < size; i++) {
+                list.add(builder.mFields.valueAt(i));
+            }
+            mList = Collections.unmodifiableList(list);
+            // TODO: use FastImmutableArraySet or a similar structure instead?
+        }
+
+        /**
+         * Gets the response as a {@code List} so it can be used in a binder call.
+         */
+        List<FillableInputField> asList() {
+            return mList;
+        }
+
+        @Override
+        public String toString() {
+            return "[AutoFillResponse: " + mList + "]";
+        }
+
+        /**
+         * Builder for {@link FillData} objects.
+         *
+         * <p>Typical usage:
+         *
+         * <pre class="prettyprint">
+         * FillCallback.FillData data = new FillCallback.FillData.Builder()
+         *     .setTextField(id1, "value 1")
+         *     .setTextField(id2, "value 2")
+         *     .build()
+         * </pre>
+         */
+        public static class Builder {
+            private final SparseArray<FillableInputField> mFields = new SparseArray<>();
+
+            /**
+             * Auto-fills a text field.
+             *
+             * @param id view id as returned by {@link ViewNode#getAutoFillId()}.
+             * @param text text to be auto-filled.
+             * @return same builder so it can be chained.
+             */
+            public Builder setTextField(int id, String text) {
+                mFields.put(id, FillableInputField.forText(id, text));
+                return this;
+            }
+
+            /**
+             * Builds a new {@link FillData} instance.
+             */
+            public FillData build() {
+                return new FillData(this);
+            }
+        }
+    }
+}
diff --git a/core/java/android/service/autofill/FillableInputField.java b/core/java/android/service/autofill/FillableInputField.java
new file mode 100644
index 0000000..62950b4
--- /dev/null
+++ b/core/java/android/service/autofill/FillableInputField.java
@@ -0,0 +1,99 @@
+/*
+ * 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.service.autofill;
+
+import android.app.assist.AssistStructure.ViewNode;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a view field that can be auto-filled.
+ *
+ * <p>Currently only text-fields are supported, so the value of the field can be obtained through
+ * {@link #getValue()}.
+ *
+ * @hide
+ */
+public final class FillableInputField implements Parcelable {
+
+    private final int mId;
+    private final String mValue;
+
+    private FillableInputField(int id, String value) {
+        mId = id;
+        mValue = value;
+    }
+
+    private FillableInputField(Parcel parcel) {
+        mId = parcel.readInt();
+        mValue = parcel.readString();
+    }
+
+    /**
+     * Gets the view id as returned by {@link ViewNode#getAutoFillId()}.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Gets the value of this field.
+     */
+    public String getValue() {
+        return mValue;
+
+    }
+
+    @Override
+    public String toString() {
+        return "[AutoFillField: " + mId + "=" + mValue + "]";
+    }
+
+    /**
+     * Creates an {@code AutoFillField} for a text field.
+     *
+     * @param id view id as returned by {@link ViewNode#getAutoFillId()}.
+     * @param text value to be auto-filled.
+     */
+    public static FillableInputField forText(int id, String text) {
+        return new FillableInputField(id, text);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mId);
+        parcel.writeString(mValue);
+    }
+
+    public static final Parcelable.Creator<FillableInputField> CREATOR =
+            new Parcelable.Creator<FillableInputField>() {
+        @Override
+        public FillableInputField createFromParcel(Parcel source) {
+            return new FillableInputField(source);
+        }
+
+        @Override
+        public FillableInputField[] newArray(int size) {
+            return new FillableInputField[size];
+        }
+    };
+}
diff --git a/core/java/android/service/autofill/IAutoFillCallback.aidl b/core/java/android/service/autofill/IAutoFillCallback.aidl
new file mode 100644
index 0000000..db8ef96
--- /dev/null
+++ b/core/java/android/service/autofill/IAutoFillCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.service.autofill;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+interface IAutoFillCallback {
+    void autofill(in List values);
+    void showError(String message);
+}
diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl
index 2c06234..cab073f 100644
--- a/core/java/android/service/autofill/IAutoFillManagerService.aidl
+++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl
@@ -19,36 +19,17 @@
 import android.os.Bundle;
 
 /**
- * Intermediator between apps being auto-filled and auto-fill service implementations.
+ * Mediator between apps being auto-filled and auto-fill service implementations.
  *
  * {@hide}
  */
 interface IAutoFillManagerService {
 
     /**
-     * Starts an auto-fill session for the top activities for a given user.
-     *
-     * It's used to start a new session from system affordances.
+     * Request auto-fill on the top activity of a given user.
      *
      * @param userId user handle.
-     * @param args the bundle to pass as arguments to the voice interaction session.
-     * @param flags flags indicating optional session behavior.
      * @param activityToken optional token of activity that needs to be on top.
-     *
-     * @return session token, or null if session was not created (for example, if the activity's
-     *         user does not have an auto-fill service associated with).
      */
-     // TODO: pass callback providing an onAutoFill() method
-    String startSession(int userId, in Bundle args, int flags, IBinder activityToken);
-
-    /**
-     * Finishes an auto-fill session.
-     *
-     * @param userId user handle.
-     * @param token session token.
-     *
-     * @return true if session existed and was finished.
-     */
-    boolean finishSession(int userId, String token);
-
+    void requestAutoFill(int userId, IBinder activityToken);
 }
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 73d8d5d..e3e911c 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -16,15 +16,16 @@
 
 package android.service.autofill;
 
-import android.os.Bundle;
 import android.app.assist.AssistStructure;
+import android.os.Bundle;
+import android.service.autofill.IAutoFillCallback;
+import com.android.internal.os.IResultReceiver;
 
 /**
  * @hide
  */
-oneway interface IAutoFillService {
-    void ready();
-    void newSession(String token, in Bundle data, int flags, in AssistStructure structure);
-    void finishSession(String token);
-    void shutdown();
+interface IAutoFillService {
+    void onConnected();
+    void onDisconnected();
+    IResultReceiver getAssistReceiver();
 }
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index e9bbc2d..12aed25 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -119,6 +119,8 @@
     public static final String KEY_CONTENT = "content";
     /** @hide */
     public static final String KEY_RECEIVER_EXTRAS = "receiverExtras";
+    /** @hide */
+    public static final String KEY_AUTO_FILL_CALLBACK = "autoFillCallback";
 
     final Context mContext;
     final HandlerCaller mHandlerCaller;
diff --git a/core/java/android/util/Half.java b/core/java/android/util/Half.java
index 08fb948..1abc10d 100644
--- a/core/java/android/util/Half.java
+++ b/core/java/android/util/Half.java
@@ -16,12 +16,15 @@
 
 package android.util;
 
+import android.annotation.HalfFloat;
+
 /**
  * <p>Half is a utility class to manipulate half-precision 16-bit
  * <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">IEEE 754</a>
- * floating point data types (also called fp16 or binary16). A half-precision
- * float is stored in a short data type. A half-precision float can be
- * created from or converted to single-precision floats.</p>
+ * floating point data types (also called fp16 or binary16). A half-precision float can be
+ * created from or converted to single-precision floats, and is stored in a short data type.
+ * To distinguish short values holding half-precision floats from regular short values,
+ * it is recommended to use the <code>@HalfFloat</code> annotation.</p>
  *
  * <p>The IEEE 754 standard specifies an fp16 as having the following format:</p>
  * <ul>
@@ -95,51 +98,53 @@
      * Epsilon is the difference between 1.0 and the next value representable
      * by a half-precision floating-point.
      */
-    public static final short EPSILON            = (short) 0x1400;
-    /**
-     * Smallest negative value a half-precision float may have.
-     */
-    public static final short LOWEST_VALUE       = (short) 0xfbff;
+    public static final @HalfFloat short EPSILON = (short) 0x1400;
+
     /**
      * Maximum exponent a finite half-precision float may have.
      */
-    public static final int MAX_EXPONENT         = 15;
-    /**
-     * Maximum positive finite value a half-precision float may have.
-     */
-    public static final short MAX_VALUE          = (short) 0x7bff;
+    public static final int MAX_EXPONENT = 15;
     /**
      * Minimum exponent a normalized half-precision float may have.
      */
-    public static final int MIN_EXPONENT         = -14;
+    public static final int MIN_EXPONENT = -14;
+
+    /**
+     * Smallest negative value a half-precision float may have.
+     */
+    public static final @HalfFloat short LOWEST_VALUE = (short) 0xfbff;
+    /**
+     * Maximum positive finite value a half-precision float may have.
+     */
+    public static final @HalfFloat short MAX_VALUE = (short) 0x7bff;
     /**
      * Smallest positive normal value a half-precision float may have.
      */
-    public static final short MIN_NORMAL         = (short) 0x0400;
+    public static final @HalfFloat short MIN_NORMAL = (short) 0x0400;
     /**
      * Smallest positive non-zero value a half-precision float may have.
      */
-    public static final short MIN_VALUE          = (short) 0x0001;
+    public static final @HalfFloat short MIN_VALUE = (short) 0x0001;
     /**
      * A Not-a-Number representation of a half-precision float.
      */
-    public static final short NaN                = (short) 0x7e00;
+    public static final @HalfFloat short NaN = (short) 0x7e00;
     /**
      * Negative infinity of type half-precision float.
      */
-    public static final short NEGATIVE_INFINITY  = (short) 0xfc00;
+    public static final @HalfFloat short NEGATIVE_INFINITY = (short) 0xfc00;
     /**
      * Negative 0 of type half-precision float.
      */
-    public static final short NEGATIVE_ZERO      = (short) 0x8000;
+    public static final @HalfFloat short NEGATIVE_ZERO = (short) 0x8000;
     /**
      * Positive infinity of type half-precision float.
      */
-    public static final short POSITIVE_INFINITY  = (short) 0x7c00;
+    public static final @HalfFloat short POSITIVE_INFINITY = (short) 0x7c00;
     /**
      * Positive 0 of type half-precision float.
      */
-    public static final short POSITIVE_ZERO      = (short) 0x0000;
+    public static final @HalfFloat short POSITIVE_ZERO = (short) 0x0000;
 
     private static final int FP16_SIGN_SHIFT        = 15;
     private static final int FP16_SIGN_MASK         = 0x8000;
@@ -171,7 +176,7 @@
      * @return A value with the magnitude of the first parameter and the sign
      *         of the second parameter
      */
-    public static short copySign(short magnitude, short sign) {
+    public static @HalfFloat short copySign(@HalfFloat short magnitude, @HalfFloat short sign) {
         return (short) ((sign & FP16_SIGN_MASK) | (magnitude & FP16_COMBINED));
     }
 
@@ -189,7 +194,7 @@
      * @param h A half-precision float value
      * @return The absolute value of the specified half-precision float
      */
-    public static short abs(short h) {
+    public static @HalfFloat short abs(@HalfFloat short h) {
         return (short) (h & FP16_COMBINED);
     }
 
@@ -209,7 +214,7 @@
      * @return The value of the specified half-precision float rounded to the nearest
      *         half-precision float value
      */
-    public static short round(short h) {
+    public static @HalfFloat short round(@HalfFloat short h) {
         int bits = h & 0xffff;
         int e = bits & 0x7fff;
         int result = bits;
@@ -243,7 +248,7 @@
      * @return The smallest half-precision float value toward negative infinity
      *         greater than or equal to the specified half-precision float value
      */
-    public static short ceil(short h) {
+    public static @HalfFloat short ceil(@HalfFloat short h) {
         int bits = h & 0xffff;
         int e = bits & 0x7fff;
         int result = bits;
@@ -277,7 +282,7 @@
      * @return The largest half-precision float value toward positive infinity
      *         less than or equal to the specified half-precision float value
      */
-    public static short floor(short h) {
+    public static @HalfFloat short floor(@HalfFloat short h) {
         int bits = h & 0xffff;
         int e = bits & 0x7fff;
         int result = bits;
@@ -310,7 +315,7 @@
      * @return The truncated half-precision float value of the specified
      *         half-precision float value
      */
-    public static short trunc(short h) {
+    public static @HalfFloat short trunc(@HalfFloat short h) {
         int bits = h & 0xffff;
         int e = bits & 0x7fff;
         int result = bits;
@@ -338,7 +343,7 @@
      * @param y The second half-precision value
      * @return The smaller of the two specified half-precision values
      */
-    public static short min(short x, short y) {
+    public static @HalfFloat short min(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return NaN;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return NaN;
 
@@ -363,7 +368,7 @@
      *
      * @return The larger of the two specified half-precision values
      */
-    public static short max(short x, short y) {
+    public static @HalfFloat short max(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return NaN;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return NaN;
 
@@ -385,7 +390,7 @@
      *
      * @return True if x is less than y, false otherwise
      */
-    public static boolean less(short x, short y) {
+    public static boolean less(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
 
@@ -403,7 +408,7 @@
      *
      * @return True if x is less than or equal to y, false otherwise
      */
-    public static boolean lessEquals(short x, short y) {
+    public static boolean lessEquals(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
 
@@ -421,7 +426,7 @@
      *
      * @return True if x is greater than y, false otherwise
      */
-    public static boolean greater(short x, short y) {
+    public static boolean greater(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
 
@@ -439,7 +444,7 @@
      *
      * @return True if x is greater than y, false otherwise
      */
-    public static boolean greaterEquals(short x, short y) {
+    public static boolean greaterEquals(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
 
@@ -457,7 +462,7 @@
      *
      * @return True if x is equal to y, false otherwise
      */
-    public static boolean equals(short x, short y) {
+    public static boolean equals(@HalfFloat short x, @HalfFloat short y) {
         if ((x & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
         if ((y & FP16_COMBINED) > FP16_EXPONENT_MAX) return false;
 
@@ -470,7 +475,7 @@
      * @param h A half-precision float value
      * @return 1 if the value is positive, -1 if the value is negative
      */
-    public static int getSign(short h) {
+    public static int getSign(@HalfFloat short h) {
         return (h & FP16_SIGN_MASK) == 0 ? 1 : -1;
     }
 
@@ -484,7 +489,7 @@
      * @param h A half-precision float value
      * @return The unbiased exponent of the specified value
      */
-    public static int getExponent(short h) {
+    public static int getExponent(@HalfFloat short h) {
         return ((h >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK) - FP16_EXPONENT_BIAS;
     }
 
@@ -495,7 +500,7 @@
      * @param h A half-precision float value
      * @return The significand, or significand, of the specified vlaue
      */
-    public static int getSignificand(short h) {
+    public static int getSignificand(@HalfFloat short h) {
         return h & FP16_SIGNIFICAND_MASK;
     }
 
@@ -507,7 +512,7 @@
      * @return true if the value is positive infinity or negative infinity,
      *         false otherwise
      */
-    public static boolean isInfinite(short h) {
+    public static boolean isInfinite(@HalfFloat short h) {
         return (h & FP16_COMBINED) == FP16_EXPONENT_MAX;
     }
 
@@ -518,7 +523,7 @@
      * @param h A half-precision float value
      * @return true if the value is a NaN, false otherwise
      */
-    public static boolean isNaN(short h) {
+    public static boolean isNaN(@HalfFloat short h) {
         return (h & FP16_COMBINED) > FP16_EXPONENT_MAX;
     }
 
@@ -532,7 +537,7 @@
      * @param h A half-precision float value
      * @return true if the value is normalized, false otherwise
      */
-    public static boolean isNormalized(short h) {
+    public static boolean isNormalized(@HalfFloat short h) {
         return (h & FP16_EXPONENT_MAX) != 0 && (h & FP16_EXPONENT_MAX) != FP16_EXPONENT_MAX;
     }
 
@@ -551,7 +556,7 @@
      * @param h The half-precision float value to convert to single-precision
      * @return A normalized single-precision float value
      */
-    public static float toFloat(short h) {
+    public static float toFloat(@HalfFloat short h) {
         int bits = h & 0xffff;
         int s = bits & FP16_SIGN_MASK;
         int e = (bits >>> FP16_EXPONENT_SHIFT) & FP16_EXPONENT_MASK;
@@ -603,7 +608,7 @@
      * @return A half-precision float value
      */
     @SuppressWarnings("StatementWithEmptyBody")
-    public static short valueOf(float f) {
+    public static @HalfFloat short valueOf(float f) {
         int bits = Float.floatToRawIntBits(f);
         int s = (bits >>> FP32_SIGN_SHIFT    );
         int e = (bits >>> FP32_EXPONENT_SHIFT) & FP32_EXPONENT_MASK;
@@ -653,7 +658,7 @@
      * @param h A half-precision float value
      * @return A string representation of the specified value
      */
-    public static String toString(short h) {
+    public static String toString(@HalfFloat short h) {
         return Float.toString(toFloat(h));
     }
 
@@ -683,7 +688,7 @@
      * @param h A half-precision float value
      * @return A hexadecimal string representation of the specified value
      */
-    public static String toHexString(short h) {
+    public static String toHexString(@HalfFloat short h) {
         StringBuilder o = new StringBuilder();
 
         int bits = h & 0xffff;
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/View.java b/core/java/android/view/View.java
index 441f330..02a8521 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6703,6 +6703,11 @@
         } else {
             structure.setId(id, null, null, null);
         }
+
+        // The auto-fill id needs to be unique, but its value doesn't matter, so it's better to
+        // reuse the accessibility id to save space.
+        structure.setAutoFillId(getAccessibilityViewId());
+
         structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
         if (!hasIdentityMatrix()) {
             structure.setTransformation(getMatrix());
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/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 2e4ba74..e9ff9d0 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -275,4 +275,7 @@
 
     /** @hide */
     public abstract Rect getTempRect();
+
+    /** @hide */
+    public abstract void setAutoFillId(int autoFillId);
 }
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/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 18ce260..a9268d4e 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/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/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/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_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 886c0e6..1a67cee 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -267,9 +267,9 @@
 
     const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
     if (interfaceName) {
-        String16 nameCopy(
+        String8 nameCopy = String8(String16(
                 reinterpret_cast<const char16_t *>(interfaceName),
-                env->GetStringLength(interfaceNameObj));
+                env->GetStringLength(interfaceNameObj)));
 
         env->ReleaseStringCritical(interfaceNameObj, interfaceName);
         interfaceName = NULL;
@@ -277,7 +277,7 @@
         hardware::Parcel *parcel =
             JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
-        status_t err = parcel->writeInterfaceToken(nameCopy);
+        status_t err = parcel->writeInterfaceToken(nameCopy.string());
         signalExceptionForError(env, err);
     }
 }
@@ -294,9 +294,9 @@
 
     const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
     if (interfaceName) {
-        String16 interfaceNameCopy(
+        String8 interfaceNameCopy = String8(String16(
                 reinterpret_cast<const char16_t *>(interfaceName),
-                env->GetStringLength(interfaceNameObj));
+                env->GetStringLength(interfaceNameObj)));
 
         env->ReleaseStringCritical(interfaceNameObj, interfaceName);
         interfaceName = NULL;
@@ -304,7 +304,7 @@
         hardware::Parcel *parcel =
             JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
-        bool valid = parcel->enforceInterface(interfaceNameCopy);
+        bool valid = parcel->enforceInterface(interfaceNameCopy.string());
 
         if (!valid) {
             jniThrowException(
@@ -425,8 +425,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 +453,8 @@
     if (err == OK) {                                                           \
         size_t childHandle;                                                    \
                                                                                \
-        err = vec->writeEmbeddedToParcel(                                      \
+        err = ::android::hardware::writeEmbeddedToParcel(                      \
+                *vec,                                                          \
                 parcel,                                                        \
                 parentHandle,                                                  \
                 0 /* parentOffset */,                                          \
@@ -508,7 +509,8 @@
     if (err == OK) {
         size_t childHandle;
 
-        err = vec->writeEmbeddedToParcel(
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *vec,
                 parcel,
                 parentHandle,
                 0 /* parentOffset */,
@@ -568,7 +570,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 +600,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 +642,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 +704,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 +764,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/fd_utils-inl.h b/core/jni/fd_utils-inl.h
index 2babe44..e270911 100644
--- a/core/jni/fd_utils-inl.h
+++ b/core/jni/fd_utils-inl.h
@@ -241,6 +241,18 @@
     is_sock(false) {
   }
 
+  static bool StartsWith(const std::string& str, const std::string& prefix) {
+    return str.compare(0, prefix.size(), prefix) == 0;
+  }
+
+  static bool EndsWith(const std::string& str, const std::string& suffix) {
+    if (suffix.size() > str.size()) {
+      return false;
+    }
+
+    return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+  }
+
   // Returns true iff. a given path is whitelisted. A path is whitelisted
   // if it belongs to the whitelist (see kPathWhitelist) or if it's a path
   // under /system/framework that ends with ".jar" or if it is a system
@@ -252,31 +264,42 @@
       }
     }
 
-    static const char* kFrameworksPrefix = "/system/framework/";
-    static const char* kJarSuffix = ".jar";
-    if (android::base::StartsWith(path, kFrameworksPrefix)
-        && android::base::EndsWith(path, kJarSuffix)) {
+    static const std::string kFrameworksPrefix = "/system/framework/";
+    static const std::string kJarSuffix = ".jar";
+    if (StartsWith(path, kFrameworksPrefix) && EndsWith(path, kJarSuffix)) {
       return true;
     }
 
     // Whitelist files needed for Runtime Resource Overlay, like these:
+    // /system/vendor/overlay/framework-res.apk
+    // /system/vendor/overlay-subdir/pg/framework-res.apk
     // /vendor/overlay/framework-res.apk
     // /vendor/overlay/PG/android-framework-runtime-resource-overlay.apk
     // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap
-    // /data/resource-cache/system@vendor@overlay@PG@framework-res.apk@idmap
-    static const char* kOverlayDir = "/vendor/overlay/";
-    static const char* kApkSuffix = ".apk";
+    // /data/resource-cache/system@vendor@overlay-subdir@pg@framework-res.apk@idmap
+    // See AssetManager.cpp for more details on overlay-subdir.
+    static const std::string kOverlayDir = "/system/vendor/overlay/";
+    static const std::string kVendorOverlayDir = "/vendor/overlay";
+    static const std::string kOverlaySubdir = "/system/vendor/overlay-subdir/";
+    static const std::string kApkSuffix = ".apk";
 
-    if (android::base::StartsWith(path, kOverlayDir)
-        && android::base::EndsWith(path, kApkSuffix)
+    if ((StartsWith(path, kOverlayDir) || StartsWith(path, kOverlaySubdir)
+         || StartsWith(path, kVendorOverlayDir))
+        && EndsWith(path, kApkSuffix)
         && path.find("/../") == std::string::npos) {
       return true;
     }
 
-    static const char* kOverlayIdmapPrefix = "/data/resource-cache/";
-    static const char* kOverlayIdmapSuffix = ".apk@idmap";
-    if (android::base::StartsWith(path, kOverlayIdmapPrefix)
-        && android::base::EndsWith(path, kOverlayIdmapSuffix)) {
+    static const std::string kOverlayIdmapPrefix = "/data/resource-cache/";
+    static const std::string kOverlayIdmapSuffix = ".apk@idmap";
+    if (StartsWith(path, kOverlayIdmapPrefix) && EndsWith(path, kOverlayIdmapSuffix)
+        && path.find("/../") == std::string::npos) {
+      return true;
+    }
+
+    // All regular files that are placed under this path are whitelisted automatically.
+    static const std::string kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
+    if (StartsWith(path, kZygoteWhitelistPath) && path.find("/../") == std::string::npos) {
       return true;
     }
 
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/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-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 13218b7..9c26340 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1333,7 +1333,7 @@
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Tik voor gebruik en instellingen"</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Gegevenslimiet van 2G-3G bereikt"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Gegevenslimiet van 4G bereikt"</string>
-    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Mobiele gegevenslimiet bereikt"</string>
+    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Mobiele datalimiet bereikt"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wifi-gegevenslimiet bereikt"</string>
     <string name="data_usage_limit_body" msgid="291731708279614081">"Gegev. onderbr. voor rest cyclus"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Gegevenslimiet 2G-3G overschreden"</string>
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/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 8dc502a..4722050 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -40,6 +40,7 @@
     renderthread/OpenGLPipeline.cpp \
     renderthread/DrawFrameTask.cpp \
     renderthread/EglManager.cpp \
+    renderthread/VulkanManager.cpp \
     renderthread/RenderProxy.cpp \
     renderthread/RenderTask.cpp \
     renderthread/RenderThread.cpp \
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index b8f7d9f..2077b0e 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()) {
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/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index dca78b3..37126a6 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -18,6 +18,7 @@
     libutils \
     libEGL \
     libGLESv2 \
+    libvulkan \
     libskia \
     libui \
     libgui \
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index ba13ca5..ca394b2 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -23,37 +23,43 @@
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 
+#include <SkSurface.h>
 #include <SkTypes.h>
-#include <WindowContextFactory_android.h>
-#include <VulkanWindowContext.h>
+
+#include <GrContext.h>
+#include <GrTypes.h>
+#include <vk/GrVkTypes.h>
 
 #include <android/native_window.h>
 #include <cutils/properties.h>
 #include <strings.h>
 
 using namespace android::uirenderer::renderthread;
-using namespace sk_app;
 
 namespace android {
 namespace uirenderer {
 namespace skiapipeline {
 
+SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread)
+        : SkiaPipeline(thread)
+        , mVkManager(thread.vulkanManager()) {}
+
 MakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
-    return (mWindowContext != nullptr) ?
-        MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed;
+    return MakeCurrentResult::AlreadyCurrent;
 }
 
 Frame SkiaVulkanPipeline::getFrame() {
-    LOG_ALWAYS_FATAL_IF(mWindowContext == nullptr, "Tried to draw into null vulkan context!");
-    mBackbuffer = mWindowContext->getBackbufferSurface();
-    if (mBackbuffer.get() == nullptr) {
-        // try recreating the context?
+    LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr,
+                "drawRenderNode called on a context with no surface!");
+
+    SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface);
+    if (backBuffer == nullptr) {
         SkDebugf("failed to get backbuffer");
         return Frame(-1, -1, 0);
     }
 
     // TODO: support buffer age if Vulkan API can do it
-    Frame frame(mBackbuffer->width(), mBackbuffer->height(), 0);
+    Frame frame(backBuffer->width(), backBuffer->height(), 0);
     return frame;
 }
 
@@ -66,16 +72,18 @@
         const std::vector<sp<RenderNode>>& renderNodes,
         FrameInfoVisualizer* profiler) {
 
-    if (mBackbuffer.get() == nullptr) {
+    sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface();
+    if (backBuffer.get() == nullptr) {
         return false;
     }
-    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mBackbuffer);
+    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer);
     layerUpdateQueue->clear();
 
     // Draw visual debugging features
     if (CC_UNLIKELY(Properties::showDirtyRegions
             || ProfileType::None != Properties::getProfileType())) {
-        SkCanvas* profileCanvas = mBackbuffer->getCanvas();
+        SkCanvas* profileCanvas = backBuffer->getCanvas();
         SkiaProfileRenderer profileRenderer(profileCanvas);
         profiler->draw(profileRenderer);
         profileCanvas->flush();
@@ -99,11 +107,9 @@
     currentFrameInfo->markSwapBuffers();
 
     if (*requireSwap) {
-        mWindowContext->swapBuffers();
+        mVkManager.swapBuffers(mVkSurface);
     }
 
-    mBackbuffer.reset();
-
     return *requireSwap;
 }
 
@@ -113,6 +119,7 @@
 }
 
 DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
+    mVkManager.initialize();
     Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
     return new DeferredLayerUpdater(layer);
 }
@@ -121,33 +128,24 @@
 }
 
 bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
-
-    if (mWindowContext) {
-        delete mWindowContext;
-        mWindowContext = nullptr;
+    if (mVkSurface) {
+        mVkManager.destroySurface(mVkSurface);
+        mVkSurface = nullptr;
     }
 
     if (surface) {
-        DisplayParams displayParams;
-        mWindowContext = window_context_factory::NewVulkanForAndroid(surface, displayParams);
-        if (mWindowContext) {
-            DeviceInfo::initialize(mWindowContext->getGrContext()->caps()->maxRenderTargetSize());
-        }
+        mVkSurface = mVkManager.createSurface(surface);
     }
 
-
-    // this doesn't work for if there is more than one CanvasContext available at one time!
-    mRenderThread.setGrContext(mWindowContext ? mWindowContext->getGrContext() : nullptr);
-
-    return mWindowContext != nullptr;
+    return mVkSurface != nullptr;
 }
 
 bool SkiaVulkanPipeline::isSurfaceReady() {
-    return CC_LIKELY(mWindowContext != nullptr) && mWindowContext->isValid();
+    return CC_UNLIKELY(mVkSurface != nullptr);
 }
 
 bool SkiaVulkanPipeline::isContextReady() {
-    return CC_LIKELY(mWindowContext != nullptr);
+    return CC_LIKELY(mVkManager.hasVkContext());
 }
 
 void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index cdc8692..aab1d7a 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -17,11 +17,7 @@
 #pragma once
 
 #include "SkiaPipeline.h"
-#include <SkSurface.h>
-
-namespace sk_app {
-class WindowContext;
-}
+#include "renderthread/VulkanManager.h"
 
 namespace android {
 namespace uirenderer {
@@ -29,7 +25,7 @@
 
 class SkiaVulkanPipeline : public SkiaPipeline {
 public:
-    SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {}
+    SkiaVulkanPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaVulkanPipeline() {}
 
     renderthread::MakeCurrentResult makeCurrent() override;
@@ -53,8 +49,8 @@
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
 
 private:
-    sk_app::WindowContext* mWindowContext = nullptr;
-    sk_sp<SkSurface> mBackbuffer;
+    renderthread::VulkanManager& mVkManager;
+    renderthread::VulkanSurface* mVkSurface = nullptr;
 };
 
 } /* namespace skiapipeline */
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 9688340..f3789c8 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -20,6 +20,7 @@
 #include "CanvasContext.h"
 #include "EglManager.h"
 #include "RenderProxy.h"
+#include "VulkanManager.h"
 
 #include <gui/DisplayEventReceiver.h>
 #include <gui/ISurfaceComposer.h>
@@ -157,7 +158,8 @@
         , mFrameCallbackTaskPending(false)
         , mFrameCallbackTask(nullptr)
         , mRenderState(nullptr)
-        , mEglManager(nullptr) {
+        , mEglManager(nullptr)
+        , mVkManager(nullptr) {
     Properties::load();
     mFrameCallbackTask = new DispatchFrameCallbacks(this);
     mLooper = new Looper(false);
@@ -191,6 +193,7 @@
     mEglManager = new EglManager(*this);
     mRenderState = new RenderState(*this);
     mJankTracker = new JankTracker(mDisplayInfo);
+    mVkManager = new VulkanManager(*this);
 }
 
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index d8677e13..12050dd 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -46,6 +46,7 @@
 class DispatchFrameCallbacks;
 class EglManager;
 class RenderProxy;
+class VulkanManager;
 
 class TaskQueue {
 public:
@@ -98,6 +99,8 @@
     GrContext* getGrContext() const { return mGrContext.get(); }
     void setGrContext(GrContext* cxt) { mGrContext.reset(cxt); }
 
+    VulkanManager& vulkanManager() { return *mVkManager; }
+
 protected:
     virtual bool threadLoop() override;
 
@@ -150,6 +153,7 @@
     JankTracker* mJankTracker = nullptr;
 
     sk_sp<GrContext> mGrContext;
+    VulkanManager* mVkManager;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
new file mode 100644
index 0000000..4d239bc
--- /dev/null
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -0,0 +1,675 @@
+/*
+ * 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 "VulkanManager.h"
+
+#include "DeviceInfo.h"
+#include "RenderThread.h"
+
+#include <GrContext.h>
+#include <GrTypes.h>
+#include <vk/GrVkTypes.h>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+#define GET_PROC(F) m ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F)
+#define GET_DEV_PROC(F) m ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F)
+
+VulkanManager::VulkanManager(RenderThread& thread) : mRenderThread(thread) {
+}
+
+void VulkanManager::destroy() {
+    if (!hasVkContext()) return;
+
+    if (VK_NULL_HANDLE != mCommandPool) {
+        mDestroyCommandPool(mBackendContext->fDevice, mCommandPool, nullptr);
+        mCommandPool = VK_NULL_HANDLE;
+    }
+}
+
+void VulkanManager::initialize() {
+    if (hasVkContext()) { return; }
+
+    auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
+
+    mBackendContext.reset(GrVkBackendContext::Create(&mPresentQueueIndex, canPresent));
+
+    // Get all the addresses of needed vulkan functions
+    VkInstance instance = mBackendContext->fInstance;
+    VkDevice device = mBackendContext->fDevice;
+    GET_PROC(CreateAndroidSurfaceKHR);
+    GET_PROC(DestroySurfaceKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
+    GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
+    GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
+    GET_DEV_PROC(CreateSwapchainKHR);
+    GET_DEV_PROC(DestroySwapchainKHR);
+    GET_DEV_PROC(GetSwapchainImagesKHR);
+    GET_DEV_PROC(AcquireNextImageKHR);
+    GET_DEV_PROC(QueuePresentKHR);
+    GET_DEV_PROC(CreateCommandPool);
+    GET_DEV_PROC(DestroyCommandPool);
+    GET_DEV_PROC(AllocateCommandBuffers);
+    GET_DEV_PROC(FreeCommandBuffers);
+    GET_DEV_PROC(ResetCommandBuffer);
+    GET_DEV_PROC(BeginCommandBuffer);
+    GET_DEV_PROC(EndCommandBuffer);
+    GET_DEV_PROC(CmdPipelineBarrier);
+    GET_DEV_PROC(GetDeviceQueue);
+    GET_DEV_PROC(QueueSubmit);
+    GET_DEV_PROC(QueueWaitIdle);
+    GET_DEV_PROC(DeviceWaitIdle);
+    GET_DEV_PROC(CreateSemaphore);
+    GET_DEV_PROC(DestroySemaphore);
+    GET_DEV_PROC(CreateFence);
+    GET_DEV_PROC(DestroyFence);
+    GET_DEV_PROC(WaitForFences);
+    GET_DEV_PROC(ResetFences);
+
+    // create the command pool for the command buffers
+    if (VK_NULL_HANDLE == mCommandPool) {
+        VkCommandPoolCreateInfo commandPoolInfo;
+        memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
+        commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+        // this needs to be on the render queue
+        commandPoolInfo.queueFamilyIndex = mBackendContext->fGraphicsQueueIndex;
+        commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+        SkDEBUGCODE(VkResult res =) mCreateCommandPool(mBackendContext->fDevice,
+                &commandPoolInfo, nullptr, &mCommandPool);
+        SkASSERT(VK_SUCCESS == res);
+    }
+
+    mGetDeviceQueue(mBackendContext->fDevice, mPresentQueueIndex, 0, &mPresentQueue);
+
+    mRenderThread.setGrContext(GrContext::Create(kVulkan_GrBackend,
+            (GrBackendContext) mBackendContext.get()));
+    DeviceInfo::initialize(mRenderThread.getGrContext()->caps()->maxRenderTargetSize());
+}
+
+// Returns the next BackbufferInfo to use for the next draw. The function will make sure all
+// previous uses have finished before returning.
+VulkanSurface::BackbufferInfo* VulkanManager::getAvailableBackbuffer(VulkanSurface* surface) {
+    SkASSERT(surface->mBackbuffers);
+
+    ++surface->mCurrentBackbufferIndex;
+    if (surface->mCurrentBackbufferIndex > surface->mImageCount) {
+        surface->mCurrentBackbufferIndex = 0;
+    }
+
+    VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers +
+            surface->mCurrentBackbufferIndex;
+
+    // Before we reuse a backbuffer, make sure its fences have all signaled so that we can safely
+    // reuse its commands buffers.
+    VkResult res = mWaitForFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences,
+            true, UINT64_MAX);
+    if (res != VK_SUCCESS) {
+        return nullptr;
+    }
+
+    return backbuffer;
+}
+
+
+SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface* surface) {
+    VulkanSurface::BackbufferInfo* backbuffer = getAvailableBackbuffer(surface);
+    SkASSERT(backbuffer);
+
+    VkResult res;
+
+    res = mResetFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences);
+    SkASSERT(VK_SUCCESS == res);
+
+    // The acquire will signal the attached mAcquireSemaphore. We use this to know the image has
+    // finished presenting and that it is safe to begin sending new commands to the returned image.
+    res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX,
+            backbuffer->mAcquireSemaphore, VK_NULL_HANDLE, &backbuffer->mImageIndex);
+
+    if (VK_ERROR_SURFACE_LOST_KHR == res) {
+        // need to figure out how to create a new vkSurface without the platformData*
+        // maybe use attach somehow? but need a Window
+        return nullptr;
+    }
+    if (VK_ERROR_OUT_OF_DATE_KHR == res) {
+        // tear swapchain down and try again
+        if (!createSwapchain(surface)) {
+            return nullptr;
+        }
+
+        // acquire the image
+        res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX,
+                backbuffer->mAcquireSemaphore, VK_NULL_HANDLE, &backbuffer->mImageIndex);
+
+        if (VK_SUCCESS != res) {
+            return nullptr;
+        }
+    }
+
+    // set up layout transfer from initial to color attachment
+    VkImageLayout layout = surface->mImageLayouts[backbuffer->mImageIndex];
+    SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout || VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout);
+    VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
+                                        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT :
+                                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkAccessFlags srcAccessMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout) ?
+                                  0 : VK_ACCESS_MEMORY_READ_BIT;
+    VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+    VkImageMemoryBarrier imageMemoryBarrier = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,    // sType
+        NULL,                                      // pNext
+        srcAccessMask,                             // outputMask
+        dstAccessMask,                             // inputMask
+        layout,                                    // oldLayout
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,  // newLayout
+        mPresentQueueIndex,                        // srcQueueFamilyIndex
+        mBackendContext->fGraphicsQueueIndex,      // dstQueueFamilyIndex
+        surface->mImages[backbuffer->mImageIndex], // image
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }  // subresourceRange
+    };
+    mResetCommandBuffer(backbuffer->mTransitionCmdBuffers[0], 0);
+
+    VkCommandBufferBeginInfo info;
+    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.flags = 0;
+    mBeginCommandBuffer(backbuffer->mTransitionCmdBuffers[0], &info);
+
+    mCmdPipelineBarrier(backbuffer->mTransitionCmdBuffers[0], srcStageMask, dstStageMask, 0,
+            0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
+
+    mEndCommandBuffer(backbuffer->mTransitionCmdBuffers[0]);
+
+    VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    // insert the layout transfer into the queue and wait on the acquire
+    VkSubmitInfo submitInfo;
+    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.waitSemaphoreCount = 1;
+    // Wait to make sure aquire semaphore set above has signaled.
+    submitInfo.pWaitSemaphores = &backbuffer->mAcquireSemaphore;
+    submitInfo.pWaitDstStageMask = &waitDstStageFlags;
+    submitInfo.commandBufferCount = 1;
+    submitInfo.pCommandBuffers = &backbuffer->mTransitionCmdBuffers[0];
+    submitInfo.signalSemaphoreCount = 0;
+
+    // Attach first fence to submission here so we can track when the command buffer finishes.
+    mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[0]);
+
+    // We need to notify Skia that we changed the layout of the wrapped VkImage
+    GrVkImageInfo* imageInfo;
+    sk_sp<SkSurface> skSurface = surface->mSurfaces[backbuffer->mImageIndex];
+    skSurface->getRenderTargetHandle((GrBackendObject*)&imageInfo,
+            SkSurface::kFlushRead_BackendHandleAccess);
+    imageInfo->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+
+    surface->mBackbuffer = std::move(skSurface);
+    return surface->mBackbuffer.get();
+}
+
+void VulkanManager::destroyBuffers(VulkanSurface* surface) {
+    if (surface->mBackbuffers) {
+        for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) {
+            mWaitForFences(mBackendContext->fDevice, 2, surface->mBackbuffers[i].mUsageFences, true,
+                    UINT64_MAX);
+            surface->mBackbuffers[i].mImageIndex = -1;
+            mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mAcquireSemaphore,
+                    nullptr);
+            mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mRenderSemaphore,
+                    nullptr);
+            mFreeCommandBuffers(mBackendContext->fDevice, mCommandPool, 2,
+                    surface->mBackbuffers[i].mTransitionCmdBuffers);
+            mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[0], 0);
+            mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[1], 0);
+        }
+    }
+
+    delete[] surface->mBackbuffers;
+    surface->mBackbuffers = nullptr;
+    delete[] surface->mSurfaces;
+    surface->mSurfaces = nullptr;
+    delete[] surface->mImageLayouts;
+    surface->mImageLayouts = nullptr;
+    delete[] surface->mImages;
+    surface->mImages = nullptr;
+}
+
+void VulkanManager::destroySurface(VulkanSurface* surface) {
+    // Make sure all submit commands have finished before starting to destroy objects.
+    if (VK_NULL_HANDLE != mPresentQueue) {
+        mQueueWaitIdle(mPresentQueue);
+    }
+    mDeviceWaitIdle(mBackendContext->fDevice);
+
+    destroyBuffers(surface);
+
+    if (VK_NULL_HANDLE != surface->mSwapchain) {
+        mDestroySwapchainKHR(mBackendContext->fDevice, surface->mSwapchain, nullptr);
+        surface->mSwapchain = VK_NULL_HANDLE;
+    }
+
+    if (VK_NULL_HANDLE != surface->mVkSurface) {
+        mDestroySurfaceKHR(mBackendContext->fInstance, surface->mVkSurface, nullptr);
+        surface->mVkSurface = VK_NULL_HANDLE;
+    }
+    delete surface;
+}
+
+void VulkanManager::createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent) {
+    mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain, &surface->mImageCount,
+            nullptr);
+    SkASSERT(surface->mImageCount);
+    surface->mImages = new VkImage[surface->mImageCount];
+    mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain,
+            &surface->mImageCount, surface->mImages);
+
+    SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+
+    bool wantSRGB = VK_FORMAT_R8G8B8A8_SRGB == format;
+    GrPixelConfig config = wantSRGB ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
+
+    // set up initial image layouts and create surfaces
+    surface->mImageLayouts = new VkImageLayout[surface->mImageCount];
+    surface->mSurfaces = new sk_sp<SkSurface>[surface->mImageCount];
+    for (uint32_t i = 0; i < surface->mImageCount; ++i) {
+        GrBackendRenderTargetDesc desc;
+        GrVkImageInfo info;
+        info.fImage = surface->mImages[i];
+        info.fAlloc = { VK_NULL_HANDLE, 0, 0, 0 };
+        info.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+        info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
+        info.fFormat = format;
+        info.fLevelCount = 1;
+
+        desc.fWidth = extent.width;
+        desc.fHeight = extent.height;
+        desc.fConfig = config;
+        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
+        desc.fSampleCnt = 0;
+        desc.fStencilBits = 0;
+        desc.fRenderTargetHandle = (GrBackendObject) &info;
+
+        surface->mSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(mRenderThread.getGrContext(),
+                desc, &props);
+        surface->mImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
+    }
+
+    SkASSERT(mCommandPool != VK_NULL_HANDLE);
+
+    // set up the backbuffers
+    VkSemaphoreCreateInfo semaphoreInfo;
+    memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
+    semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    semaphoreInfo.pNext = nullptr;
+    semaphoreInfo.flags = 0;
+    VkCommandBufferAllocateInfo commandBuffersInfo;
+    memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo));
+    commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    commandBuffersInfo.pNext = nullptr;
+    commandBuffersInfo.commandPool = mCommandPool;
+    commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    commandBuffersInfo.commandBufferCount = 2;
+    VkFenceCreateInfo fenceInfo;
+    memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
+    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fenceInfo.pNext = nullptr;
+    fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
+
+    // we create one additional backbuffer structure here, because we want to
+    // give the command buffers they contain a chance to finish before we cycle back
+    surface->mBackbuffers = new VulkanSurface::BackbufferInfo[surface->mImageCount + 1];
+    for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) {
+        SkDEBUGCODE(VkResult res);
+        surface->mBackbuffers[i].mImageIndex = -1;
+        SkDEBUGCODE(res = ) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr,
+                &surface->mBackbuffers[i].mAcquireSemaphore);
+        SkDEBUGCODE(res = ) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr,
+                &surface->mBackbuffers[i].mRenderSemaphore);
+        SkDEBUGCODE(res = ) mAllocateCommandBuffers(mBackendContext->fDevice, &commandBuffersInfo,
+                surface->mBackbuffers[i].mTransitionCmdBuffers);
+        SkDEBUGCODE(res = ) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr,
+                &surface->mBackbuffers[i].mUsageFences[0]);
+        SkDEBUGCODE(res = ) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr,
+                &surface->mBackbuffers[i].mUsageFences[1]);
+        SkASSERT(VK_SUCCESS == res);
+    }
+    surface->mCurrentBackbufferIndex = surface->mImageCount;
+}
+
+bool VulkanManager::createSwapchain(VulkanSurface* surface) {
+    // check for capabilities
+    VkSurfaceCapabilitiesKHR caps;
+    VkResult res = mGetPhysicalDeviceSurfaceCapabilitiesKHR(mBackendContext->fPhysicalDevice,
+            surface->mVkSurface, &caps);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    uint32_t surfaceFormatCount;
+    res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface,
+            &surfaceFormatCount, nullptr);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
+    VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
+    res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface,
+            &surfaceFormatCount, surfaceFormats);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    uint32_t presentModeCount;
+    res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice,
+            surface->mVkSurface, &presentModeCount, nullptr);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
+    VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
+    res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice,
+            surface->mVkSurface, &presentModeCount, presentModes);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    VkExtent2D extent = caps.currentExtent;
+    // clamp width; to handle currentExtent of -1 and  protect us from broken hints
+    if (extent.width < caps.minImageExtent.width) {
+        extent.width = caps.minImageExtent.width;
+    }
+    SkASSERT(extent.width <= caps.maxImageExtent.width);
+    // clamp height
+    if (extent.height < caps.minImageExtent.height) {
+        extent.height = caps.minImageExtent.height;
+    }
+    SkASSERT(extent.height <= caps.maxImageExtent.height);
+
+    uint32_t imageCount = caps.minImageCount + 2;
+    if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
+        // Application must settle for fewer images than desired:
+        imageCount = caps.maxImageCount;
+    }
+
+    // Currently Skia requires the images to be color attchments and support all transfer
+    // operations.
+    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
+    SkASSERT(caps.supportedTransforms & caps.currentTransform);
+    SkASSERT(caps.supportedCompositeAlpha & (VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR |
+                                             VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR));
+    VkCompositeAlphaFlagBitsKHR composite_alpha =
+        (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
+                                        VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR :
+                                        VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+
+    // Pick our surface format. For now, just make sure it matches our sRGB request:
+    VkFormat surfaceFormat = VK_FORMAT_UNDEFINED;
+    VkColorSpaceKHR colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
+
+    bool wantSRGB = false;
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+    wantSRGB = true;
+#endif
+    for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
+        // We are assuming we can get either R8G8B8A8_UNORM or R8G8B8A8_SRGB
+        VkFormat desiredFormat = wantSRGB ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
+        if (desiredFormat == surfaceFormats[i].format) {
+            surfaceFormat = surfaceFormats[i].format;
+            colorSpace = surfaceFormats[i].colorSpace;
+        }
+    }
+
+    if (VK_FORMAT_UNDEFINED == surfaceFormat) {
+        return false;
+    }
+
+    // If mailbox mode is available, use it, as it is the lowest-latency non-
+    // tearing mode. If not, fall back to FIFO which is always available.
+    VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
+    for (uint32_t i = 0; i < presentModeCount; ++i) {
+        // use mailbox
+        if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
+            mode = presentModes[i];
+            break;
+        }
+    }
+
+    VkSwapchainCreateInfoKHR swapchainCreateInfo;
+    memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
+    swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+    swapchainCreateInfo.surface = surface->mVkSurface;
+    swapchainCreateInfo.minImageCount = imageCount;
+    swapchainCreateInfo.imageFormat = surfaceFormat;
+    swapchainCreateInfo.imageColorSpace = colorSpace;
+    swapchainCreateInfo.imageExtent = extent;
+    swapchainCreateInfo.imageArrayLayers = 1;
+    swapchainCreateInfo.imageUsage = usageFlags;
+
+    uint32_t queueFamilies[] = { mBackendContext->fGraphicsQueueIndex, mPresentQueueIndex };
+    if (mBackendContext->fGraphicsQueueIndex != mPresentQueueIndex) {
+        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+        swapchainCreateInfo.queueFamilyIndexCount = 2;
+        swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
+    } else {
+        swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        swapchainCreateInfo.queueFamilyIndexCount = 0;
+        swapchainCreateInfo.pQueueFamilyIndices = nullptr;
+    }
+
+    swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+    swapchainCreateInfo.compositeAlpha = composite_alpha;
+    swapchainCreateInfo.presentMode = mode;
+    swapchainCreateInfo.clipped = true;
+    swapchainCreateInfo.oldSwapchain = surface->mSwapchain;
+
+    res = mCreateSwapchainKHR(mBackendContext->fDevice, &swapchainCreateInfo, nullptr,
+            &surface->mSwapchain);
+    if (VK_SUCCESS != res) {
+        return false;
+    }
+
+    // destroy the old swapchain
+    if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
+        mDeviceWaitIdle(mBackendContext->fDevice);
+
+        destroyBuffers(surface);
+
+        mDestroySwapchainKHR(mBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
+    }
+
+    createBuffers(surface, surfaceFormat, extent);
+
+    return true;
+}
+
+
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window) {
+    initialize();
+
+    if (!window) {
+        return nullptr;
+    }
+
+    VulkanSurface* surface = new VulkanSurface();
+
+    VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
+    memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
+    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+    surfaceCreateInfo.pNext = nullptr;
+    surfaceCreateInfo.flags = 0;
+    surfaceCreateInfo.window = window;
+
+    VkResult res = mCreateAndroidSurfaceKHR(mBackendContext->fInstance, &surfaceCreateInfo,
+            nullptr, &surface->mVkSurface);
+    if (VK_SUCCESS != res) {
+        delete surface;
+        return nullptr;
+    }
+
+SkDEBUGCODE(
+    VkBool32 supported;
+    res = mGetPhysicalDeviceSurfaceSupportKHR(mBackendContext->fPhysicalDevice,
+            mPresentQueueIndex, surface->mVkSurface, &supported);
+    // All physical devices and queue families on Android must be capable of presentation with any
+    // native window.
+    SkASSERT(VK_SUCCESS == res && supported);
+);
+
+    if (!createSwapchain(surface)) {
+        destroySurface(surface);
+        return nullptr;
+    }
+
+    return surface;
+}
+
+// Helper to know which src stage flags we need to set when transitioning to the present layout
+static VkPipelineStageFlags layoutToPipelineStageFlags(const VkImageLayout layout) {
+    if (VK_IMAGE_LAYOUT_GENERAL == layout) {
+        return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
+    } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout ||
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
+        return VK_PIPELINE_STAGE_TRANSFER_BIT;
+    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout ||
+               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout ||
+               VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout ||
+               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
+        return VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
+    } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) {
+        return VK_PIPELINE_STAGE_HOST_BIT;
+    }
+
+    SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout);
+    return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+}
+
+// Helper to know which src access mask we need to set when transitioning to the present layout
+static VkAccessFlags layoutToSrcAccessMask(const VkImageLayout layout) {
+    VkAccessFlags flags = 0;
+    if (VK_IMAGE_LAYOUT_GENERAL == layout) {
+        flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
+                VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
+                VK_ACCESS_TRANSFER_WRITE_BIT |
+                VK_ACCESS_TRANSFER_READ_BIT |
+                VK_ACCESS_SHADER_READ_BIT |
+                VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_HOST_READ_BIT;
+    } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) {
+        flags = VK_ACCESS_HOST_WRITE_BIT;
+    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) {
+        flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+    } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout) {
+        flags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
+        flags = VK_ACCESS_TRANSFER_WRITE_BIT;
+    } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout) {
+        flags = VK_ACCESS_TRANSFER_READ_BIT;
+    } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
+        flags = VK_ACCESS_SHADER_READ_BIT;
+    }
+    return flags;
+}
+
+void VulkanManager::swapBuffers(VulkanSurface* surface) {
+    VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers +
+            surface->mCurrentBackbufferIndex;
+    GrVkImageInfo* imageInfo;
+    SkSurface* skSurface = surface->mSurfaces[backbuffer->mImageIndex].get();
+    skSurface->getRenderTargetHandle((GrBackendObject*)&imageInfo,
+            SkSurface::kFlushRead_BackendHandleAccess);
+    // Check to make sure we never change the actually wrapped image
+    SkASSERT(imageInfo->fImage == surface->mImages[backbuffer->mImageIndex]);
+
+    // We need to transition the image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR and make sure that all
+    // previous work is complete for before presenting. So we first add the necessary barrier here.
+    VkImageLayout layout = imageInfo->fImageLayout;
+    VkPipelineStageFlags srcStageMask = layoutToPipelineStageFlags(layout);
+    VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+    VkAccessFlags srcAccessMask = layoutToSrcAccessMask(layout);
+    VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+
+    VkImageMemoryBarrier imageMemoryBarrier = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,    // sType
+        NULL,                                      // pNext
+        srcAccessMask,                             // outputMask
+        dstAccessMask,                             // inputMask
+        layout,                                    // oldLayout
+        VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,           // newLayout
+        mBackendContext->fGraphicsQueueIndex,      // srcQueueFamilyIndex
+        mPresentQueueIndex,                        // dstQueueFamilyIndex
+        surface->mImages[backbuffer->mImageIndex], // image
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }  // subresourceRange
+    };
+
+    mResetCommandBuffer(backbuffer->mTransitionCmdBuffers[1], 0);
+    VkCommandBufferBeginInfo info;
+    memset(&info, 0, sizeof(VkCommandBufferBeginInfo));
+    info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    info.flags = 0;
+    mBeginCommandBuffer(backbuffer->mTransitionCmdBuffers[1], &info);
+    mCmdPipelineBarrier(backbuffer->mTransitionCmdBuffers[1], srcStageMask, dstStageMask, 0,
+            0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
+    mEndCommandBuffer(backbuffer->mTransitionCmdBuffers[1]);
+
+    surface->mImageLayouts[backbuffer->mImageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+
+    // insert the layout transfer into the queue and wait on the acquire
+    VkSubmitInfo submitInfo;
+    memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submitInfo.waitSemaphoreCount = 0;
+    submitInfo.pWaitDstStageMask = 0;
+    submitInfo.commandBufferCount = 1;
+    submitInfo.pCommandBuffers = &backbuffer->mTransitionCmdBuffers[1];
+    submitInfo.signalSemaphoreCount = 1;
+    // When this command buffer finishes we will signal this semaphore so that we know it is now
+    // safe to present the image to the screen.
+    submitInfo.pSignalSemaphores = &backbuffer->mRenderSemaphore;
+
+    // Attach second fence to submission here so we can track when the command buffer finishes.
+    mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[1]);
+
+    // Submit present operation to present queue. We use a semaphore here to make sure all rendering
+    // to the image is complete and that the layout has been change to present on the graphics
+    // queue.
+    const VkPresentInfoKHR presentInfo =
+    {
+        VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType
+        NULL, // pNext
+        1, // waitSemaphoreCount
+        &backbuffer->mRenderSemaphore, // pWaitSemaphores
+        1, // swapchainCount
+        &surface->mSwapchain, // pSwapchains
+        &backbuffer->mImageIndex, // pImageIndices
+        NULL // pResults
+    };
+
+    mQueuePresentKHR(mPresentQueue, &presentInfo);
+
+    surface->mBackbuffer.reset();
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
new file mode 100644
index 0000000..f0e3320
--- /dev/null
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+#ifndef VULKANMANAGER_H
+#define VULKANMANAGER_H
+
+#include <SkSurface.h>
+#include <vk/GrVkBackendContext.h>
+
+#include <vulkan/vulkan.h>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+class RenderThread;
+
+class VulkanSurface {
+public:
+    VulkanSurface() {}
+
+    sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
+
+private:
+    friend class VulkanManager;
+    struct BackbufferInfo {
+        uint32_t        mImageIndex;          // image this is associated with
+        VkSemaphore     mAcquireSemaphore;    // we signal on this for acquisition of image
+        VkSemaphore     mRenderSemaphore;     // we wait on this for rendering to be done
+        VkCommandBuffer mTransitionCmdBuffers[2]; // to transition layout between present and render
+        // We use these fences to make sure the above Command buffers have finished their work
+        // before attempting to reuse them or destroy them.
+        VkFence         mUsageFences[2];
+    };
+
+    sk_sp<SkSurface> mBackbuffer;
+
+    VkSurfaceKHR mVkSurface = VK_NULL_HANDLE;
+    VkSwapchainKHR mSwapchain = VK_NULL_HANDLE;
+
+    BackbufferInfo* mBackbuffers;
+    uint32_t mCurrentBackbufferIndex;
+
+    uint32_t mImageCount;
+    VkImage* mImages;
+    VkImageLayout* mImageLayouts;
+    sk_sp<SkSurface>* mSurfaces;
+};
+
+// This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
+// which are re-used by CanvasContext. This class is created once and should be used by all vulkan
+// windowing contexts. The VulkanManager must be initialized before use.
+class VulkanManager {
+public:
+    // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must
+    // be call once before use of the VulkanManager. Multiple calls after the first will simiply
+    // return.
+    void initialize();
+
+    // Quick check to see if the VulkanManager has been initialized.
+    bool hasVkContext() { return mBackendContext.get() != nullptr; }
+
+    // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
+    // VulkanSurface object which is returned.
+    VulkanSurface* createSurface(ANativeWindow* window);
+
+    // Destroy the VulkanSurface and all associated vulkan objects.
+    void destroySurface(VulkanSurface* surface);
+
+    // Cleans up all the global state in the VulkanManger.
+    void destroy();
+
+    // No work is needed to make a VulkanSurface current, and all functions require that a
+    // VulkanSurface is passed into them so we just return true here.
+    bool isCurrent(VulkanSurface* surface) { return true; }
+
+    // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also
+    // will transition the VkImage from a present layout to color attachment so that it can be used
+    // by the client for drawing.
+    SkSurface* getBackbufferSurface(VulkanSurface* surface);
+
+    // Presents the current VkImage.
+    void swapBuffers(VulkanSurface* surface);
+
+private:
+    friend class RenderThread;
+
+    explicit VulkanManager(RenderThread& thread);
+    ~VulkanManager() { destroy(); }
+
+    void destroyBuffers(VulkanSurface* surface);
+
+    bool createSwapchain(VulkanSurface* surface);
+    void createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent);
+
+    VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface);
+
+    // simple wrapper class that exists only to initialize a pointer to NULL
+    template <typename FNPTR_TYPE> class VkPtr {
+    public:
+        VkPtr() : fPtr(NULL) {}
+        VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
+        operator FNPTR_TYPE() const { return fPtr; }
+    private:
+        FNPTR_TYPE fPtr;
+    };
+
+    // WSI interface functions
+    VkPtr<PFN_vkCreateAndroidSurfaceKHR> mCreateAndroidSurfaceKHR;
+    VkPtr<PFN_vkDestroySurfaceKHR> mDestroySurfaceKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> mGetPhysicalDeviceSurfaceSupportKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> mGetPhysicalDeviceSurfaceCapabilitiesKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR;
+    VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR;
+
+    VkPtr<PFN_vkCreateSwapchainKHR> mCreateSwapchainKHR;
+    VkPtr<PFN_vkDestroySwapchainKHR> mDestroySwapchainKHR;
+    VkPtr<PFN_vkGetSwapchainImagesKHR> mGetSwapchainImagesKHR;
+    VkPtr<PFN_vkAcquireNextImageKHR> mAcquireNextImageKHR;
+    VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR;
+    VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR;
+
+    // Additional vulkan functions
+    VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool;
+    VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool;
+    VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers;
+    VkPtr<PFN_vkFreeCommandBuffers> mFreeCommandBuffers;
+    VkPtr<PFN_vkResetCommandBuffer> mResetCommandBuffer;
+    VkPtr<PFN_vkBeginCommandBuffer> mBeginCommandBuffer;
+    VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer;
+    VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier;
+
+    VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue;
+    VkPtr<PFN_vkQueueSubmit> mQueueSubmit;
+    VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle;
+    VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle;
+
+    VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore;
+    VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore;
+    VkPtr<PFN_vkCreateFence> mCreateFence;
+    VkPtr<PFN_vkDestroyFence> mDestroyFence;
+    VkPtr<PFN_vkWaitForFences> mWaitForFences;
+    VkPtr<PFN_vkResetFences> mResetFences;
+
+    RenderThread& mRenderThread;
+
+    sk_sp<const GrVkBackendContext> mBackendContext;
+    uint32_t mPresentQueueIndex;
+    VkQueue mPresentQueue = VK_NULL_HANDLE;
+    VkCommandPool mCommandPool = VK_NULL_HANDLE;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* VULKANMANAGER_H */
+
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/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-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 5dcad7a..3b84313 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -168,7 +168,7 @@
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string>
     <string name="wifi_aggressive_handover" msgid="9194078645887480917">"Agressieve handover van wifi naar mobiel"</string>
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string>
-    <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobiele gegevens altijd actief"</string>
+    <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobiele data altijd actief"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
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/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index ed411be..14a0e82 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -18,6 +18,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
@@ -25,12 +26,15 @@
 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 +115,7 @@
                 mCategoryByKeyMap.put(category.key, category);
             }
             backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+            normalizePriority(context, mCategoryByKeyMap);
         }
     }
 
@@ -163,4 +168,57 @@
             }
         }
     }
+
+    /**
+     * 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());
+        }
+    }
+
+    /**
+     * 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/CategoryManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
index 380f622..50bb216 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,114 @@
         // 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);
+    }
 }
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/layout-sw600dp/recents_grid.xml b/packages/SystemUI/res/layout-sw600dp/recents_grid.xml
index c8b4fd0..cff770a 100644
--- a/packages/SystemUI/res/layout-sw600dp/recents_grid.xml
+++ b/packages/SystemUI/res/layout-sw600dp/recents_grid.xml
@@ -16,8 +16,11 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:paddingTop="24dp"
+    android:paddingBottom="54dp"
     android:orientation="vertical"
-    android:id="@+id/recents_container">
+    android:id="@+id/recents_container"
+    android:background="#99000000">
     <include layout="@layout/recents_stack_action_button" />
     <FrameLayout
         android:layout_width="match_parent"
@@ -26,7 +29,6 @@
         android:layout_marginLeft="12dp"
         android:layout_marginTop="10dp"
         android:layout_marginRight="12dp"
-        android:layout_marginBottom="5dp"
         android:gravity="center">
     </FrameLayout>
 </LinearLayout>
\ No newline at end of file
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/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 2f5358e..07966cf 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -421,7 +421,7 @@
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Սարքը կմնա արգելափակված՝ մինչև ձեռքով չբացեք"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Ավելի արագ ստացեք ծանուցումները"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Տեսեք դրանք մինչև ապակողպելը"</string>
-    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ոչ, շնորհակալություն"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ոչ"</string>
     <string name="hidden_notifications_setup" msgid="41079514801976810">"Կարգավորել"</string>
     <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="volume_zen_end_now" msgid="3179845345429841822">"Ավարտել"</string>
@@ -430,7 +430,7 @@
     <string name="screen_pinning_title" msgid="3273740381976175811">"Էկրանն ամրացված է"</string>
     <string name="screen_pinning_description" msgid="7238941806855968768">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Հետ կոճակը:"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Եղավ"</string>
-    <string name="screen_pinning_negative" msgid="3741602308343880268">"Ոչ, շնորհակալություն"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"Ոչ"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Թաքցնե՞լ <xliff:g id="TILE_LABEL">%1$s</xliff:g>-ը:"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Այն դարձյալ կհայտնվի, երբ նորից միացնեք կարգավորումներում:"</string>
     <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Թաքցնել"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7c12b5fd..8217ee5 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -235,7 +235,7 @@
     <string name="accessibility_brightness" msgid="8003681285547803095">"Helderheid van het scherm"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G/3G-data zijn onderbroken"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data zijn onderbroken"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobiele gegevens zijn onderbroken"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobiele data zijn onderbroken"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Gegevens zijn onderbroken"</string>
     <string name="data_usage_disabled_dialog" msgid="1841738975235283398">"De ingestelde datalimiet is bereikt. Je gebruikt geen mobiele data meer.\n\nAls je hervat, kunnen er kosten voor datagebruik in rekening worden gebracht."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Hervatten"</string>
@@ -310,7 +310,7 @@
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zaklamp"</string>
-    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobiele gegevens"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobiele data"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datagebruik"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Resterende gegevens"</string>
     <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Limiet overschreden"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index cc5b693..78c6102 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -652,6 +652,5 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otwórz ustawienia: <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edytuj kolejność ustawień."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <!-- no translation found for pip_phone_expand (5889780005575693909) -->
-    <skip />
+    <string name="pip_phone_expand" msgid="5889780005575693909">"Rozwiń"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ef07edc..0dbdcb9 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -650,6 +650,5 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <!-- no translation found for pip_phone_expand (5889780005575693909) -->
-    <skip />
+    <string name="pip_phone_expand" msgid="5889780005575693909">"Expandir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ef07edc..0dbdcb9 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -650,6 +650,5 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <!-- no translation found for pip_phone_expand (5889780005575693909) -->
-    <skip />
+    <string name="pip_phone_expand" msgid="5889780005575693909">"Expandir"</string>
 </resources>
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/grid/RecentsGridActivity.java b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java
index e804b52..e1e654d5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java
@@ -27,6 +27,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -94,6 +95,11 @@
         mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
 
         mRecentsView = (FrameLayout) findViewById(R.id.recents_view);
+        mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+        getWindow().getAttributes().privateFlags |=
+                WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
         LinearLayout recentsContainer = (LinearLayout) findViewById(R.id.recents_container);
         mEmptyView = (TextView) mInflater.inflate(R.layout.recents_empty, recentsContainer, false);
         mClearAllButton = findViewById(R.id.button);
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 48bc27e..9b4b186 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
@@ -2627,6 +2648,11 @@
     // ACTION: Logs the end to end time taken by all provisioning tasks.
     PROVISIONING_TOTAL_TASK_TIME_MS = 627;
 
+    // OPEN: Settings > Privacy
+    // CATEGORY: SETTINGS
+    // OS: O
+    ENTERPRISE_PRIVACY_SETTINGS = 628;
+
     // ---- 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 3b41877..d70c439 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -20,29 +20,40 @@
 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.Parcel;
+import android.os.Message;
 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;
+import android.text.format.DateUtils;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
@@ -51,6 +62,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 
 /**
  * Entry point service for auto-fill management.
@@ -62,7 +74,13 @@
 public final class AutoFillManagerService extends SystemService {
 
     private static final String TAG = "AutoFillManagerService";
-    private static final boolean DEBUG = true; // TODO: change to false once stable
+    static final boolean DEBUG = true; // TODO: change to false once stable
+
+    private static final long SERVICE_BINDING_LIFETIME_MS = 5 * DateUtils.MINUTE_IN_MILLIS;
+
+    private static final int ARG_NOT_USED = 0;
+
+    protected static final int MSG_UNBIND = 1;
 
     private final AutoFillManagerServiceStub mServiceStub;
     private final Context mContext;
@@ -70,30 +88,39 @@
 
     private final Object mLock = new Object();
 
-    @GuardedBy("mLock")
-    private boolean mSafeMode;
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UNBIND:
+                    removeStaleServiceForUser(msg.arg1);
+                    return;
+                case MSG_SHOW_ALL_NOTIFICATIONS:
+                    showAllNotifications();
+                    return;
+                default:
+                    Slog.w(TAG, "Invalid message: " + msg);
+            }
+        }
+
+    };
 
     /**
-     * Map of {@link AutoFillManagerServiceImpl} per user id.
+     * Cache of {@link AutoFillManagerServiceImpl} per user id.
      * <p>
      * It has to be mapped by user id because the same current user could have simultaneous sessions
-     * associated to different user profiles (for example, in a multi-window environment).
+     * associated to different user profiles (for example, in a multi-window environment or when
+     * device has work profiles).
      * <p>
-     * This map is filled on demand in the following scenarios:
+     * Entries on this cache are added on demand and removed when:
      * <ol>
-     *   <li>On start, it sets the value for the default user.
-     *   <li>When an auto-fill service app is removed, its entries are removed.
-     *   <li>When the current user changes.
-     *   <li>When the {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} changes.
+     *   <li>An auto-fill service app is removed.
+     *   <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.
+     *   <li>It has not been interacted with for {@link #SERVICE_BINDING_LIFETIME_MS} ms.
      * </ol>
      */
-    // TODO: make sure all cases listed above are handled
-    // TODO: should entries be removed when there is no section and have not be used for a while?
     @GuardedBy("mLock")
-    private SparseArray<AutoFillManagerServiceImpl> mImplByUser = new SparseArray<>();
-
-    // TODO: should disable it on low-memory devices? if not, this attribute should be removed...
-    private final boolean mEnableService = true;
+    private SparseArray<AutoFillManagerServiceImpl> mServicesCache = new SparseArray<>();
 
     public AutoFillManagerService(Context context) {
         super(context);
@@ -105,133 +132,130 @@
 
     @Override
     public void onStart() {
-        if (DEBUG)
-            Slog.d(TAG, "onStart(): binding as " + AUTO_FILL_MANAGER_SERVICE);
+        if (DEBUG) Slog.d(TAG, "onStart(): binding as " + AUTO_FILL_MANAGER_SERVICE);
         publishBinderService(AUTO_FILL_MANAGER_SERVICE, mServiceStub);
     }
 
-    // TODO: refactor so it's bound on demand, in which case it can use isSafeMode() from PM.
     @Override
     public void onBootPhase(int phase) {
         if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-            systemRunning(isSafeMode());
+            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);
         }
     }
 
-    // TODO: refactor so it's bound on demand, in which case it can use isSafeMode() from PM.
-    @Override
-    public void onStartUser(int userHandle) {
-        if (DEBUG) Slog.d(TAG, "onStartUser(): userHandle=" + userHandle);
-
-        updateImplementationIfNeeded(userHandle, false);
-    }
-
-    @Override
-    public void onUnlockUser(int userHandle) {
-        if (DEBUG) Slog.d(TAG, "onUnlockUser(): userHandle=" + userHandle);
-
-        updateImplementationIfNeeded(userHandle, false);
-    }
-
-    @Override
-    public void onSwitchUser(int userHandle) {
-        if (DEBUG) Slog.d(TAG, "onSwitchUser(): userHandle=" + userHandle);
-
-        updateImplementationIfNeeded(userHandle, false);
-    }
-
-    private void systemRunning(boolean safeMode) {
-        if (DEBUG) Slog.d(TAG, "systemRunning(): safeMode=" + safeMode);
-
-        // TODO: register a PackageMonitor
-        new SettingsObserver(BackgroundThread.getHandler());
-
-        synchronized (mLock) {
-            mSafeMode = safeMode;
-            updateImplementationIfNeededLocked(ActivityManager.getCurrentUser(), false);
-        }
-    }
-
-    private void updateImplementationIfNeeded(int user, boolean force) {
-        synchronized (mLock) {
-            updateImplementationIfNeededLocked(user, force);
-        }
-    }
-
-    private void updateImplementationIfNeededLocked(int user, boolean force) {
-        if (DEBUG)
-            Slog.d(TAG, "updateImplementationIfNeededLocked(" + user + ", " + force + ")");
-
-        if (mSafeMode) {
-            if (DEBUG) Slog.d(TAG, "skipping on safe mode");
-            return;
-        }
-
-        final String curService = Settings.Secure.getStringForUser(
-                mResolver, Settings.Secure.AUTO_FILL_SERVICE, user);
-        if (DEBUG)
-            Slog.d(TAG, "Current service settings for user " + user + ": " + curService);
+    private AutoFillManagerServiceImpl newServiceForUser(int userId) {
         ComponentName serviceComponent = null;
         ServiceInfo serviceInfo = null;
-        if (!TextUtils.isEmpty(curService)) {
+        final String componentName = Settings.Secure.getStringForUser(
+                mResolver, Settings.Secure.AUTO_FILL_SERVICE, userId);
+        if (!TextUtils.isEmpty(componentName)) {
             try {
-                serviceComponent = ComponentName.unflattenFromString(curService);
+                serviceComponent = ComponentName.unflattenFromString(componentName);
                 serviceInfo =
-                        AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, user);
+                        AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, userId);
             } catch (RuntimeException | RemoteException e) {
-                Slog.wtf(TAG, "Bad auto-fill service name " + curService, e);
-                serviceComponent = null;
-                serviceInfo = null;
+                Slog.wtf(TAG, "Bad auto-fill service name " + componentName, e);
+                return null;
             }
         }
 
-        final AutoFillManagerServiceImpl impl = mImplByUser.get(user);
-        if (DEBUG) Slog.d(TAG, "Current impl: " + impl + " component: " + serviceComponent
-                + " info: " + serviceInfo);
+        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 new AutoFillManagerServiceImpl(this, mContext, mLock, FgThread.getHandler(), userId,
+                serviceInfo.applicationInfo.uid, serviceComponent, SERVICE_BINDING_LIFETIME_MS);
+    }
 
-        if (force || impl == null || !impl.mComponent.equals(serviceComponent)) {
-            if (impl != null) {
-                impl.shutdownLocked();
+    /**
+     * Gets the service instance for an user.
+     *
+     * <p>First it tries to return the existing instance from the cache; if it's not cached, it
+     * creates a new instance and caches it.
+     */
+    private AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
+        AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        if (service != null) {
+            if (DEBUG) Log.d(TAG, "reusing cached service for userId " + userId);
+            service.setLifeExpectancy(SERVICE_BINDING_LIFETIME_MS);
+        } else {
+            service = newServiceForUser(userId);
+            if (service == null) {
+                // Already logged
+                return null;
             }
-            if (serviceInfo != null) {
-                final AutoFillManagerServiceImpl newImpl = new AutoFillManagerServiceImpl(mContext,
-                        mLock, mServiceStub, FgThread.getHandler(), user, serviceComponent);
-                if (DEBUG) Slog.d(TAG, "Setting impl for user " + user + " as: " + newImpl);
-                mImplByUser.put(user, newImpl);
-                newImpl.startLocked();
-            } else {
-                if (DEBUG) Slog.d(TAG, "Removing impl for user " + user + ": " + impl);
-                mImplByUser.remove(user);
-            }
+            if (DEBUG) Log.d(TAG, "creating new cached service for userId " + userId);
+            service.startLocked();
+            mServicesCache.put(userId, service);
+        }
+        // Keep service connection alive for a while, in case user needs to interact with it
+        // (for example, to save the data that was inputted in)
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UNBIND, userId, ARG_NOT_USED),
+                SERVICE_BINDING_LIFETIME_MS);
+        return service;
+    }
+
+    /**
+     * Removes a cached service, but respecting its TTL.
+     */
+    private void removeStaleServiceForUser(int userId) {
+        synchronized (mLock) {
+            removeCachedService(userId, false);
         }
     }
 
-    // TODO: might need to return null instead of throw exception
-    private AutoFillManagerServiceImpl getImplOrThrowLocked(int userId) {
-        final AutoFillManagerServiceImpl impl = mImplByUser.get(userId);
-        if (impl == null) {
-            throw new IllegalStateException("no auto-fill service for user " + userId);
+    /**
+     * Removes a cached service, even if it has TTL.
+     */
+    void removeCachedServiceForUserLocked(int userId) {
+        removeCachedService(userId, true);
+    }
+
+    private void removeCachedService(int userId, boolean force) {
+        if (DEBUG) Log.d(TAG, "removing cached service for userId " + userId);
+        final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
+        if (service == null) {
+            Log.w(TAG, "removeCachedServiceForUser(): no cached service for userId " + userId);
+            return;
         }
-        return impl;
+        if (!force) {
+            // Check TTL first.
+            final long now = SystemClock.uptimeMillis();
+            if (service.mEstimateTimeOfDeath > now) {
+                if (DEBUG) {
+                    final StringBuilder msg = new StringBuilder("service has some TTL left: ");
+                    TimeUtils.formatDuration(service.mEstimateTimeOfDeath - now, msg);
+                    Log.d(TAG, msg.toString());
+                }
+                return;
+            }
+        }
+        mServicesCache.delete(userId);
+        service.stopLocked();
+
     }
 
     final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
 
         @Override
-        public String startSession(int userId, Bundle args, int flags, IBinder activityToken) {
+        public void requestAutoFill(int userId, IBinder activityToken) {
             mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
 
             synchronized (mLock) {
-                return getImplOrThrowLocked(userId).startSession(args, flags, activityToken);
-            }
-        }
-
-        @Override
-        public boolean finishSession(int userId, String token) {
-            mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-
-            synchronized (mLock) {
-                return getImplOrThrowLocked(userId).finishSessionLocked(token);
+                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                if (service != null) {
+                    service.requestAutoFill(activityToken);
+                }
             }
         }
 
@@ -244,44 +268,22 @@
                         + ", uid=" + Binder.getCallingUid());
                 return;
             }
-            if (args.length > 0) {
-                if ("--sessions".equals(args[0])) {
-                    dumpSessions(pw);
-                    return;
-                }
-            }
             synchronized (mLock) {
-                pw.print("mEnableService: "); pw.println(mEnableService);
-                pw.print("mSafeMode: "); pw.println(mSafeMode);
-                final int size = mImplByUser.size();
-                pw.print("Number of implementations: ");
+                final int size = mServicesCache.size();
+                pw.print("Cached services: ");
                 if (size == 0) {
                     pw.println("none");
                 } else {
                     pw.println(size);
                     for (int i = 0; i < size; i++) {
-                        pw.print("\nImplementation at index "); pw.println(i);
-                        final AutoFillManagerServiceImpl impl = mImplByUser.valueAt(i);
+                        pw.print("\nService at index "); pw.println(i);
+                        final AutoFillManagerServiceImpl impl = mServicesCache.valueAt(i);
                         impl.dumpLocked("  ", pw);
                     }
                 }
             }
         }
 
-        private void dumpSessions(PrintWriter pw) {
-            boolean foundOne = false;
-            synchronized (mLock) {
-                final int size = mImplByUser.size();
-                for (int i = 0; i < size; i++) {
-                    final AutoFillManagerServiceImpl impl = mImplByUser.valueAt(i);
-                    foundOne |= impl.dumpSessionsLocked("", pw);
-                }
-            }
-            if (!foundOne) {
-                pw.println("No active sessions");
-            }
-        }
-
         @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
@@ -296,15 +298,144 @@
             super(handler);
             ContentResolver resolver = mContext.getContentResolver();
             resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.AUTO_FILL_SERVICE), false, this,
-                    UserHandle.USER_ALL);
+                    Settings.Secure.AUTO_FILL_SERVICE), false, this, UserHandle.USER_ALL);
         }
 
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
+            if (DEBUG) Slog.d(TAG, "settings (" + uri + " changed for " + userId);
             synchronized (mLock) {
-                updateImplementationIfNeededLocked(userId, false);
+                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/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index c780062..e409cb0 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -16,7 +16,11 @@
 
 package com.android.server.autofill;
 
+import static com.android.server.autofill.AutoFillManagerService.DEBUG;
+
+import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -24,10 +28,12 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
-import android.os.Bundle;
+import android.icu.text.DateFormat;
+import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.service.autofill.AutoFillService;
 import android.service.autofill.AutoFillServiceInfo;
@@ -35,39 +41,42 @@
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
+import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.LocalServices;
-import com.android.server.autofill.AutoFillManagerService.AutoFillManagerServiceStub;
 
 import java.io.PrintWriter;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.UUID;
 
 /**
  * Bridge between the {@code system_server}'s {@link AutoFillManagerService} and the
  * app's {@link IAutoFillService} implementation.
  *
- * <p>It keeps a list of auto-fill sessions for a specifc user.
  */
 final class AutoFillManagerServiceImpl {
 
     private static final String TAG = "AutoFillManagerServiceImpl";
-    private static final boolean DEBUG = true; // TODO: change to false once stable
 
-    final int mUser;
-    final ComponentName mComponent;
-
+    private final int mUserId;
+    private final int mUid;
+    private final ComponentName mComponent;
     private final Context mContext;
+    private final IActivityManager mAm;
     private final Object mLock;
-    private final AutoFillManagerServiceStub mServiceStub;
     private final AutoFillServiceInfo mInfo;
+    private final AutoFillManagerService mManagerService;
 
-    // Map of sessions keyed by session tokens.
+    // TODO: improve its usage
+    // - set maximum number of entries
+    // - disable on low-memory devices.
+    private final List<String> mRequestHistory = new LinkedList<>();
+
     @GuardedBy("mLock")
-    private Map<String, AutoFillSession> mSessions = new HashMap<>();
+    private final List<IBinder> mQueuedRequests = new LinkedList<>();
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -75,7 +84,7 @@
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
                 final String reason = intent.getStringExtra("reason");
                 if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason);
-                // TODO: close any pending UI like account selection
+                // TODO: close any pending UI like account selection (or remove this receiver)
             }
         }
     };
@@ -87,9 +96,16 @@
             synchronized (mLock) {
                 mService = IAutoFillService.Stub.asInterface(service);
                 try {
-                    mService.ready();
+                    mService.onConnected();
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception on service.ready(): " + e);
+                    Slog.w(TAG, "Exception on service.onConnected(): " + e);
+                    return;
+                }
+                if (!mQueuedRequests.isEmpty()) {
+                    if (DEBUG) Log.d(TAG, "queued requests:" + mQueuedRequests.size());
+                }
+                for (IBinder activityToken : mQueuedRequests) {
+                    requestAutoFillLocked(activityToken, false);
                 }
             }
         }
@@ -97,7 +113,10 @@
         @Override
         public void onServiceDisconnected(ComponentName name) {
             if (DEBUG) Log.d(TAG, name + " disconnected");
-            mService = null;
+            synchronized (mLock) {
+                mService = null;
+                mManagerService.removeCachedServiceForUserLocked(mUserId);
+            }
         }
     };
 
@@ -106,17 +125,23 @@
     private boolean mBound;
     private boolean mValid;
 
-    AutoFillManagerServiceImpl(Context context, Object lock, AutoFillManagerServiceStub stub,
-            Handler handler, int user, ComponentName component) {
+    // Estimated time when the service will be evicted from the cache.
+    long mEstimateTimeOfDeath;
+
+    AutoFillManagerServiceImpl(AutoFillManagerService managerService, Context context, Object lock,
+            Handler handler, int userId, int uid,ComponentName component, long ttl) {
+        mManagerService = managerService;
         mContext = context;
         mLock = lock;
-        mServiceStub = stub;
-        mUser = user;
+        mUserId = userId;
+        mUid = uid;
         mComponent = component;
+        mAm = ActivityManager.getService();
+        setLifeExpectancy(ttl);
 
-        AutoFillServiceInfo info;
+        final AutoFillServiceInfo info;
         try {
-            info = new AutoFillServiceInfo(component, mUser);
+            info = new AutoFillServiceInfo(component, mUserId);
         } catch (PackageManager.NameNotFoundException e) {
             Slog.w(TAG, "Auto-fill service not found: " + component, e);
             mInfo = null;
@@ -136,13 +161,18 @@
         mContext.registerReceiver(mBroadcastReceiver, filter, null, handler);
     }
 
+    void setLifeExpectancy(long ttl) {
+        mEstimateTimeOfDeath = SystemClock.uptimeMillis() + ttl;
+    }
+
     void startLocked() {
         if (DEBUG) Slog.d(TAG, "startLocked()");
 
         final Intent intent = new Intent(AutoFillService.SERVICE_INTERFACE);
         intent.setComponent(mComponent);
         mBound = mContext.bindServiceAsUser(intent, mConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUser));
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUserId));
+
         if (!mBound) {
             Slog.w(TAG, "Failed binding to auto-fill service " + mComponent);
             return;
@@ -150,19 +180,16 @@
         if (DEBUG) Slog.d(TAG, "Bound to " + mComponent);
     }
 
-    String startSession(Bundle args, int flags, IBinder activityToken) {
-
-        if (!mBound) {
-            // TODO: should it bind on demand? Or perhaps always run when on on low-memory?
-            Slog.w(TAG, "startSession() failed because it's not bound to service");
-            return null;
+    void requestAutoFill(IBinder activityToken) {
+        synchronized (mLock) {
+            if (!mBound) {
+                Slog.w(TAG, "requestAutoFill() failed because it's not bound to service");
+                return;
+            }
         }
 
-        // TODO: session should have activity ids, so same session is reused when called again
-        // for the same activity.
-
         // TODO: activityToken should probably not be null, but we need to wait until the UI is
-        // triggering the call (for now it's trough 'adb shell cmd autofill start session'
+        // triggering the call (for now it's trough 'adb shell cmd autofill request'
         if (activityToken == null) {
             // Let's get top activities from all visible stacks.
 
@@ -175,51 +202,64 @@
                 Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
             if (topActivities.isEmpty()) {
                 Slog.w(TAG, "Could not get top activity");
-                return null;
+                return;
             }
             activityToken = topActivities.get(0);
         }
 
+        final String historyItem =
+                DateFormat.getDateTimeInstance().format(new Date()) + " - " + activityToken;
         synchronized (mLock) {
-            return startSessionLocked(args, flags, activityToken);
+            mRequestHistory.add(historyItem);
+            requestAutoFillLocked(activityToken, true);
         }
     }
 
-    // TODO: remove args and flags if not needed?
-    private String startSessionLocked(Bundle args, int flags, IBinder activityToken) {
-
-        final String sessionToken = UUID.randomUUID().toString();
-
-        if (DEBUG) Slog.d(TAG, "Starting session for user " + mUser
-                + ": sessionToken=" + sessionToken + ", activityToken=" + activityToken);
-
-        final AutoFillSession session =
-                new AutoFillSession(mService, mLock, sessionToken, activityToken);
-        session.startLocked();
-        mSessions.put(sessionToken, session);
-
-        return sessionToken;
-    }
-
-    // TODO: need a way to automatically call it when the activity is destroyed.
-    boolean finishSessionLocked(String token) {
-        if (DEBUG) Slog.d(TAG, "Removing session " + token + " for user " + mUser);
-        final AutoFillSession session = mSessions.remove(token);
-        if (session != null) {
-            session.finishLocked();
+    private void requestAutoFillLocked(IBinder activityToken, boolean queueIfNecessary) {
+        if (mService == null) {
+            if (!queueIfNecessary) {
+                Slog.w(TAG, "requestAutoFillLocked(): service is null");
+                return;
+            }
+            if (DEBUG) Slog.d(TAG, "requestAutoFill(): service not set yet, queuing it");
+            mQueuedRequests.add(activityToken);
+            return;
         }
-        return session != null;
-    }
 
-    void shutdownLocked() {
-        if (DEBUG) Slog.d(TAG, "shutdownLocked()");
-
+        /*
+         * TODO: apply security checks below:
+         * - checks if disabled by secure settings / device policy
+         * - log operation using noteOp()
+         * - check flags
+         * - display disclosure if needed
+         */
         try {
-            if (mService != null) {
-                mService.shutdown();
+            // TODO: add MetricsLogger call
+            if (!mAm.requestAutoFillData(mService.getAssistReceiver(), null, activityToken)) {
+                // TODO: might need a way to warn user (perhaps a new method on AutoFillService).
+                Slog.w(TAG, "failed to request auto-fill data for " + activityToken);
             }
         } catch (RemoteException e) {
-            Slog.w(TAG, "RemoteException in shutdown", e);
+            // Should happen, it's a local call.
+        }
+    }
+
+    void stopLocked() {
+        if (DEBUG) Slog.d(TAG, "stopLocked()");
+
+        // Sanity check.
+        if (mService == null) {
+            Log.w(TAG, "service already null on shutdown");
+            return;
+        }
+        try {
+            mService.onDisconnected();
+        } catch (RemoteException e) {
+            if (! (e instanceof DeadObjectException)) {
+                Slog.w(TAG, "Exception calling service.onDisconnected(): " + e);
+            }
+        } finally {
+            mService = null;
         }
 
         if (mBound) {
@@ -242,10 +282,14 @@
             return;
         }
 
-        pw.print(prefix); pw.print("mUser="); pw.println(mUser);
+        pw.print(prefix); pw.print("mUserId="); pw.println(mUserId);
+        pw.print(prefix); pw.print("mUid="); pw.println(mUid);
         pw.print(prefix); pw.print("mComponent="); pw.println(mComponent.flattenToShortString());
         pw.print(prefix); pw.print("mBound="); pw.println(mBound);
         pw.print(prefix); pw.print("mService="); pw.println(mService);
+        pw.print(prefix); pw.print("mEstimateTimeOfDeath=");
+            TimeUtils.formatDuration(mEstimateTimeOfDeath, SystemClock.uptimeMillis(), pw);
+        pw.println();
 
         if (DEBUG) {
             // ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps)
@@ -253,28 +297,29 @@
             mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), prefix + prefix);
         }
 
-        if (!dumpSessionsLocked(prefix, pw)) {
-            pw.print(prefix); pw.print("No active sessions for user "); pw.println(mUser);
+        if (mRequestHistory.isEmpty()) {
+            pw.print(prefix); pw.println("No history");
+        } else {
+            pw.print(prefix); pw.println("History:");
+            final String prefix2 = prefix + prefix;
+            for (int i = 0; i < mRequestHistory.size(); i++) {
+                pw.print(prefix2); pw.print(i); pw.print(": "); pw.println(mRequestHistory.get(i));
+            }
         }
-    }
-
-    boolean dumpSessionsLocked(String prefix, PrintWriter pw) {
-        if (mSessions.isEmpty()) {
-            return false;
+        if (mQueuedRequests.isEmpty()) {
+            pw.print(prefix); pw.println("No queued requests");
+        } else {
+            pw.print(prefix); pw.println("Queued requests:");
+            final String prefix2 = prefix + prefix;
+            for (int i = 0; i < mQueuedRequests.size(); i++) {
+                pw.print(prefix2); pw.print(i); pw.print(": "); pw.println(mQueuedRequests.get(i));
+            }
         }
-
-        pw.print(mSessions.size());pw.println(" active sessions:");
-        final String sessionPrefix = prefix + prefix;
-        for (AutoFillSession session : mSessions.values()) {
-            pw.println();
-            session.dumpLocked(sessionPrefix, pw);
-        }
-        return true;
     }
 
     @Override
     public String toString() {
-        return "[AutoFillManagerServiceImpl: user=" + mUser
+        return "[AutoFillManagerServiceImpl: userId=" + mUserId + ", uid=" + mUid
                 + ", component=" + mComponent.flattenToShortString() + "]";
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
index 4e08ed6..6406b8a 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
@@ -40,10 +40,8 @@
         final PrintWriter pw = getOutPrintWriter();
         try {
             switch (cmd) {
-                case "start":
-                    return runStart(pw);
-                case "finish":
-                    return runFinish(pw);
+                case "request":
+                    return requestAutoFill();
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -60,61 +58,15 @@
             pw.println("  help");
             pw.println("    Prints this help text.");
             pw.println("");
-            pw.println("  start session [--user USER_ID]");
-            pw.println("    Starts an auto-fill session. "
-                    + "Prints 'token:SESSION_TOKEN if successful, or error message");
-            pw.println("");
-            pw.println("  finish session <TOKEN> [--user USER_ID]");
-            pw.println("    Finishes a session with the given TOKEN. "
-                    + "Prints empty string if successful, or error message.");
+            pw.println("  request [--user USER_ID]");
+            pw.println("    Request auto-fill on the top activity. ");
             pw.println("");
         }
     }
 
-    private int runStart(PrintWriter pw) throws RemoteException {
-        final String type = getNextArg();
-        if (type == null) {
-            pw.println("Error: didn't specify type of data to start");
-            return -1;
-        }
-        switch (type) {
-            case "session":
-                return startAutoFillSession(pw);
-        }
-        pw.println("Error: unknown start type '" + type + "'");
-        return -1;
-    }
-
-    private int runFinish(PrintWriter pw) throws RemoteException {
-        final String type = getNextArg();
-        if (type == null) {
-            pw.println("Error: didn't specify type of data to finish");
-            return -1;
-        }
-        switch (type) {
-            case "session":
-                return finishAutoFillSession(pw);
-        }
-        pw.println("Error: unknown finish type '" + type + "'");
-        return -1;
-    }
-
-    private int startAutoFillSession(PrintWriter pw) throws RemoteException {
+    private int requestAutoFill() throws RemoteException {
         final int userId = getUserIdFromArgs();
-        final String token = mService.startSession(userId, null, 0, null);
-        pw.print("token:"); pw.println(token);
-        return 0;
-    }
-
-    private int finishAutoFillSession(PrintWriter pw) throws RemoteException {
-        final String token = getNextArgRequired();
-        final int userId = getUserIdFromArgs();
-
-        boolean finished = mService.finishSession(userId, token);
-        if (!finished) {
-            pw.println("No such session");
-            return 1;
-        }
+        mService.requestAutoFill(userId, null);
         return 0;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillSession.java b/services/autofill/java/com/android/server/autofill/AutoFillSession.java
deleted file mode 100644
index 44637c3..0000000
--- a/services/autofill/java/com/android/server/autofill/AutoFillSession.java
+++ /dev/null
@@ -1,135 +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.
- */
-
-package com.android.server.autofill;
-
-import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.assist.AssistStructure;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.service.autofill.AutoFillService;
-import android.service.autofill.IAutoFillService;
-import android.service.voice.VoiceInteractionSession;
-import android.util.Slog;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.IResultReceiver;
-
-import java.io.PrintWriter;
-
-/**
- * An auto-fill session between the system's {@link AutoFillManagerServiceImpl} and the provider's
- * {@link AutoFillService} implementation.
- */
-final class AutoFillSession {
-
-    private static final String TAG = "AutoFillSession";
-
-    private static final boolean FOCUSED = true;
-    private static final boolean NEW_SESSION_ID = true;
-
-    private final IAutoFillService mService;
-    private final String mSessionToken;
-    private final IBinder mActivityToken;
-    private final Object mLock;
-    private final IActivityManager mAm;
-
-    private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
-        @Override
-        public void send(int resultCode, Bundle resultData) throws RemoteException {
-            synchronized (mLock) {
-                mPendingResponse = false;
-                mAssistResponse = resultData;
-                deliverSessionDataLocked();
-            }
-        }
-    };
-
-    // Assist data is filled asynchronously.
-    @GuardedBy("mLock")
-    private Bundle mAssistResponse;
-    @GuardedBy("mLock")
-    private boolean mPendingResponse;
-
-    AutoFillSession(IAutoFillService service, Object lock, String sessionToken,
-            IBinder activityToken) {
-        mService = service;
-        mSessionToken = sessionToken;
-        mActivityToken = activityToken;
-        mLock = lock;
-        mAm = ActivityManagerNative.getDefault();
-    }
-
-    void startLocked() {
-        /*
-         * TODO: apply security checks below:
-         * - checks if disabled by secure settings / device policy
-         * - log operation using noteOp()
-         * - check flags
-         * - display disclosure if needed
-         */
-        mAssistResponse = null;
-        mPendingResponse = true;
-        try {
-            // TODO: add MetricsLogger call
-            if (!mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
-                    mAssistReceiver, (Bundle) null, mActivityToken, FOCUSED, NEW_SESSION_ID)) {
-                mPendingResponse = false;
-                Slog.w(TAG, "requestAssistContextExtras() rejected");
-            }
-        } catch (RemoteException e) {
-            // Should happen, it's a local call.
-        }
-    }
-
-    void finishLocked() {
-        try {
-            mService.finishSession(mSessionToken);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "auto-fill service failed to finish session " + mSessionToken, e);
-        }
-    }
-
-    private void deliverSessionDataLocked() {
-        if (mAssistResponse == null) {
-            Slog.w(TAG, "No assist data for session " + mSessionToken);
-            return;
-        }
-
-        final Bundle assistData = mAssistResponse.getBundle(VoiceInteractionSession.KEY_DATA);
-        final AssistStructure structure =
-                mAssistResponse.getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
-        try {
-            mService.newSession(mSessionToken, assistData, 0, structure);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "auto-fill service failed to start session " + mSessionToken, e);
-        } finally {
-            mPendingResponse = false;
-            // We could set mAssistResponse to null here, but we don't so it's shown on dump()
-        }
-    }
-
-    void dumpLocked(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("mSessionToken="); pw.println(mSessionToken);
-        pw.print(prefix); pw.print("mActivityToken="); pw.println(mActivityToken);
-        pw.print(prefix); pw.print("mPendingResponse="); pw.println(mPendingResponse);
-        pw.print(prefix); pw.print("mAssistResponse="); pw.println(mAssistResponse);
-    }
-
-}
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..581aa05d 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 d60f115..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,
@@ -12142,6 +12143,15 @@
                 != null;
     }
 
+    @Override
+    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
+            IBinder activityToken) {
+        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null, receiver,
+                receiverExtras, activityToken, true, true,
+                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
+                != null;
+    }
+
     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
@@ -12266,6 +12276,12 @@
                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
                         pae.receiverExtras);
+                IBinder autoFillCallback =
+                        extras.getBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK);
+                if (autoFillCallback != null) {
+                    sendBundle.putBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK,
+                            autoFillCallback);
+                }
             }
         }
         if (sendReceiver != null) {
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..709c3d0 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;
@@ -254,11 +257,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;
@@ -1952,12 +1951,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 +1966,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 +1995,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 +2061,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/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 79ef486..6eb8927 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;
@@ -193,8 +192,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;
@@ -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;
@@ -1470,10 +1470,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;
@@ -1878,6 +1879,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 +4139,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 +4542,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);
@@ -7238,15 +7244,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 +7266,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 +7353,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 +9701,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 +10401,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) {
+                Slog.e(TAG, "Not granting privileged permission " + perm + " for package "
+                        + pkg.packageName + " - not in privapp-permissions whitelist");
+                return false;
+            }
+        }
+        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.
@@ -11587,7 +11607,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 +11704,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 +11854,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 +13816,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) {
@@ -17125,7 +17145,7 @@
 
     private void postPreferredActivityChangedBroadcast(int userId) {
         mHandler.post(() -> {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             if (am == null) {
                 return;
             }
@@ -18397,10 +18417,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 +19298,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 +20810,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 {
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..1f302e3 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;
@@ -3943,7 +3942,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 +3956,7 @@
 
         // no keyguard stuff to worry about, just launch home!
         try {
-            ActivityManagerNative.getDefault().stopAppSwitches();
+            ActivityManager.getService().stopAppSwitches();
         } catch (RemoteException e) {
         }
         if (mRecentsVisible) {
@@ -7340,7 +7339,7 @@
         if (false) {
             // This code always brings home to the front.
             try {
-                ActivityManagerNative.getDefault().stopAppSwitches();
+                ActivityManager.getService().stopAppSwitches();
             } catch (RemoteException e) {
             }
             sendCloseSystemWindows();
@@ -7353,11 +7352,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 +7367,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/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/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c4c4bcd..9648282 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;
@@ -8261,7 +8262,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..c11003d 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;
@@ -3833,21 +3835,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 +3857,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 +3867,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 +3893,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 +3903,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/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 95dffe8..543bba6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -38,10 +38,11 @@
 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;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -137,6 +138,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.ParcelableString;
@@ -1439,6 +1441,10 @@
                 ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
         }
 
+        PackageManager getPackageManager() {
+            return mContext.getPackageManager();
+        }
+
         PowerManagerInternal getPowerManagerInternal() {
             return LocalServices.getService(PowerManagerInternal.class);
         }
@@ -1453,7 +1459,7 @@
         }
 
         IActivityManager getIActivityManager() {
-            return ActivityManagerNative.getDefault();
+            return ActivityManager.getService();
         }
 
         IPackageManager getIPackageManager() {
@@ -5517,7 +5523,7 @@
 
         final long callingIdentity = mInjector.binderClearCallingIdentity();
         try {
-            ActivityManagerNative.getDefault().requestBugReport(
+            ActivityManager.getService().requestBugReport(
                     ActivityManager.BUGREPORT_OPTION_REMOTE);
 
             mRemoteBugreportServiceIsActive.set(true);
@@ -5907,6 +5913,10 @@
         }
     }
 
+    boolean isDeviceOwner(ActiveAdmin admin) {
+        return isDeviceOwner(admin.info.getComponent(), admin.getUserHandle().getIdentifier());
+    }
+
     public boolean isDeviceOwner(ComponentName who, int userId) {
         synchronized (this) {
             return mOwners.hasDeviceOwner()
@@ -9428,6 +9438,77 @@
         }
     }
 
+    @Override
+    public boolean bindDeviceAdminServiceAsUser(
+            @NonNull ComponentName admin, @NonNull IApplicationThread caller,
+            @Nullable IBinder activtiyToken, @NonNull Intent serviceIntent,
+            @NonNull IServiceConnection connection, int flags, @UserIdInt int targetUserId) {
+        if (!mHasFeature) {
+            return false;
+        }
+        Preconditions.checkNotNull(admin);
+        Preconditions.checkNotNull(caller);
+        Preconditions.checkNotNull(serviceIntent);
+        Preconditions.checkNotNull(connection);
+        final int callingUserId = mInjector.userHandleGetCallingUserId();
+        Preconditions.checkArgument(callingUserId != targetUserId,
+                "target user id must be different from the calling user id");
+
+        synchronized (this) {
+            final ActiveAdmin callingAdmin = getActiveAdminForCallerLocked(admin,
+                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            // Ensure the target user is valid.
+            if (isDeviceOwner(callingAdmin)) {
+                enforceManagedProfile(targetUserId, "Target user must be a managed profile");
+            } else {
+                // Further lock down to profile owner in managed profile.
+                enforceManagedProfile(callingUserId,
+                        "Only support profile owner in managed profile.");
+                if (mOwners.getDeviceOwnerUserId() != targetUserId) {
+                    throw new SecurityException("Target user must be a device owner.");
+                }
+            }
+        }
+        final long callingIdentity = mInjector.binderClearCallingIdentity();
+        try {
+            if (!mUserManager.isSameProfileGroup(callingUserId, targetUserId)) {
+                throw new SecurityException(
+                        "Can only bind service across users under the same profile group");
+            }
+            final String targetPackage;
+            synchronized (this) {
+                targetPackage = getOwnerPackageNameForUserLocked(targetUserId);
+            }
+            // STOPSHIP(b/31952368): Add policy to control which packages can talk.
+            if (TextUtils.isEmpty(targetPackage) || !targetPackage.equals(admin.getPackageName())) {
+                throw new SecurityException("Device owner and profile owner must be the same " +
+                        "package in order to communicate.");
+            }
+            // Validate and sanitize the incoming service intent.
+            final Intent sanitizedIntent =
+                    createCrossUserServiceIntent(serviceIntent, targetPackage);
+            if (sanitizedIntent == null) {
+                // Fail, cannot lookup the target service.
+                throw new SecurityException("Invalid intent or failed to look up the service");
+            }
+            // Ask ActivityManager to bind it. Notice that we are binding the service with the
+            // caller app instead of DevicePolicyManagerService.
+            try {
+                return mInjector.getIActivityManager().bindService(
+                        caller, activtiyToken, serviceIntent,
+                        serviceIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                        connection, flags, mContext.getOpPackageName(),
+                        targetUserId) != 0;
+            } catch (RemoteException ex) {
+                // Same process, should not happen.
+            }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(callingIdentity);
+        }
+        // Fail to bind.
+        return false;
+    }
+
     /**
      * Return true if a given user has any accounts that'll prevent installing a device or profile
      * owner {@code owner}.
@@ -9572,6 +9653,8 @@
      * A maximum of 1200 events are returned, and the total marshalled size is in the order of
      * 100kB, so returning a List instead of ParceledListSlice is acceptable.
      * Ideally this would be done with ParceledList, however it only supports homogeneous types.
+     *
+     * @see NetworkLoggingHandler#MAX_EVENTS_PER_BATCH
      */
     @Override
     public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin,
@@ -9589,4 +9672,46 @@
                 ? mNetworkLogger.retrieveLogs(batchToken)
                 : null;
     }
+
+    /**
+     * Return the package name of owner in a given user.
+     */
+    private String getOwnerPackageNameForUserLocked(int userId) {
+        return getDeviceOwnerUserId() == userId
+                ? mOwners.getDeviceOwnerPackageName()
+                : mOwners.getProfileOwnerPackage(userId);
+    }
+
+    /**
+     * @param rawIntent Original service intent specified by caller.
+     * @param expectedPackageName The expected package name in the incoming intent.
+     * @return Intent that have component explicitly set. {@code null} if the incoming intent
+     *         or target service is invalid.
+     */
+    private Intent createCrossUserServiceIntent (
+            @NonNull Intent rawIntent, @NonNull String expectedPackageName) {
+        if (rawIntent.getComponent() == null && rawIntent.getPackage() == null) {
+            Log.e(LOG_TAG, "Service intent must be explicit (with a package name or component): "
+                    + rawIntent);
+            return null;
+        }
+        ResolveInfo info = mInjector.getPackageManager().resolveService(rawIntent, 0);
+        if (info == null || info.serviceInfo == null) {
+            Log.e(LOG_TAG, "Fail to look up the service: " + rawIntent);
+            return null;
+        }
+        if (!expectedPackageName.equals(info.serviceInfo.packageName)) {
+            Log.e(LOG_TAG, "Only allow to bind service in " + expectedPackageName);
+            return null;
+        }
+        if (info.serviceInfo.exported) {
+            Log.e(LOG_TAG, "The service must be unexported.");
+            return null;
+        }
+        // It is the system server to bind the service, it would be extremely dangerous if it
+        // can be exploited to bind any service. Set the component explicitly to make sure we
+        // do not bind anything accidentally.
+        rawIntent.setComponent(info.serviceInfo.getComponentName());
+        return rawIntent;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 98e5570..29cc43f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -61,8 +61,9 @@
     @GuardedBy("this")
     private ArrayList<NetworkEvent> mFullBatch;
 
+    // each full batch is represented by its token, which the DPC has to provide back to revieve it
     @GuardedBy("this")
-    private long currentFullBatchToken;
+    private long mCurrentFullBatchToken;
 
     NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
         super(looper);
@@ -101,9 +102,9 @@
         scheduleBatchFinalization(BATCH_FINALIZATION_TIMEOUT_MS);
         // notify DO that there's a new non-empty batch waiting
         if (mFullBatch.size() > 0) {
-            currentFullBatchToken++;
+            mCurrentFullBatchToken++;
             Bundle extras = new Bundle();
-            extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, currentFullBatchToken);
+            extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken);
             extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size());
             mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
         } else {
@@ -112,7 +113,7 @@
     }
 
     synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) {
-        if (batchToken != currentFullBatchToken) {
+        if (batchToken != mCurrentFullBatchToken) {
             return null;
         }
         return mFullBatch;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3db24fa..1202025 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;
@@ -167,8 +167,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 =
@@ -572,7 +572,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 +784,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 +993,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/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 0533efc..225dc5d2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -98,7 +98,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 +112,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));
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..4499275 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -41,9 +41,7 @@
 /**
  * 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
@@ -160,6 +158,15 @@
         assertEquals(root, child2.getTopParentWindow());
     }
 
+    @Test
+    public void testIsOnScreen_hiddenByPolicy() {
+        final WindowState window = createWindow(null, TYPE_APPLICATION);
+        window.setHasSurface(true);
+        assertTrue(window.isOnScreen());
+        window.hideLw(false /* doAnimation */);
+        assertFalse(window.isOnScreen());
+    }
+
     private WindowState createWindow(WindowState parent, int type) {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
 
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/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/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index fdd971b..190fc35 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -17,6 +17,8 @@
 package android.test.mock;
 
 import android.annotation.SystemApi;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -759,4 +761,23 @@
     public boolean isCredentialProtectedStorage() {
         throw new UnsupportedOperationException();
     }
+
+    /** {@hide} */
+    @Override
+    public IBinder getActivityToken() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
+            int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public IApplicationThread getIApplicationThread() {
+        throw new UnsupportedOperationException();
+    }
 }
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..6874b49e 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 80bbaf1..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(871703200000L, 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/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/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
      *
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index ee2e895..8b1cfae 100644
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -28,5 +28,6 @@
     Messenger getMessenger();
     Messenger getP2pStateMachineMessenger();
     void setMiracastMode(int mode);
+    void checkConfigureWifiDisplayPermission();
 }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 398308d..c93ac7b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -1324,6 +1324,11 @@
             Channel c, WifiP2pWfdInfo wfdInfo,
             ActionListener listener) {
         checkChannel(c);
+        try {
+            mService.checkConfigureWifiDisplayPermission();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
         c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
     }