Merge "Add ACTION_WIFI_SAVED_NETWORK_SETTINGS to Settings."
diff --git a/Android.mk b/Android.mk
index cd738e7..552103d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -245,9 +245,9 @@
 	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
-	core/java/android/os/storage/IMountService.aidl \
-	core/java/android/os/storage/IMountServiceListener.aidl \
-	core/java/android/os/storage/IMountShutdownObserver.aidl \
+	core/java/android/os/storage/IStorageManager.aidl \
+	core/java/android/os/storage/IStorageEventListener.aidl \
+	core/java/android/os/storage/IStorageShutdownObserver.aidl \
 	core/java/android/os/storage/IObbActionListener.aidl \
 	core/java/android/security/IKeystoreService.aidl \
 	core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index cee8fdb..71e6af7 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -241,6 +241,7 @@
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit1_intermediates/src/com/android/test/split/feature/R.java)
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit2_intermediates/src/com/android/test/split/feature/R.java)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
 
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
diff --git a/apct-tests/perftests/core/res/layout/twelve_key_entry.xml b/apct-tests/perftests/core/res/layout/twelve_key_entry.xml
new file mode 100644
index 0000000..4d68018
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/twelve_key_entry.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="64dip"
+        android:layout_marginStart="2dip"
+        android:layout_marginEnd="2dip"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/one"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/two"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/three"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="64dip"
+        android:layout_marginStart="2dip"
+        android:layout_marginEnd="2dip"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/four"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/five"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/six"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="64dip"
+        android:layout_marginStart="2dip"
+        android:layout_marginEnd="2dip"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/seven"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/eight"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/nine"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="64dip"
+        android:layout_marginStart="2dip"
+        android:layout_marginEnd="2dip"
+        android:orientation="horizontal">
+
+        <Button android:id="@+id/cancel"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold"
+            android:text="@android:string/cancel"
+        />
+
+        <Button android:id="@+id/zero"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textStyle="bold"
+        />
+
+        <Button android:id="@+id/ok"
+            android:layout_width="0sp"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"
+            android:layout_marginStart="2dip"
+            android:layout_marginEnd="2dip"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textStyle="bold"
+            android:text="@android:string/ok"
+        />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/apct-tests/perftests/core/src/android/view/ViewPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
index 5503ca9..990be24 100644
--- a/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
@@ -44,4 +44,15 @@
             inflater.inflate(R.layout.test_simple_view, root, false);
         }
     }
+
+    @Test
+    public void testTwelveKeyInflate() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        LayoutInflater inflater = LayoutInflater.from(context);
+        FrameLayout root = new FrameLayout(context);
+        while (state.keepRunning()) {
+            inflater.inflate(R.layout.twelve_key_entry, root, false);
+        }
+    }
 }
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/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
index fd393e9..bb9dc4a 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
@@ -63,7 +63,7 @@
     // TODO: Tune these values.
     private static final long TARGET_TEST_DURATION_NS = ms2ns(500); // target testing for 500 ms
     private static final int MAX_TEST_ITERATIONS = 1000000;
-    private static final int MIN_TEST_ITERATIONS = 100;
+    private static final int MIN_TEST_ITERATIONS = 10;
     private static final int REPEAT_COUNT = 5;
 
     private long mStartTimeNs = 0;  // Previously captured System.nanoTime().
diff --git a/api/current.txt b/api/current.txt
index 9c19fd7..8a00273 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";
@@ -4656,7 +4658,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -5350,12 +5352,12 @@
     method public int getImportance();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
-    method public android.net.Uri getRingtone();
+    method public android.net.Uri getSound();
     method public void setBypassDnd(boolean);
     method public void setImportance(int);
     method public void setLights(boolean);
     method public void setLockscreenVisibility(int);
-    method public void setRingtone(android.net.Uri);
+    method public void setSound(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -7906,6 +7908,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8039,6 +8042,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -32192,6 +32196,7 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -34643,9 +34648,9 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
+    method public void onConnected();
+    method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onReady();
-    method public void onShutdown();
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
@@ -59082,8 +59087,8 @@
     method public static void rotate(java.util.List<?>, int);
     method public static void shuffle(java.util.List<?>);
     method public static void shuffle(java.util.List<?>, java.util.Random);
-    method public static <E> java.util.Set<E> singleton(E);
-    method public static <E> java.util.List<E> singletonList(E);
+    method public static <T> java.util.Set<T> singleton(T);
+    method public static <T> java.util.List<T> singletonList(T);
     method public static <K, V> java.util.Map<K, V> singletonMap(K, V);
     method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>);
     method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>);
@@ -63352,7 +63357,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -63361,7 +63369,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -63432,6 +63443,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/api/system-current.txt b/api/system-current.txt
index 18845b6..8c11322 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";
@@ -4552,9 +4554,10 @@
   public abstract class EphemeralResolverService extends android.app.Service {
     ctor public EphemeralResolverService();
     method public final void attachBaseContext(android.content.Context);
+    method public android.os.Looper getLooper();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract deprecated java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int);
-    method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralIntentFilter(int[]);
+    method public android.content.pm.EphemeralResolveInfo onGetEphemeralIntentFilter(java.lang.String);
     method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralResolveInfo(int[]);
     field public static final java.lang.String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO";
     field public static final java.lang.String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE";
@@ -4809,7 +4812,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -5505,7 +5508,7 @@
     method public int getImportance();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
-    method public android.net.Uri getRingtone();
+    method public android.net.Uri getSound();
     method public int getUserLockedFields();
     method public void lockFields(int);
     method public void populateFromXml(org.xmlpull.v1.XmlPullParser);
@@ -5513,7 +5516,7 @@
     method public void setImportance(int);
     method public void setLights(boolean);
     method public void setLockscreenVisibility(int);
-    method public void setRingtone(android.net.Uri);
+    method public void setSound(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -5525,7 +5528,7 @@
     field public static final int USER_LOCKED_IMPORTANCE = 4; // 0x4
     field public static final int USER_LOCKED_LIGHTS = 8; // 0x8
     field public static final int USER_LOCKED_PRIORITY = 1; // 0x1
-    field public static final int USER_LOCKED_RINGTONE = 32; // 0x20
+    field public static final int USER_LOCKED_SOUND = 32; // 0x20
     field public static final int USER_LOCKED_VIBRATION = 16; // 0x10
     field public static final int USER_LOCKED_VISIBILITY = 2; // 0x2
   }
@@ -8238,6 +8241,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8371,6 +8375,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -34880,6 +34885,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";
@@ -37437,9 +37443,9 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
+    method public void onConnected();
+    method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onReady();
-    method public void onShutdown();
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
@@ -62609,8 +62615,8 @@
     method public static void rotate(java.util.List<?>, int);
     method public static void shuffle(java.util.List<?>);
     method public static void shuffle(java.util.List<?>, java.util.Random);
-    method public static <E> java.util.Set<E> singleton(E);
-    method public static <E> java.util.List<E> singletonList(E);
+    method public static <T> java.util.Set<T> singleton(T);
+    method public static <T> java.util.List<T> singletonList(T);
     method public static <K, V> java.util.Map<K, V> singletonMap(K, V);
     method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>);
     method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>);
@@ -66879,7 +66885,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -66888,7 +66897,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -66959,6 +66971,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/api/test-current.txt b/api/test-current.txt
index 7eeb6c1..13b0c94 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);
@@ -4666,7 +4668,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -5360,12 +5362,12 @@
     method public int getImportance();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
-    method public android.net.Uri getRingtone();
+    method public android.net.Uri getSound();
     method public void setBypassDnd(boolean);
     method public void setImportance(int);
     method public void setLights(boolean);
     method public void setLockscreenVisibility(int);
-    method public void setRingtone(android.net.Uri);
+    method public void setSound(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -7922,6 +7924,7 @@
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -8056,6 +8059,7 @@
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
+    method public final boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public void releasePersistableUriPermission(android.net.Uri, int);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
@@ -32278,6 +32282,7 @@
 
   public final class MediaStore {
     ctor public MediaStore();
+    method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
@@ -34733,9 +34738,9 @@
   public abstract class AutoFillService extends android.app.Service {
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
+    method public void onConnected();
+    method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onReady();
-    method public void onShutdown();
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
   }
 
@@ -59343,8 +59348,8 @@
     method public static void rotate(java.util.List<?>, int);
     method public static void shuffle(java.util.List<?>);
     method public static void shuffle(java.util.List<?>, java.util.Random);
-    method public static <E> java.util.Set<E> singleton(E);
-    method public static <E> java.util.List<E> singletonList(E);
+    method public static <T> java.util.Set<T> singleton(T);
+    method public static <T> java.util.List<T> singletonList(T);
     method public static <K, V> java.util.Map<K, V> singletonMap(K, V);
     method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>);
     method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>);
@@ -63613,7 +63618,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -63622,7 +63630,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -63693,6 +63704,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 470a0fa..f003061 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -23,7 +23,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackInfo;
-import android.app.ActivityManagerNative;
 import android.app.IActivityContainer;
 import android.app.IActivityController;
 import android.app.IActivityManager;
@@ -108,7 +107,7 @@
     @Override
     public void onRun() throws Exception {
 
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         if (mAm == null) {
             System.err.println(NO_SYSTEM_ERROR_CODE);
             throw new AndroidException("Can't connect to activity manager; is the system running?");
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 132a4f8..63641a8 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -16,7 +16,7 @@
 
 package com.android.commands.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
 import android.content.ContentValues;
@@ -433,7 +433,7 @@
         public final void execute() {
             String providerName = mUri.getAuthority();
             try {
-                IActivityManager activityManager = ActivityManagerNative.getDefault();
+                IActivityManager activityManager = ActivityManager.getService();
                 IContentProvider provider = null;
                 IBinder token = new Binder();
                 try {
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index 31c7421..3ac70d6 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -16,7 +16,7 @@
 
 package com.android.commands.dpm;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
@@ -117,7 +117,7 @@
                     mUserId = parseInt(arg);
                 }
                 if (mUserId == UserHandle.USER_CURRENT) {
-                    IActivityManager activityManager = ActivityManagerNative.getDefault();
+                    IActivityManager activityManager = ActivityManager.getService();
                     try {
                         mUserId = activityManager.getCurrentUser().id;
                     } catch (RemoteException e) {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 718f141..50f46f4 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -24,7 +24,6 @@
 
 import android.accounts.IAccountManager;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1191,7 +1190,7 @@
 
         ClearDataObserver obs = new ClearDataObserver();
         try {
-            ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId);
+            ActivityManager.getService().clearApplicationUserData(pkg, obs, userId);
             synchronized (obs) {
                 while (!obs.finished) {
                     try {
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index d527ad7..4291c77 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -20,7 +20,7 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.storage.DiskInfo;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.util.Log;
@@ -28,7 +28,7 @@
 public final class Sm {
     private static final String TAG = "Sm";
 
-    IMountService mSm;
+    IStorageManager mSm;
 
     private String[] mArgs;
     private int mNextArg;
@@ -55,7 +55,7 @@
             throw new IllegalArgumentException();
         }
 
-        mSm = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+        mSm = IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
         if (mSm == null) {
             throw new RemoteException("Failed to find running mount service");
         }
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index 8681166..32b4595 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -16,7 +16,7 @@
 
 package com.android.uiautomator.core;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
@@ -56,7 +56,7 @@
         try {
             IContentProvider provider = null;
             Cursor cursor = null;
-            IActivityManager activityManager = ActivityManagerNative.getDefault();
+            IActivityManager activityManager = ActivityManager.getService();
             String providerName = Settings.Secure.CONTENT_URI.getAuthority();
             IBinder token = new Binder();
             try {
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
index ddeb8e7..d98b4ff 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/UiAutomationShellWrapper.java
@@ -2,7 +2,6 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityController;
 import android.app.IActivityManager;
 import android.app.UiAutomation;
@@ -44,7 +43,7 @@
      * @see {@link ActivityManager#isUserAMonkey()}
      */
     public void setRunAsMonkey(boolean isSet) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (am == null) {
             throw new RuntimeException("Can't manage monkey status; is the system running?");
         }
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 33e3e04..f09bad9 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -174,9 +174,6 @@
 android.app.ActivityManager$TaskThumbnailInfo$1
 android.app.ActivityManagerInternal
 android.app.ActivityManagerInternal$SleepToken
-android.app.ActivityManagerNative
-android.app.ActivityManagerNative$1
-android.app.ActivityManagerProxy
 android.app.ActivityOptions
 android.app.ActivityOptions$OnAnimationFinishedListener
 android.app.ActivityOptions$OnAnimationStartedListener
@@ -3226,17 +3223,17 @@
 android.os.health.SystemHealthManager
 android.os.storage.DiskInfo
 android.os.storage.DiskInfo$1
-android.os.storage.IMountService
-android.os.storage.IMountService$Stub
-android.os.storage.IMountService$Stub$Proxy
-android.os.storage.IMountServiceListener
-android.os.storage.IMountServiceListener$Stub
-android.os.storage.IMountServiceListener$Stub$Proxy
-android.os.storage.IMountShutdownObserver
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.IStorageEventListener
+android.os.storage.IStorageEventListener$Stub
+android.os.storage.IStorageEventListener$Stub$Proxy
+android.os.storage.IStorageShutdownObserver
 android.os.storage.IObbActionListener
 android.os.storage.IObbActionListener$Stub
-android.os.storage.MountServiceInternal
-android.os.storage.MountServiceInternal$ExternalStorageMountPolicy
+android.os.storage.StorageManagerInternal
+android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
 android.os.storage.StorageEventListener
 android.os.storage.StorageManager
 android.os.storage.StorageManager$ObbActionListener
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index aed7a36..8c71f50 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -18,7 +18,7 @@
 import com.google.android.collect.Sets;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -141,8 +141,8 @@
 
         try {
             IBinder activityToken = getActivityToken();
-            mCallingUid = ActivityManagerNative.getDefault().getLaunchedFromUid(activityToken);
-            mCallingPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+            mCallingUid = ActivityManager.getService().getLaunchedFromUid(activityToken);
+            mCallingPackage = ActivityManager.getService().getLaunchedFromPackage(
                     activityToken);
             if (mCallingUid != 0 && mCallingPackage != null) {
                 Bundle restrictions = UserManager.get(this)
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6f53f13..64e5dfc 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1313,7 +1313,7 @@
     public boolean isVoiceInteractionRoot() {
         try {
             return mVoiceInteractor != null
-                    && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken);
+                    && ActivityManager.getService().isRootVoiceInteraction(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1336,7 +1336,7 @@
      */
     public boolean isLocalVoiceInteractionSupported() {
         try {
-            return ActivityManagerNative.getDefault().supportsLocalVoiceInteraction();
+            return ActivityManager.getService().supportsLocalVoiceInteraction();
         } catch (RemoteException re) {
         }
         return false;
@@ -1350,7 +1350,7 @@
      */
     public void startLocalVoiceInteraction(Bundle privateOptions) {
         try {
-            ActivityManagerNative.getDefault().startLocalVoiceInteraction(mToken, privateOptions);
+            ActivityManager.getService().startLocalVoiceInteraction(mToken, privateOptions);
         } catch (RemoteException re) {
         }
     }
@@ -1379,7 +1379,7 @@
      */
     public void stopLocalVoiceInteraction() {
         try {
-            ActivityManagerNative.getDefault().stopLocalVoiceInteraction(mToken);
+            ActivityManager.getService().stopLocalVoiceInteraction(mToken);
         } catch (RemoteException re) {
         }
     }
@@ -1798,7 +1798,7 @@
      */
     public boolean showAssist(Bundle args) {
         try {
-            return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args);
+            return ActivityManager.getService().showAssistFromActivity(mToken, args);
         } catch (RemoteException e) {
         }
         return false;
@@ -1914,7 +1914,7 @@
         if (mDoReportFullyDrawn) {
             mDoReportFullyDrawn = false;
             try {
-                ActivityManagerNative.getDefault().reportActivityFullyDrawn(mToken);
+                ActivityManager.getService().reportActivityFullyDrawn(mToken);
             } catch (RemoteException e) {
             }
         }
@@ -1940,7 +1940,7 @@
      */
     public boolean isInMultiWindowMode() {
         try {
-            return ActivityManagerNative.getDefault().isInMultiWindowMode(mToken);
+            return ActivityManager.getService().isInMultiWindowMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1965,7 +1965,7 @@
      */
     public boolean isInPictureInPictureMode() {
         try {
-            return ActivityManagerNative.getDefault().isInPictureInPictureMode(mToken);
+            return ActivityManager.getService().isInPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -1977,7 +1977,7 @@
      */
     public void enterPictureInPictureMode() {
         try {
-            ActivityManagerNative.getDefault().enterPictureInPictureMode(mToken);
+            ActivityManager.getService().enterPictureInPictureMode(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -3037,7 +3037,7 @@
      */
     @Override
     public void exitFreeformMode() throws RemoteException {
-        ActivityManagerNative.getDefault().exitFreeformMode(mToken);
+        ActivityManager.getService().exitFreeformMode(mToken);
     }
 
     /** Returns the current stack Id for the window.
@@ -3045,7 +3045,7 @@
      */
     @Override
     public int getWindowStackId() throws RemoteException {
-        return ActivityManagerNative.getDefault().getActivityStackId(mToken);
+        return ActivityManager.getService().getActivityStackId(mToken);
     }
 
     /**
@@ -4533,7 +4533,7 @@
                 fillInIntent.prepareToLeaveProcess(this);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
                         fillInIntent, resolvedType, mToken, who,
                         requestCode, flagsMask, flagsValues, options);
@@ -4763,7 +4763,7 @@
                 }
                 intent.migrateExtraStreamToClipData();
                 intent.prepareToLeaveProcess(this);
-                result = ActivityManagerNative.getDefault()
+                result = ActivityManager.getService()
                     .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
                             intent, intent.resolveTypeIfNeeded(getContentResolver()), mToken,
                             mEmbeddedID, requestCode, ActivityManager.START_FLAG_ONLY_IF_NEEDED,
@@ -4834,7 +4834,7 @@
             try {
                 intent.migrateExtraStreamToClipData();
                 intent.prepareToLeaveProcess(this);
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                     .startNextMatchingActivity(mToken, intent, options);
             } catch (RemoteException e) {
                 // Empty
@@ -5032,7 +5032,7 @@
      */
     public void overridePendingTransition(int enterAnim, int exitAnim) {
         try {
-            ActivityManagerNative.getDefault().overridePendingTransition(
+            ActivityManager.getService().overridePendingTransition(
                     mToken, getPackageName(), enterAnim, exitAnim);
         } catch (RemoteException e) {
         }
@@ -5157,7 +5157,7 @@
     @Nullable
     public String getCallingPackage() {
         try {
-            return ActivityManagerNative.getDefault().getCallingPackage(mToken);
+            return ActivityManager.getService().getCallingPackage(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5180,7 +5180,7 @@
     @Nullable
     public ComponentName getCallingActivity() {
         try {
-            return ActivityManagerNative.getDefault().getCallingActivity(mToken);
+            return ActivityManager.getService().getCallingActivity(mToken);
         } catch (RemoteException e) {
             return null;
         }
@@ -5265,7 +5265,7 @@
             throw new IllegalStateException("Must be called from main thread");
         }
         try {
-            ActivityManagerNative.getDefault().requestActivityRelaunch(mToken);
+            ActivityManager.getService().requestActivityRelaunch(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -5287,7 +5287,7 @@
                 if (resultData != null) {
                     resultData.prepareToLeaveProcess(this);
                 }
-                if (ActivityManagerNative.getDefault()
+                if (ActivityManager.getService()
                         .finishActivity(mToken, resultCode, resultData, finishTask)) {
                     mFinished = true;
                 }
@@ -5330,7 +5330,7 @@
             throw new IllegalStateException("Can not be called to deliver a result");
         }
         try {
-            if (ActivityManagerNative.getDefault().finishActivityAffinity(mToken)) {
+            if (ActivityManager.getService().finishActivityAffinity(mToken)) {
                 mFinished = true;
             }
         } catch (RemoteException e) {
@@ -5376,7 +5376,7 @@
     public void finishActivity(int requestCode) {
         if (mParent == null) {
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishSubActivity(mToken, mEmbeddedID, requestCode);
             } catch (RemoteException e) {
                 // Empty
@@ -5396,7 +5396,7 @@
      */
     public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
         try {
-            ActivityManagerNative.getDefault()
+            ActivityManager.getService()
                 .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
         } catch (RemoteException e) {
             // Empty
@@ -5424,7 +5424,7 @@
      */
     public boolean releaseInstance() {
         try {
-            return ActivityManagerNative.getDefault().releaseActivityInstance(mToken);
+            return ActivityManager.getService().releaseActivityInstance(mToken);
         } catch (RemoteException e) {
             // Empty
         }
@@ -5514,7 +5514,7 @@
         try {
             data.prepareToLeaveProcess(this);
             IIntentSender target =
-                ActivityManagerNative.getDefault().getIntentSender(
+                ActivityManager.getService().getIntentSender(
                         ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
                         mParent == null ? mToken : mParent.mToken,
                         mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null,
@@ -5539,7 +5539,7 @@
     public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
             try {
-                ActivityManagerNative.getDefault().setRequestedOrientation(
+                ActivityManager.getService().setRequestedOrientation(
                         mToken, requestedOrientation);
             } catch (RemoteException e) {
                 // Empty
@@ -5562,7 +5562,7 @@
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
-                return ActivityManagerNative.getDefault()
+                return ActivityManager.getService()
                         .getRequestedOrientation(mToken);
             } catch (RemoteException e) {
                 // Empty
@@ -5581,7 +5581,7 @@
      */
     public int getTaskId() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getTaskForActivity(mToken, false);
         } catch (RemoteException e) {
             return -1;
@@ -5596,7 +5596,7 @@
      */
     public boolean isTaskRoot() {
         try {
-            return ActivityManagerNative.getDefault().getTaskForActivity(mToken, true) >= 0;
+            return ActivityManager.getService().getTaskForActivity(mToken, true) >= 0;
         } catch (RemoteException e) {
             return false;
         }
@@ -5615,7 +5615,7 @@
      */
     public boolean moveTaskToBack(boolean nonRoot) {
         try {
-            return ActivityManagerNative.getDefault().moveActivityTaskToBack(
+            return ActivityManager.getService().moveActivityTaskToBack(
                     mToken, nonRoot);
         } catch (RemoteException e) {
             // Empty
@@ -5786,7 +5786,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().setTaskDescription(mToken, mTaskDescription);
+            ActivityManager.getService().setTaskDescription(mToken, mTaskDescription);
         } catch (RemoteException e) {
         }
     }
@@ -6049,7 +6049,7 @@
      */
     public boolean isImmersive() {
         try {
-            return ActivityManagerNative.getDefault().isImmersive(mToken);
+            return ActivityManager.getService().isImmersive(mToken);
         } catch (RemoteException e) {
             return false;
         }
@@ -6067,7 +6067,7 @@
             return false;
         }
         try {
-            return ActivityManagerNative.getDefault().isTopOfTask(getActivityToken());
+            return ActivityManager.getService().isTopOfTask(getActivityToken());
         } catch (RemoteException e) {
             return false;
         }
@@ -6093,7 +6093,7 @@
     public void convertFromTranslucent() {
         try {
             mTranslucentCallback = null;
-            if (ActivityManagerNative.getDefault().convertFromTranslucent(mToken)) {
+            if (ActivityManager.getService().convertFromTranslucent(mToken)) {
                 WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
             }
         } catch (RemoteException e) {
@@ -6132,7 +6132,7 @@
         boolean drawComplete;
         try {
             mTranslucentCallback = callback;
-            mChangeCanvasToTranslucent = ActivityManagerNative.getDefault().convertToTranslucent(
+            mChangeCanvasToTranslucent = ActivityManager.getService().convertToTranslucent(
                     mToken, options == null ? null : options.toBundle());
             WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
             drawComplete = true;
@@ -6178,7 +6178,7 @@
     ActivityOptions getActivityOptions() {
         try {
             return ActivityOptions.fromBundle(
-                    ActivityManagerNative.getDefault().getActivityOptions(mToken));
+                    ActivityManager.getService().getActivityOptions(mToken));
         } catch (RemoteException e) {
         }
         return null;
@@ -6222,7 +6222,7 @@
             visible = false;
         }
         try {
-            mVisibleBehind = ActivityManagerNative.getDefault()
+            mVisibleBehind = ActivityManager.getService()
                     .requestVisibleBehind(mToken, visible) && visible;
         } catch (RemoteException e) {
             mVisibleBehind = false;
@@ -6263,7 +6263,7 @@
     @SystemApi
     public boolean isBackgroundVisibleBehind() {
         try {
-            return ActivityManagerNative.getDefault().isBackgroundVisibleBehind(mToken);
+            return ActivityManager.getService().isBackgroundVisibleBehind(mToken);
         } catch (RemoteException e) {
         }
         return false;
@@ -6320,7 +6320,7 @@
      */
     public void setImmersive(boolean i) {
         try {
-            ActivityManagerNative.getDefault().setImmersive(mToken, i);
+            ActivityManager.getService().setImmersive(mToken, i);
         } catch (RemoteException e) {
             // pass
         }
@@ -6384,7 +6384,7 @@
     public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent)
           throws PackageManager.NameNotFoundException {
         try {
-            if (ActivityManagerNative.getDefault().setVrMode(mToken, enabled, requestedComponent)
+            if (ActivityManager.getService().setVrMode(mToken, enabled, requestedComponent)
                     != 0) {
                 throw new PackageManager.NameNotFoundException(
                         requestedComponent.flattenToString());
@@ -6505,7 +6505,7 @@
             if (info.taskAffinity == null) {
                 return false;
             }
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .shouldUpRecreateTask(mToken, info.taskAffinity);
         } catch (RemoteException e) {
             return false;
@@ -6558,7 +6558,7 @@
             }
             try {
                 upIntent.prepareToLeaveProcess(this);
-                return ActivityManagerNative.getDefault().navigateUpTo(mToken, upIntent,
+                return ActivityManager.getService().navigateUpTo(mToken, upIntent,
                         resultCode, resultData);
             } catch (RemoteException e) {
                 return false;
@@ -7074,7 +7074,7 @@
      */
     public void startLockTask() {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeByToken(mToken);
+            ActivityManager.getService().startLockTaskModeByToken(mToken);
         } catch (RemoteException e) {
         }
     }
@@ -7098,7 +7098,7 @@
      */
     public void stopLockTask() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            ActivityManager.getService().stopLockTaskMode();
         } catch (RemoteException e) {
         }
     }
@@ -7110,7 +7110,7 @@
      */
     public void showLockTaskEscapeMessage() {
         try {
-            ActivityManagerNative.getDefault().showLockTaskEscapeMessage(mToken);
+            ActivityManager.getService().showLockTaskEscapeMessage(mToken);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c55d3b8..65f74d1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -36,6 +36,7 @@
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
+import com.android.server.LocalServices;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -89,6 +90,8 @@
     private final Context mContext;
     private final Handler mHandler;
 
+    private static volatile boolean sSystemReady = false;
+
     static final class UidObserver extends IUidObserver.Stub {
         final OnUidImportanceListener mListener;
 
@@ -826,7 +829,7 @@
     /** @hide */
     public int getFrontActivityScreenCompatMode() {
         try {
-            return ActivityManagerNative.getDefault().getFrontActivityScreenCompatMode();
+            return getService().getFrontActivityScreenCompatMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -835,7 +838,7 @@
     /** @hide */
     public void setFrontActivityScreenCompatMode(int mode) {
         try {
-            ActivityManagerNative.getDefault().setFrontActivityScreenCompatMode(mode);
+            getService().setFrontActivityScreenCompatMode(mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -844,7 +847,7 @@
     /** @hide */
     public int getPackageScreenCompatMode(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getPackageScreenCompatMode(packageName);
+            return getService().getPackageScreenCompatMode(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -853,7 +856,7 @@
     /** @hide */
     public void setPackageScreenCompatMode(String packageName, int mode) {
         try {
-            ActivityManagerNative.getDefault().setPackageScreenCompatMode(packageName, mode);
+            getService().setPackageScreenCompatMode(packageName, mode);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -862,7 +865,7 @@
     /** @hide */
     public boolean getPackageAskScreenCompat(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getPackageAskScreenCompat(packageName);
+            return getService().getPackageAskScreenCompat(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -871,7 +874,7 @@
     /** @hide */
     public void setPackageAskScreenCompat(String packageName, boolean ask) {
         try {
-            ActivityManagerNative.getDefault().setPackageAskScreenCompat(packageName, ask);
+            getService().setPackageAskScreenCompat(packageName, ask);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1166,7 +1169,7 @@
         public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) {
             if (iconFilename != null) {
                 try {
-                    return ActivityManagerNative.getDefault().getTaskDescriptionIcon(iconFilename,
+                    return getService().getTaskDescriptionIcon(iconFilename,
                             userId);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -1555,7 +1558,7 @@
     public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
+            return getService().getRecentTasks(maxNum,
                     flags, UserHandle.myUserId()).getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1580,7 +1583,7 @@
     public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
+            return getService().getRecentTasks(maxNum,
                     flags, userId).getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1726,7 +1729,7 @@
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
         List<IBinder> appTasks;
         try {
-            appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
+            appTasks = getService().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1751,7 +1754,7 @@
     private void ensureAppTaskThumbnailSizeLocked() {
         if (mAppTaskThumbnailSize == null) {
             try {
-                mAppTaskThumbnailSize = ActivityManagerNative.getDefault().getAppTaskThumbnailSize();
+                mAppTaskThumbnailSize = getService().getAppTaskThumbnailSize();
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1816,7 +1819,7 @@
             description = new TaskDescription();
         }
         try {
-            return ActivityManagerNative.getDefault().addAppTask(activity.getActivityToken(),
+            return getService().addAppTask(activity.getActivityToken(),
                     intent, description, thumbnail);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1859,7 +1862,7 @@
     public List<RunningTaskInfo> getRunningTasks(int maxNum)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTasks(maxNum, 0);
+            return getService().getTasks(maxNum, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1875,7 +1878,7 @@
      */
     public boolean removeTask(int taskId) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().removeTask(taskId);
+            return getService().removeTask(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2043,7 +2046,7 @@
     /** @hide */
     public TaskThumbnail getTaskThumbnail(int id) throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault().getTaskThumbnail(id);
+            return getService().getTaskThumbnail(id);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2052,7 +2055,7 @@
     /** @hide */
     public boolean isInHomeStack(int taskId) {
         try {
-            return ActivityManagerNative.getDefault().isInHomeStack(taskId);
+            return getService().isInHomeStack(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2101,7 +2104,7 @@
      */
     public void moveTaskToFront(int taskId, int flags, Bundle options) {
         try {
-            ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags, options);
+            getService().moveTaskToFront(taskId, flags, options);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2286,7 +2289,7 @@
     public List<RunningServiceInfo> getRunningServices(int maxNum)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault()
+            return getService()
                     .getServices(maxNum, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2301,7 +2304,7 @@
     public PendingIntent getRunningServiceControlPanel(ComponentName service)
             throws SecurityException {
         try {
-            return ActivityManagerNative.getDefault()
+            return getService()
                     .getRunningServiceControlPanel(service);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2406,7 +2409,7 @@
      */
     public void getMemoryInfo(MemoryInfo outInfo) {
         try {
-            ActivityManagerNative.getDefault().getMemoryInfo(outInfo);
+            getService().getMemoryInfo(outInfo);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2545,7 +2548,7 @@
      */
     public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) {
         try {
-            return ActivityManagerNative.getDefault().clearApplicationUserData(packageName,
+            return getService().clearApplicationUserData(packageName,
                     observer, UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2579,7 +2582,7 @@
      */
     public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName) {
         try {
-            return ActivityManagerNative.getDefault().getGrantedUriPermissions(packageName,
+            return getService().getGrantedUriPermissions(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2597,7 +2600,7 @@
      */
     public void clearGrantedUriPermissions(String packageName) {
         try {
-            ActivityManagerNative.getDefault().clearGrantedUriPermissions(packageName,
+            getService().clearGrantedUriPermissions(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2718,7 +2721,7 @@
      */
     public List<ProcessErrorStateInfo> getProcessesInErrorState() {
         try {
-            return ActivityManagerNative.getDefault().getProcessesInErrorState();
+            return getService().getProcessesInErrorState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3055,7 +3058,7 @@
      */
     public List<ApplicationInfo> getRunningExternalApplications() {
         try {
-            return ActivityManagerNative.getDefault().getRunningExternalApplications();
+            return getService().getRunningExternalApplications();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3071,7 +3074,7 @@
      */
     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
         try {
-            return ActivityManagerNative.getDefault().setProcessMemoryTrimLevel(process, userId,
+            return getService().setProcessMemoryTrimLevel(process, userId,
                     level);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3090,7 +3093,7 @@
      */
     public List<RunningAppProcessInfo> getRunningAppProcesses() {
         try {
-            return ActivityManagerNative.getDefault().getRunningAppProcesses();
+            return getService().getRunningAppProcesses();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3208,7 +3211,7 @@
      */
     static public void getMyMemoryState(RunningAppProcessInfo outState) {
         try {
-            ActivityManagerNative.getDefault().getMyMemoryState(outState);
+            getService().getMyMemoryState(outState);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3227,7 +3230,7 @@
      */
     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
         try {
-            return ActivityManagerNative.getDefault().getProcessMemoryInfo(pids);
+            return getService().getProcessMemoryInfo(pids);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3260,7 +3263,7 @@
      */
     public void killBackgroundProcesses(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killBackgroundProcesses(packageName,
+            getService().killBackgroundProcesses(packageName,
                     UserHandle.myUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3278,7 +3281,7 @@
     @RequiresPermission(Manifest.permission.KILL_UID)
     public void killUid(int uid, String reason) {
         try {
-            ActivityManagerNative.getDefault().killUid(UserHandle.getAppId(uid),
+            getService().killUid(UserHandle.getAppId(uid),
                     UserHandle.getUserId(uid), reason);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3306,7 +3309,7 @@
      */
     public void forceStopPackageAsUser(String packageName, int userId) {
         try {
-            ActivityManagerNative.getDefault().forceStopPackage(packageName, userId);
+            getService().forceStopPackage(packageName, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3325,7 +3328,7 @@
      */
     public ConfigurationInfo getDeviceConfigurationInfo() {
         try {
-            return ActivityManagerNative.getDefault().getDeviceConfigurationInfo();
+            return getService().getDeviceConfigurationInfo();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3415,7 +3418,7 @@
      */
     public static boolean isUserAMonkey() {
         try {
-            return ActivityManagerNative.getDefault().isUserAMonkey();
+            return getService().isUserAMonkey();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3537,7 +3540,7 @@
             return userId;
         }
         try {
-            return ActivityManagerNative.getDefault().handleIncomingUser(callingPid,
+            return getService().handleIncomingUser(callingPid,
                     callingUid, userId, allowAll, requireFull, name, callerPackage);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3552,7 +3555,7 @@
     public static int getCurrentUser() {
         UserInfo ui;
         try {
-            ui = ActivityManagerNative.getDefault().getCurrentUser();
+            ui = getService().getCurrentUser();
             return ui != null ? ui.id : 0;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3565,7 +3568,7 @@
      */
     public boolean switchUser(int userid) {
         try {
-            return ActivityManagerNative.getDefault().switchUser(userid);
+            return getService().switchUser(userid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3580,8 +3583,8 @@
         int currentUser = ActivityManager.getCurrentUser();
         if (currentUser != UserHandle.USER_SYSTEM) {
             try {
-                ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM);
-                ActivityManagerNative.getDefault().stopUser(currentUser, /* force= */ false, null);
+                getService().switchUser(UserHandle.USER_SYSTEM);
+                getService().stopUser(currentUser, /* force= */ false, null);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
@@ -3608,7 +3611,7 @@
      */
     public boolean isUserRunning(int userId) {
         try {
-            return ActivityManagerNative.getDefault().isUserRunning(userId, 0);
+            return getService().isUserRunning(userId, 0);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3617,7 +3620,7 @@
     /** {@hide} */
     public boolean isVrModePackageEnabled(ComponentName component) {
         try {
-            return ActivityManagerNative.getDefault().isVrModePackageEnabled(component);
+            return getService().isVrModePackageEnabled(component);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3662,6 +3665,23 @@
     /**
      * @hide
      */
+    public static boolean isSystemReady() {
+        if (!sSystemReady) {
+            if (ActivityThread.isSystem()) {
+                sSystemReady =
+                        LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
+            } else {
+                // Since this is being called from outside system server, system should be
+                // ready by now.
+                sSystemReady = true;
+            }
+        }
+        return sSystemReady;
+    }
+
+    /**
+     * @hide
+     */
     public static void broadcastStickyIntent(Intent intent, int userId) {
         broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId);
     }
@@ -3771,7 +3791,7 @@
      */
     public void setWatchHeapLimit(long pssSize) {
         try {
-            ActivityManagerNative.getDefault().setDumpHeapDebugLimit(null, 0, pssSize,
+            getService().setDumpHeapDebugLimit(null, 0, pssSize,
                     mContext.getPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -3791,7 +3811,7 @@
      */
     public void clearWatchHeapLimit() {
         try {
-            ActivityManagerNative.getDefault().setDumpHeapDebugLimit(null, 0, 0, null);
+            getService().setDumpHeapDebugLimit(null, 0, 0, null);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3802,7 +3822,7 @@
      */
     public void startLockTaskMode(int taskId) {
         try {
-            ActivityManagerNative.getDefault().startLockTaskModeById(taskId);
+            getService().startLockTaskModeById(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3813,7 +3833,7 @@
      */
     public void stopLockTaskMode() {
         try {
-            ActivityManagerNative.getDefault().stopLockTaskMode();
+            getService().stopLockTaskMode();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3841,7 +3861,7 @@
      */
     public int getLockTaskModeState() {
         try {
-            return ActivityManagerNative.getDefault().getLockTaskModeState();
+            return getService().getLockTaskModeState();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3859,7 +3879,7 @@
      */
     public static void setVrThread(int tid) {
         try {
-            ActivityManagerNative.getDefault().setVrThread(tid);
+            getService().setVrThread(tid);
         } catch (RemoteException e) {
             // pass
         }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 38e3572..bfa6d34 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -61,6 +61,11 @@
      */
     public static final int APP_TRANSITION_TIMEOUT = 3;
 
+    /**
+     * Verify that calling app has access to the given provider.
+     */
+    public abstract String checkContentProviderAccess(String authority, int userId);
+
     // Called by the power manager.
     public abstract void onWakefulnessChanged(int wakefulness);
 
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index cabdd4b..c09403c 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -16,11 +16,7 @@
 
 package android.app;
 import android.content.Intent;
-import android.os.Debug;
 import android.os.IBinder;
-import android.util.Log;
-
-import com.android.server.LocalServices;
 
 /**
  * {@hide}
@@ -28,8 +24,6 @@
  */
 @Deprecated
 public abstract class ActivityManagerNative {
-    private final static String TAG = "ActivityManagerNative";
-
     /**
      * Cast a Binder object into an activity manager interface, generating
      * a proxy if needed.
@@ -55,21 +49,9 @@
      * @deprecated use ActivityManagerInternal.isSystemReady instead.
      */
     static public boolean isSystemReady() {
-        if (!sSystemReady) {
-            if (ActivityThread.isSystem()) {
-                sSystemReady =
-                        LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
-            } else {
-                // Since this is being called from outside system server, system should be
-                // ready by now.
-                sSystemReady = true;
-            }
-        }
-        return sSystemReady;
+        return ActivityManager.isSystemReady();
     }
 
-    static volatile boolean sSystemReady = false;
-
     /**
      * @deprecated use ActivityManager.broadcastStickyIntent instead.
      */
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index d9a4690..1e7f4f0 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -152,6 +153,12 @@
     private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
 
     /**
+     * The display id the activity should be launched into.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";
+
+    /**
      * The stack id the activity should be launched into.
      * @hide
      */
@@ -240,6 +247,7 @@
     private int mResultCode;
     private int mExitCoordinatorIndex;
     private PendingIntent mUsageTimeReport;
+    private int mLaunchDisplayId = INVALID_DISPLAY;
     private int mLaunchStackId = INVALID_STACK_ID;
     private int mLaunchTaskId = -1;
     private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
@@ -850,6 +858,7 @@
                 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
                 break;
         }
+        mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
         mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
         mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
         mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
@@ -1015,6 +1024,25 @@
         }
     }
 
+    /**
+     * Gets the id of the display where activity should be launched.
+     * @return The id of the display where activity should be launched,
+     *         {@link android.view.Display#INVALID_DISPLAY} if not set.
+     */
+    public int getLaunchDisplayId() {
+        return mLaunchDisplayId;
+    }
+
+    /**
+     * Sets the id of the display where activity should be launched.
+     * @param launchDisplayId The id of the display where the activity should be launched.
+     * @return {@code this} {@link ActivityOptions} instance.
+     */
+    public ActivityOptions setLaunchDisplayId(int launchDisplayId) {
+        mLaunchDisplayId = launchDisplayId;
+        return this;
+    }
+
     /** @hide */
     public int getLaunchStackId() {
         return mLaunchStackId;
@@ -1209,6 +1237,7 @@
                 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
                 break;
         }
+        b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
         b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
         b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
         b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8dd4c9c..f052bf7 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1309,8 +1309,19 @@
         }
 
         @Override
-        public final void updateTimePrefs(boolean is24Hour) {
-            DateFormat.set24HourTimePref(is24Hour);
+        public final void updateTimePrefs(int timeFormatPreference) {
+            final Boolean timeFormatPreferenceBool;
+            // For convenience we are using the Intent extra values.
+            if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR) {
+                timeFormatPreferenceBool = Boolean.FALSE;
+            } else if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR) {
+                timeFormatPreferenceBool = Boolean.TRUE;
+            } else {
+                // timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT
+                // (or unknown).
+                timeFormatPreferenceBool = null;
+            }
+            DateFormat.set24HourTimePref(timeFormatPreferenceBool);
         }
 
         @Override
@@ -1800,7 +1811,7 @@
             }
             if (a != null) {
                 mNewActivities = null;
-                IActivityManager am = ActivityManagerNative.getDefault();
+                IActivityManager am = ActivityManager.getService();
                 ActivityClientRecord prev;
                 do {
                     if (localLOGV) Slog.v(
@@ -2712,7 +2723,7 @@
     private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
         int displayId = Display.DEFAULT_DISPLAY;
         try {
-            displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
+            displayId = ActivityManager.getService().getActivityDisplayId(r.token);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2792,7 +2803,7 @@
         } else {
             // If there was an error, for any reason, tell the activity manager to stop us.
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                             Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
             } catch (RemoteException ex) {
@@ -2822,7 +2833,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
+            ActivityManager.getService().reportSizeConfigurations(r.token,
                     horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -2931,7 +2942,7 @@
             structure = new AssistStructure();
         }
         mLastAssistStructures.add(new WeakReference<>(structure));
-        IActivityManager mgr = ActivityManagerNative.getDefault();
+        IActivityManager mgr = ActivityManager.getService();
         try {
             mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
         } catch (RemoteException e) {
@@ -2970,7 +2981,7 @@
             }
         }
         try {
-            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
+            ActivityManager.getService().backgroundResourcesReleased(token);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3069,7 +3080,7 @@
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
 
-        IActivityManager mgr = ActivityManagerNative.getDefault();
+        IActivityManager mgr = ActivityManager.getService();
 
         BroadcastReceiver receiver;
         try {
@@ -3195,7 +3206,7 @@
 
             // tell the OS that we're live now
             try {
-                ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
+                ActivityManager.getService().backupAgentCreated(packageName, binder);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -3252,11 +3263,11 @@
 
             Application app = packageInfo.makeApplication(false, mInstrumentation);
             service.attach(context, this, data.info.name, data.token, app,
-                    ActivityManagerNative.getDefault());
+                    ActivityManager.getService());
             service.onCreate();
             mServices.put(data.token, service);
             try {
-                ActivityManagerNative.getDefault().serviceDoneExecuting(
+                ActivityManager.getService().serviceDoneExecuting(
                         data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -3281,11 +3292,11 @@
                 try {
                     if (!data.rebind) {
                         IBinder binder = s.onBind(data.intent);
-                        ActivityManagerNative.getDefault().publishService(
+                        ActivityManager.getService().publishService(
                                 data.token, data.intent, binder);
                     } else {
                         s.onRebind(data.intent);
-                        ActivityManagerNative.getDefault().serviceDoneExecuting(
+                        ActivityManager.getService().serviceDoneExecuting(
                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                     }
                     ensureJitEnabled();
@@ -3311,10 +3322,10 @@
                 boolean doRebind = s.onUnbind(data.intent);
                 try {
                     if (doRebind) {
-                        ActivityManagerNative.getDefault().unbindFinished(
+                        ActivityManager.getService().unbindFinished(
                                 data.token, data.intent, doRebind);
                     } else {
-                        ActivityManagerNative.getDefault().serviceDoneExecuting(
+                        ActivityManager.getService().serviceDoneExecuting(
                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                     }
                 } catch (RemoteException ex) {
@@ -3397,7 +3408,7 @@
                 QueuedWork.waitToFinish();
 
                 try {
-                    ActivityManagerNative.getDefault().serviceDoneExecuting(
+                    ActivityManager.getService().serviceDoneExecuting(
                             data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3428,7 +3439,7 @@
                 QueuedWork.waitToFinish();
 
                 try {
-                    ActivityManagerNative.getDefault().serviceDoneExecuting(
+                    ActivityManager.getService().serviceDoneExecuting(
                             token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3550,7 +3561,7 @@
             boolean willBeVisible = !a.mStartedActivity;
             if (!willBeVisible) {
                 try {
-                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
+                    willBeVisible = ActivityManager.getService().willActivityBeVisible(
                             a.getActivityToken());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -3638,7 +3649,7 @@
             // Tell the activity manager we have resumed.
             if (reallyResume) {
                 try {
-                    ActivityManagerNative.getDefault().activityResumed(token);
+                    ActivityManager.getService().activityResumed(token);
                 } catch (RemoteException ex) {
                     throw ex.rethrowFromSystemServer();
                 }
@@ -3648,7 +3659,7 @@
             // If an exception was thrown when trying to resume, then
             // just end this activity.
             try {
-                ActivityManagerNative.getDefault()
+                ActivityManager.getService()
                     .finishActivity(token, Activity.RESULT_CANCELED, null,
                             Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
             } catch (RemoteException ex) {
@@ -3737,7 +3748,7 @@
             // Tell the activity manager we have paused.
             if (!dontReport) {
                 try {
-                    ActivityManagerNative.getDefault().activityPaused(token);
+                    ActivityManager.getService().activityPaused(token);
                 } catch (RemoteException ex) {
                     throw ex.rethrowFromSystemServer();
                 }
@@ -3835,7 +3846,7 @@
             // Tell activity manager we have been stopped.
             try {
                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
-                ActivityManagerNative.getDefault().activityStopped(
+                ActivityManager.getService().activityStopped(
                     activity.token, state, persistentState, description);
             } catch (RemoteException ex) {
                 if (ex instanceof TransactionTooLargeException
@@ -4090,7 +4101,7 @@
 
             // Tell activity manager we slept.
             try {
-                ActivityManagerNative.getDefault().activitySlept(r.token);
+                ActivityManager.getService().activitySlept(r.token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -4344,7 +4355,7 @@
         }
         if (finishing) {
             try {
-                ActivityManagerNative.getDefault().activityDestroyed(token);
+                ActivityManager.getService().activityDestroyed(token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
@@ -4386,7 +4397,7 @@
                     // For each relaunch request, activity manager expects an answer
                     if (!r.onlyLocalRequest && fromServer) {
                         try {
-                            ActivityManagerNative.getDefault().activityRelaunched(token);
+                            ActivityManager.getService().activityRelaunched(token);
                         } catch (RemoteException e) {
                             throw e.rethrowFromSystemServer();
                         }
@@ -4512,7 +4523,7 @@
         if (r == null) {
             if (!tmp.onlyLocalRequest) {
                 try {
-                    ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
+                    ActivityManager.getService().activityRelaunched(tmp.token);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
@@ -4585,7 +4596,7 @@
 
         if (!tmp.onlyLocalRequest) {
             try {
-                ActivityManagerNative.getDefault().activityRelaunched(r.token);
+                ActivityManager.getService().activityRelaunched(r.token);
                 if (r.window != null) {
                     r.window.reportActivityRelaunched();
                 }
@@ -4950,7 +4961,7 @@
             Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
         }
         try {
-            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
+            ActivityManager.getService().dumpHeapFinished(dhd.path);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -5242,7 +5253,14 @@
         }
         updateDefaultDensity();
 
-        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
+        final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
+        Boolean is24Hr = null;
+        if (use24HourSetting != null) {
+            is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
+        }
+        // null : use locale default for 12/24 hour formatting,
+        // false : use 12 hour format,
+        // true : use 24 hour format.
         DateFormat.set24HourTimePref(is24Hr);
 
         View.mDebugViewAttributes =
@@ -5294,7 +5312,7 @@
                 Slog.w(TAG, "Application " + data.info.getPackageName()
                       + " is waiting for the debugger on port 8100...");
 
-                IActivityManager mgr = ActivityManagerNative.getDefault();
+                IActivityManager mgr = ActivityManager.getService();
                 try {
                     mgr.showWaitingForDebugger(mAppThread, true);
                 } catch (RemoteException ex) {
@@ -5488,12 +5506,12 @@
     }
 
     /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (mProfiler.profileFile != null && mProfiler.handlingProfiling
                 && mProfiler.profileFd == null) {
             Debug.stopMethodTracing();
         }
-        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
+        //Slog.i(TAG, "am: " + ActivityManager.getService()
         //      + ", app thr: " + mAppThread);
         try {
             am.finishInstrumentation(mAppThread, resultCode, results);
@@ -5524,7 +5542,7 @@
         }
 
         try {
-            ActivityManagerNative.getDefault().publishContentProviders(
+            ActivityManager.getService().publishContentProviders(
                 getApplicationThread(), results);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -5546,7 +5564,7 @@
         // be re-entrant in the case where the provider is in the same process.
         ContentProviderHolder holder = null;
         try {
-            holder = ActivityManagerNative.getDefault().getContentProvider(
+            holder = ActivityManager.getService().getContentProvider(
                     getApplicationThread(), auth, userId, stable);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
@@ -5592,7 +5610,7 @@
                                 + prc.holder.info.name + ": unstableDelta="
                                 + unstableDelta);
                     }
-                    ActivityManagerNative.getDefault().refContentProvider(
+                    ActivityManager.getService().refContentProvider(
                             prc.holder.connection, 1, unstableDelta);
                 } catch (RemoteException e) {
                     //do nothing content provider object is dead any way
@@ -5621,7 +5639,7 @@
                             Slog.v(TAG, "incProviderRef: Now unstable - "
                                     + prc.holder.info.name);
                         }
-                        ActivityManagerNative.getDefault().refContentProvider(
+                        ActivityManager.getService().refContentProvider(
                                 prc.holder.connection, 0, 1);
                     } catch (RemoteException e) {
                         //do nothing content provider object is dead any way
@@ -5695,7 +5713,7 @@
                             Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
                                     + lastRef + " - " + prc.holder.info.name);
                         }
-                        ActivityManagerNative.getDefault().refContentProvider(
+                        ActivityManager.getService().refContentProvider(
                                 prc.holder.connection, -1, lastRef ? 1 : 0);
                     } catch (RemoteException e) {
                         //do nothing content provider object is dead any way
@@ -5719,7 +5737,7 @@
                                 Slog.v(TAG, "releaseProvider: No longer unstable - "
                                         + prc.holder.info.name);
                             }
-                            ActivityManagerNative.getDefault().refContentProvider(
+                            ActivityManager.getService().refContentProvider(
                                     prc.holder.connection, 0, -1);
                         } catch (RemoteException e) {
                             //do nothing content provider object is dead any way
@@ -5783,10 +5801,10 @@
 
         try {
             if (DEBUG_PROVIDER) {
-                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
+                Slog.v(TAG, "removeProvider: Invoking ActivityManagerService."
                         + "removeContentProvider(" + prc.holder.info.name + ")");
             }
-            ActivityManagerNative.getDefault().removeContentProvider(
+            ActivityManager.getService().removeContentProvider(
                     prc.holder.connection, false);
         } catch (RemoteException e) {
             //do nothing content provider object is dead any way
@@ -5820,7 +5838,7 @@
                 // it knows it is dead (so we don't race with its death
                 // notification).
                 try {
-                    ActivityManagerNative.getDefault().unstableProviderDied(
+                    ActivityManager.getService().unstableProviderDied(
                             prc.holder.connection);
                 } catch (RemoteException e) {
                     //do nothing content provider object is dead any way
@@ -5834,7 +5852,7 @@
             ProviderRefCount prc = mProviderRefCountMap.get(provider);
             if (prc != null) {
                 try {
-                    ActivityManagerNative.getDefault()
+                    ActivityManager.getService()
                             .appNotRespondingViaProvider(prc.holder.connection);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -5992,7 +6010,7 @@
                     if (!noReleaseNeeded) {
                         incProviderRefLocked(prc, stable);
                         try {
-                            ActivityManagerNative.getDefault().removeContentProvider(
+                            ActivityManager.getService().removeContentProvider(
                                     holder.connection, stable);
                         } catch (RemoteException e) {
                             //do nothing content provider object is dead any way
@@ -6029,7 +6047,7 @@
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                     UserHandle.myUserId());
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
-            final IActivityManager mgr = ActivityManagerNative.getDefault();
+            final IActivityManager mgr = ActivityManager.getService();
             try {
                 mgr.attachApplication(mAppThread);
             } catch (RemoteException ex) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index ec21882..af41db0 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -37,6 +37,8 @@
 import android.view.Window;
 import android.widget.ImageView;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -570,16 +572,9 @@
     protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) {
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver().addOnPreDrawListener(
-                    new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            notifySharedElementEnd(snapshots);
-                            return true;
-                        }
-                    }
-            );
+            OneShotPreDrawListener.add(decorView, () -> {
+                notifySharedElementEnd(snapshots);
+            });
         }
     }
 
@@ -816,6 +811,7 @@
                 if (moveWithParent && !isInTransitionGroup(parent, decor)) {
                     GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
                     parent.getViewTreeObserver().addOnPreDrawListener(listener);
+                    parent.addOnAttachStateChangeListener(listener);
                     mGhostViewListeners.add(listener);
                 }
             }
@@ -842,8 +838,7 @@
         int numListeners = mGhostViewListeners.size();
         for (int i = 0; i < numListeners; i++) {
             GhostViewListeners listener = mGhostViewListeners.get(i);
-            ViewGroup parent = (ViewGroup) listener.getView().getParent();
-            parent.getViewTreeObserver().removeOnPreDrawListener(listener);
+            listener.removeListener();
         }
         mGhostViewListeners.clear();
 
@@ -874,15 +869,9 @@
     protected void scheduleGhostVisibilityChange(final int visibility) {
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver()
-                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            setGhostVisibility(visibility);
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(decorView, () -> {
+                setGhostVisibility(visibility);
+            });
         }
     }
 
@@ -988,16 +977,19 @@
         }
     }
 
-    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener {
+    private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener,
+            View.OnAttachStateChangeListener {
         private View mView;
         private ViewGroup mDecor;
         private View mParent;
         private Matrix mMatrix = new Matrix();
+        private ViewTreeObserver mViewTreeObserver;
 
         public GhostViewListeners(View view, View parent, ViewGroup decor) {
             mView = view;
             mParent = parent;
             mDecor = decor;
+            mViewTreeObserver = parent.getViewTreeObserver();
         }
 
         public View getView() {
@@ -1008,13 +1000,32 @@
         public boolean onPreDraw() {
             GhostView ghostView = GhostView.getGhost(mView);
             if (ghostView == null) {
-                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
+                removeListener();
             } else {
                 GhostView.calculateMatrix(mView, mDecor, mMatrix);
                 ghostView.setMatrix(mMatrix);
             }
             return true;
         }
+
+        public void removeListener() {
+            if (mViewTreeObserver.isAlive()) {
+                mViewTreeObserver.removeOnPreDrawListener(this);
+            } else {
+                mParent.getViewTreeObserver().removeOnPreDrawListener(this);
+            }
+            mParent.removeOnAttachStateChangeListener(this);
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+            mViewTreeObserver = v.getViewTreeObserver();
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            removeListener();
+        }
     }
 
     static class SharedElementOriginalState {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index 60046b5..f2616ff 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -22,9 +22,10 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.view.Window;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
@@ -321,18 +322,12 @@
                 }
                 if (delayExitBack && decor != null) {
                     final ViewGroup finalDecor = decor;
-                    decor.getViewTreeObserver().addOnPreDrawListener(
-                            new ViewTreeObserver.OnPreDrawListener() {
-                                @Override
-                                public boolean onPreDraw() {
-                                    finalDecor.getViewTreeObserver().removeOnPreDrawListener(this);
-                                    if (mReturnExitCoordinator != null) {
-                                        mReturnExitCoordinator.startExit(activity.mResultCode,
-                                                activity.mResultData);
-                                    }
-                                    return true;
-                                }
-                            });
+                    OneShotPreDrawListener.add(decor, () -> {
+                        if (mReturnExitCoordinator != null) {
+                            mReturnExitCoordinator.startExit(activity.mResultCode,
+                                    activity.mResultData);
+                        }
+                    });
                 } else {
                     mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData);
                 }
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index cada1b8..29b83dc 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -152,7 +152,7 @@
 
         try {
             mActivityContainer = new ActivityContainerWrapper(
-                    ActivityManagerNative.getDefault().createVirtualActivityContainer(
+                    ActivityManager.getService().createVirtualActivityContainer(
                             mActivity.getActivityToken(), new ActivityContainerCallback(this)));
         } catch (RemoteException e) {
             throw new RuntimeException("ActivityView: Unable to create ActivityContainer. "
diff --git a/core/java/android/app/AppImportanceMonitor.java b/core/java/android/app/AppImportanceMonitor.java
index e0d0d8d..b5cbeeb 100644
--- a/core/java/android/app/AppImportanceMonitor.java
+++ b/core/java/android/app/AppImportanceMonitor.java
@@ -86,7 +86,7 @@
         };
         ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
         try {
-            ActivityManagerNative.getDefault().registerProcessObserver(mProcessObserver);
+            ActivityManager.getService().registerProcessObserver(mProcessObserver);
         } catch (RemoteException e) {
         }
         List<ActivityManager.RunningAppProcessInfo> apps = am.getRunningAppProcesses();
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 6a73829..ef2db4a 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -16,17 +16,19 @@
 
 package android.app;
 
+import android.os.Build;
 import android.os.Trace;
 import android.util.ArrayMap;
 import com.android.internal.os.PathClassLoaderFactory;
 import dalvik.system.PathClassLoader;
 
-class ApplicationLoaders {
+/** @hide */
+public class ApplicationLoaders {
     public static ApplicationLoaders getDefault() {
         return gApplicationLoaders;
     }
 
-    public ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
+    ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                       String librarySearchPath, String libraryPermittedPath,
                                       ClassLoader parent) {
         /*
@@ -80,6 +82,19 @@
         }
     }
 
+    /**
+     * Creates a classloader for the WebView APK and places it in the cache of loaders maintained
+     * by this class. This is used in the WebView zygote, where its presence in the cache speeds up
+     * startup and enables memory sharing.
+     */
+    public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) {
+      // The correct paths are calculated by WebViewZygote in the system server and passed to
+      // us here. We hardcode the other parameters: WebView always targets the current SDK,
+      // does not need to use non-public system libraries, and uses the base classloader as its
+      // parent to permit usage of the cache.
+      return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null);
+    }
+
     private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
 
     /**
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 3b3e070..b199984 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -698,7 +698,13 @@
     @SuppressWarnings("unchecked")
     @Override
     public List<ApplicationInfo> getInstalledApplications(int flags) {
-        final int userId = mContext.getUserId();
+        return getInstalledApplicationsAsUser(flags, mContext.getUserId());
+    }
+
+    /** @hide */
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
         try {
             ParceledListSlice<ApplicationInfo> parceledList =
                     mPM.getInstalledApplications(flags, userId);
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 6b16e8f..e222fee 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -764,7 +764,7 @@
         }
         if (!mAllowOptimization) {
             // Added fragments are added at the end to comply with prior behavior.
-            mManager.moveToState(mManager.mCurState);
+            mManager.moveToState(mManager.mCurState, true);
         }
     }
 
@@ -810,7 +810,7 @@
             }
         }
         if (!mAllowOptimization) {
-            mManager.moveToState(mManager.mCurState);
+            mManager.moveToState(mManager.mCurState, true);
         }
     }
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c5180fd..496c05f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -33,7 +33,6 @@
 import android.content.ReceiverCallNotAllowedException;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -61,7 +60,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;
@@ -160,7 +159,7 @@
     private final String mOpPackageName;
 
     private final @NonNull ResourcesManager mResourcesManager;
-    private final @NonNull Resources mResources;
+    private @NonNull Resources mResources;
     private @Nullable Display mDisplay; // may be null if default display
 
     private final int mFlags;
@@ -798,7 +797,7 @@
     @Override
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         try {
-            ActivityManagerNative.getDefault().startActivityAsUser(
+            ActivityManager.getService().startActivityAsUser(
                 mMainThread.getApplicationThread(), getBasePackageName(), intent,
                 intent.resolveTypeIfNeeded(getContentResolver()),
                 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options,
@@ -860,7 +859,7 @@
                 fillInIntent.prepareToLeaveProcess(this);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
                         fillInIntent, resolvedType, null, null,
                         0, flagsMask, flagsValues, options);
@@ -879,7 +878,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                     getUserId());
@@ -896,7 +895,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, false, false, getUserId());
@@ -911,7 +910,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, false, false, getUserId());
@@ -928,7 +927,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     options, false, false, getUserId());
@@ -945,7 +944,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
                     getUserId());
@@ -962,7 +961,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     null, true, false, getUserId());
@@ -1025,7 +1024,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermissions, appOp,
                     options, true, false, getUserId());
@@ -1039,7 +1038,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
+            ActivityManager.getService().broadcastIntent(mMainThread.getApplicationThread(),
                     intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
                     AppOpsManager.OP_NONE, null, false, false, user.getIdentifier());
         } catch (RemoteException e) {
@@ -1061,7 +1060,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
                     options, false, false, user.getIdentifier());
@@ -1078,7 +1077,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                     mMainThread.getApplicationThread(), intent, resolvedType, null,
                     Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
                     user.getIdentifier());
@@ -1129,7 +1128,7 @@
                 : new String[] {receiverPermission};
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermissions,
                     appOp, options, true, false, user.getIdentifier());
@@ -1145,7 +1144,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
                 getUserId());
@@ -1181,7 +1180,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
                     AppOpsManager.OP_NONE, null, true, true, getUserId());
@@ -1200,7 +1199,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1213,7 +1212,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
                     user.getIdentifier());
@@ -1228,7 +1227,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, options, false, true,
                 user.getIdentifier());
@@ -1263,7 +1262,7 @@
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().broadcastIntent(
+            ActivityManager.getService().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
                     AppOpsManager.OP_NONE, null, true, true, user.getIdentifier());
@@ -1282,7 +1281,7 @@
         }
         try {
             intent.prepareToLeaveProcess(this);
-            ActivityManagerNative.getDefault().unbroadcastIntent(
+            ActivityManager.getService().unbroadcastIntent(
                     mMainThread.getApplicationThread(), intent, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1329,7 +1328,7 @@
             }
         }
         try {
-            final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
+            final Intent intent = ActivityManager.getService().registerReceiver(
                     mMainThread.getApplicationThread(), mBasePackageName,
                     rd, filter, broadcastPermission, userId);
             if (intent != null) {
@@ -1348,7 +1347,7 @@
             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
                     getOuterContext(), receiver);
             try {
-                ActivityManagerNative.getDefault().unregisterReceiver(rd);
+                ActivityManager.getService().unregisterReceiver(rd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1391,7 +1390,7 @@
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
-            ComponentName cn = ActivityManagerNative.getDefault().startService(
+            ComponentName cn = ActivityManager.getService().startService(
                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                             getContentResolver()), getOpPackageName(), user.getIdentifier());
             if (cn != null) {
@@ -1420,7 +1419,7 @@
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
-            int res = ActivityManagerNative.getDefault().stopService(
+            int res = ActivityManager.getService().stopService(
                 mMainThread.getApplicationThread(), service,
                 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
             if (res < 0) {
@@ -1492,7 +1491,7 @@
                 flags |= BIND_WAIVE_PRIORITY;
             }
             service.prepareToLeaveProcess(this);
-            int res = ActivityManagerNative.getDefault().bindService(
+            int res = ActivityManager.getService().bindService(
                 mMainThread.getApplicationThread(), getActivityToken(), service,
                 service.resolveTypeIfNeeded(getContentResolver()),
                 sd, flags, getOpPackageName(), user.getIdentifier());
@@ -1515,7 +1514,7 @@
             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
                     getOuterContext(), conn);
             try {
-                ActivityManagerNative.getDefault().unbindService(sd);
+                ActivityManager.getService().unbindService(sd);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -1531,7 +1530,7 @@
             if (arguments != null) {
                 arguments.setAllowFds(false);
             }
-            return ActivityManagerNative.getDefault().startInstrumentation(
+            return ActivityManager.getService().startInstrumentation(
                     className, profileFile, 0, arguments, null, null, getUserId(),
                     null /* ABI override */);
         } catch (RemoteException e) {
@@ -1556,7 +1555,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermission(
+            return ActivityManager.getService().checkPermission(
                     permission, pid, uid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1571,7 +1570,7 @@
         }
 
         try {
-            return ActivityManagerNative.getDefault().checkPermissionWithToken(
+            return ActivityManager.getService().checkPermissionWithToken(
                     permission, pid, uid, callerToken);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1656,7 +1655,7 @@
     @Override
     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
          try {
-            ActivityManagerNative.getDefault().grantUriPermission(
+            ActivityManager.getService().grantUriPermission(
                     mMainThread.getApplicationThread(), toPackage,
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
@@ -1667,7 +1666,7 @@
     @Override
     public void revokeUriPermission(Uri uri, int modeFlags) {
          try {
-            ActivityManagerNative.getDefault().revokeUriPermission(
+            ActivityManager.getService().revokeUriPermission(
                     mMainThread.getApplicationThread(),
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
@@ -1678,7 +1677,7 @@
     @Override
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
         try {
-            return ActivityManagerNative.getDefault().checkUriPermission(
+            return ActivityManager.getService().checkUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
                     resolveUserId(uri), null);
         } catch (RemoteException e) {
@@ -1690,7 +1689,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) {
@@ -1835,6 +1834,19 @@
         }
     }
 
+    private static Resources createResources(IBinder activityToken, LoadedApk pi, int displayId,
+            Configuration overrideConfig, CompatibilityInfo compatInfo) {
+        return ResourcesManager.getInstance().getResources(activityToken,
+                pi.getResDir(),
+                pi.getSplitResDirs(),
+                pi.getOverlayDirs(),
+                pi.getApplicationInfo().sharedLibraryFiles,
+                displayId,
+                overrideConfig,
+                compatInfo,
+                pi.getClassLoader());
+    }
+
     @Override
     public Context createApplicationContext(ApplicationInfo application, int flags)
             throws NameNotFoundException {
@@ -1842,8 +1854,13 @@
                 flags | CONTEXT_REGISTER_PACKAGE);
         if (pi != null) {
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
-                    new UserHandle(UserHandle.getUserId(application.uid)), flags,
-                    mDisplay, null, Display.INVALID_DISPLAY);
+                    new UserHandle(UserHandle.getUserId(application.uid)), flags);
+
+            final int displayId = mDisplay != null
+                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+
+            c.mResources = createResources(mActivityToken, pi, displayId, null,
+                    getDisplayAdjustments(displayId).getCompatibilityInfo());
             if (c.mResources != null) {
                 return c;
             }
@@ -1864,15 +1881,21 @@
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
         if (packageName.equals("system") || packageName.equals("android")) {
-            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
+            // The system resources are loaded in every application, so we can safely copy
+            // the context without reloading Resources.
+            return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, user, flags);
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
-            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
-                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
+            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, user, flags);
+
+            final int displayId = mDisplay != null
+                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+
+            c.mResources = createResources(mActivityToken, pi, displayId, null,
+                    getDisplayAdjustments(displayId).getCompatibilityInfo());
             if (c.mResources != null) {
                 return c;
             }
@@ -1889,8 +1912,14 @@
             throw new IllegalArgumentException("overrideConfiguration must not be null");
         }
 
-        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mFlags, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
+        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mFlags);
+
+        final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+        context.mResources = createResources(mActivityToken, mPackageInfo, displayId,
+                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo());
+        context.mDisplay = mDisplay;
+        return context;
     }
 
     @Override
@@ -1899,24 +1928,28 @@
             throw new IllegalArgumentException("display must not be null");
         }
 
-        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mFlags, display, null, Display.INVALID_DISPLAY);
+        ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, mFlags);
+
+        final int displayId = display.getDisplayId();
+        context.mResources = createResources(mActivityToken, mPackageInfo, displayId, null,
+                getDisplayAdjustments(displayId).getCompatibilityInfo());
+        context.mDisplay = display;
+        return context;
     }
 
     @Override
     public Context createDeviceProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
                 | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
-        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
+        return new ContextImplFlagContextWrapper(this, flags);
     }
 
     @Override
     public Context createCredentialProtectedStorageContext() {
         final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
                 | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
-        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
+        return new ContextImplFlagContextWrapper(this, flags);
     }
 
     @Override
@@ -2003,8 +2036,8 @@
 
     static ContextImpl createSystemContext(ActivityThread mainThread) {
         LoadedApk packageInfo = new LoadedApk(mainThread);
-        ContextImpl context = new ContextImpl(null, mainThread,
-                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
+        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0);
+        context.mResources = packageInfo.getResources(mainThread);
         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                 context.mResourcesManager.getDisplayMetrics());
         return context;
@@ -2012,21 +2045,35 @@
 
     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
-        return new ContextImpl(null, mainThread,
-                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
+        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0);
+        context.mResources = packageInfo.getResources(mainThread);
+        return context;
     }
 
     static ContextImpl createActivityContext(ActivityThread mainThread,
             LoadedApk packageInfo, IBinder activityToken, int displayId,
             Configuration overrideConfiguration) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
-        return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0,
-                null, overrideConfiguration, displayId);
+
+        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityToken, null,
+                0);
+
+        // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
+        displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
+
+        final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
+                ? packageInfo.getCompatibilityInfo()
+                : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+
+        context.mResources = createResources(activityToken, packageInfo, displayId,
+                overrideConfiguration, compatInfo);
+        context.mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(displayId,
+                context.mResources.getDisplayAdjustments());
+        return context;
     }
 
     private ContextImpl(ContextImpl container, ActivityThread mainThread,
-            LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,
-            Display display, Configuration overrideConfiguration, int createDisplayWithId) {
+            LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags) {
         mOuterContext = this;
 
         // If creator didn't specify which storage to use, use the default
@@ -2053,64 +2100,11 @@
         mPackageInfo = packageInfo;
         mResourcesManager = ResourcesManager.getInstance();
 
-        final int displayId = (createDisplayWithId != Display.INVALID_DISPLAY)
-                ? createDisplayWithId
-                : (display != null) ? display.getDisplayId() : Display.DEFAULT_DISPLAY;
-
-        CompatibilityInfo compatInfo = null;
-        if (container != null) {
-            compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo();
-        }
-        if (compatInfo == null) {
-            compatInfo = (displayId == Display.DEFAULT_DISPLAY)
-                    ? packageInfo.getCompatibilityInfo()
-                    : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-        }
-
-        Resources resources = packageInfo.getResources(mainThread);
-        if (resources != null) {
-            if (displayId != Display.DEFAULT_DISPLAY
-                    || overrideConfiguration != null
-                    || (compatInfo != null && compatInfo.applicationScale
-                            != resources.getCompatibilityInfo().applicationScale)) {
-
-                if (container != null) {
-                    // This is a nested Context, so it can't be a base Activity context.
-                    // Just create a regular Resources object associated with the Activity.
-                    resources = mResourcesManager.getResources(
-                            activityToken,
-                            packageInfo.getResDir(),
-                            packageInfo.getSplitResDirs(),
-                            packageInfo.getOverlayDirs(),
-                            packageInfo.getApplicationInfo().sharedLibraryFiles,
-                            displayId,
-                            overrideConfiguration,
-                            compatInfo,
-                            packageInfo.getClassLoader());
-                } else {
-                    // This is not a nested Context, so it must be the root Activity context.
-                    // All other nested Contexts will inherit the configuration set here.
-                    resources = mResourcesManager.createBaseActivityResources(
-                            activityToken,
-                            packageInfo.getResDir(),
-                            packageInfo.getSplitResDirs(),
-                            packageInfo.getOverlayDirs(),
-                            packageInfo.getApplicationInfo().sharedLibraryFiles,
-                            displayId,
-                            overrideConfiguration,
-                            compatInfo,
-                            packageInfo.getClassLoader());
-                }
-            }
-        }
-        mResources = resources;
-
-        mDisplay = (createDisplayWithId == Display.INVALID_DISPLAY) ? display
-                : mResourcesManager.getAdjustedDisplay(displayId, mResources.getDisplayAdjustments());
-
         if (container != null) {
             mBasePackageName = container.mBasePackageName;
             mOpPackageName = container.mOpPackageName;
+            mResources = container.getResources();
+            mDisplay = container.getDisplay();
         } else {
             mBasePackageName = packageInfo.mPackageName;
             ApplicationInfo ainfo = packageInfo.getApplicationInfo();
@@ -2213,10 +2207,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/ContextImplFlagContextWrapper.java b/core/java/android/app/ContextImplFlagContextWrapper.java
new file mode 100644
index 0000000..a83f130
--- /dev/null
+++ b/core/java/android/app/ContextImplFlagContextWrapper.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 android.app;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+
+class ContextImplFlagContextWrapper extends ContextWrapper {
+    private final int mFlags;
+
+    public ContextImplFlagContextWrapper(Context base, int flags) {
+        super(base);
+        mFlags = flags;
+    }
+
+    @Override
+    public boolean isRestricted() {
+        return (mFlags & Context.CONTEXT_RESTRICTED) != 0;
+    }
+
+    @Override
+    public boolean isDeviceProtectedStorage() {
+        return (mFlags & Context.CONTEXT_DEVICE_PROTECTED_STORAGE) != 0;
+    }
+
+    @Override
+    public boolean isCredentialProtectedStorage() {
+        return (mFlags & Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) != 0;
+    }
+}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 27a0200..3464c4d 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -30,10 +30,11 @@
 import android.view.ViewGroup;
 import android.view.ViewGroupOverlay;
 import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 
 /**
@@ -58,7 +59,7 @@
     private boolean mAreViewsReady;
     private boolean mIsViewsTransitionStarted;
     private Transition mEnterViewsTransition;
-    private OnPreDrawListener mViewsReadyListener;
+    private OneShotPreDrawListener mViewsReadyListener;
     private final boolean mIsCrossTask;
 
     public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
@@ -74,12 +75,17 @@
         mResultReceiver.send(MSG_SET_REMOTE_RECEIVER, resultReceiverBundle);
         final View decorView = getDecor();
         if (decorView != null) {
-            decorView.getViewTreeObserver().addOnPreDrawListener(
+            final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
+            viewTreeObserver.addOnPreDrawListener(
                     new ViewTreeObserver.OnPreDrawListener() {
                         @Override
                         public boolean onPreDraw() {
                             if (mIsReadyForTransition) {
-                                decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                                if (viewTreeObserver.isAlive()) {
+                                    viewTreeObserver.removeOnPreDrawListener(this);
+                                } else {
+                                    decorView.getViewTreeObserver().removeOnPreDrawListener(this);
+                                }
                             }
                             return mIsReadyForTransition;
                         }
@@ -147,16 +153,10 @@
                 (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()))) {
             viewsReady(sharedElements);
         } else {
-            mViewsReadyListener = new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    mViewsReadyListener = null;
-                    decor.getViewTreeObserver().removeOnPreDrawListener(this);
-                    viewsReady(sharedElements);
-                    return true;
-                }
-            };
-            decor.getViewTreeObserver().addOnPreDrawListener(mViewsReadyListener);
+            mViewsReadyListener = OneShotPreDrawListener.add(decor, () -> {
+                mViewsReadyListener = null;
+                viewsReady(sharedElements);
+            });
             decor.invalidate();
         }
     }
@@ -206,19 +206,13 @@
             moveSharedElementsToOverlay();
             mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
         } else if (decorView != null) {
-            decorView.getViewTreeObserver()
-                    .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            if (mResultReceiver != null) {
-                                Bundle state = captureSharedElementState();
-                                moveSharedElementsToOverlay();
-                                mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
-                            }
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(decorView, () -> {
+                if (mResultReceiver != null) {
+                    Bundle state = captureSharedElementState();
+                    moveSharedElementsToOverlay();
+                    mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state);
+                }
+            });
         }
         if (allowOverlappingTransitions()) {
             startEnterTransitionOnly();
@@ -271,7 +265,7 @@
             mIsReadyForTransition = true;
             final ViewGroup decor = getDecor();
             if (decor != null && mViewsReadyListener != null) {
-                decor.getViewTreeObserver().removeOnPreDrawListener(mViewsReadyListener);
+                mViewsReadyListener.removeListener();
                 mViewsReadyListener = null;
             }
             showViews(mTransitioningViews, true);
@@ -457,20 +451,11 @@
             public void onSharedElementsReady() {
                 final View decorView = getDecor();
                 if (decorView != null) {
-                    decorView.getViewTreeObserver()
-                            .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                                @Override
-                                public boolean onPreDraw() {
-                                    decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                                    startTransition(new Runnable() {
-                                        @Override
-                                        public void run() {
-                                            startSharedElementTransition(sharedElementState);
-                                        }
-                                    });
-                                    return false;
-                                }
-                            });
+                    OneShotPreDrawListener.add(decorView, () -> {
+                        startTransition(() -> {
+                                startSharedElementTransition(sharedElementState);
+                        });
+                    });
                     decorView.invalidate();
                 }
             }
diff --git a/core/java/android/app/EphemeralResolverService.java b/core/java/android/app/EphemeralResolverService.java
index d8d7340..45652ef 100644
--- a/core/java/android/app/EphemeralResolverService.java
+++ b/core/java/android/app/EphemeralResolverService.java
@@ -68,16 +68,23 @@
     /**
      * Called to retrieve intent filters for ephemeral applications.
      *
-     * @param digestPrefix The hash prefix of the ephemeral's domain.
+     * @param hostName The name of the host to get intent filters for.
      */
-    public List<EphemeralResolveInfo> onGetEphemeralIntentFilter(int digestPrefix[]) {
+    public EphemeralResolveInfo onGetEphemeralIntentFilter(String hostName) {
         throw new IllegalStateException("Must define");
     }
 
+    /**
+     * Returns a {@link Looper} to perform service operations on.
+     */
+    public Looper getLooper() {
+        return getBaseContext().getMainLooper();
+    }
+
     @Override
     public final void attachBaseContext(Context base) {
         super.attachBaseContext(base);
-        mHandler = new ServiceHandler(base.getMainLooper());
+        mHandler = new ServiceHandler(getLooper());
     }
 
     @Override
@@ -96,11 +103,11 @@
 
             @Override
             public void getEphemeralIntentFilterList(
-                    IRemoteCallback callback, int digestPrefix[], int sequence) {
+                    IRemoteCallback callback, String hostName, int sequence) {
                 final Message msg = mHandler.obtainMessage(
                         ServiceHandler.MSG_GET_EPHEMERAL_INTENT_FILTER, sequence, 0, callback);
                 final Bundle data = new Bundle();
-                data.putIntArray(EXTRA_PREFIX, digestPrefix);
+                data.putString(EXTRA_HOSTNAME, hostName);
                 msg.setData(data);
                 msg.sendToTarget();
             }
@@ -136,12 +143,11 @@
 
                 case MSG_GET_EPHEMERAL_INTENT_FILTER: {
                     final IRemoteCallback callback = (IRemoteCallback) message.obj;
-                    final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX);
-                    final List<EphemeralResolveInfo> resolveInfo =
-                            onGetEphemeralIntentFilter(digestPrefix);
+                    final String hostName = message.getData().getString(EXTRA_HOSTNAME);
+                    final EphemeralResolveInfo resolveInfo = onGetEphemeralIntentFilter(hostName);
                     final Bundle data = new Bundle();
                     data.putInt(EXTRA_SEQUENCE, message.arg1);
-                    data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo);
+                    data.putParcelable(EXTRA_RESOLVE_INFO, resolveInfo);
                     try {
                         callback.sendResult(data);
                     } catch (RemoteException e) {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index b5b6e4a..6a79e6c 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -34,9 +34,10 @@
 import android.transition.TransitionManager;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 import android.view.Window;
 
+import com.android.internal.view.OneShotPreDrawListener;
+
 import java.util.ArrayList;
 
 /**
@@ -168,15 +169,9 @@
         });
         final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
                 mSharedElementNames);
-        decorView.getViewTreeObserver()
-                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        decorView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
-                        return true;
-                    }
-                });
+        OneShotPreDrawListener.add(decorView, () -> {
+            setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
+        });
         setGhostVisibility(View.INVISIBLE);
         scheduleGhostVisibilityChange(View.INVISIBLE);
         if (mListener != null) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 8124232..10ab2bc 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -414,6 +414,10 @@
     // True if this fragment has been restored from previously saved state.
     boolean mRestored;
 
+    // True if performCreateView has been called and a matching call to performDestroyView
+    // has not yet happened.
+    boolean mPerformedCreateView;
+
     // Number of active back stack entries this fragment is in.
     int mBackStackNesting;
 
@@ -611,7 +615,7 @@
             Fragment f = (Fragment)clazz.newInstance();
             if (args != null) {
                 args.setClassLoader(f.getClass().getClassLoader());
-                f.mArguments = args;
+                f.setArguments(args);
             }
             return f;
         } catch (ClassNotFoundException e) {
@@ -2464,6 +2468,7 @@
         if (mChildFragmentManager != null) {
             mChildFragmentManager.noteStateNotSaved();
         }
+        mPerformedCreateView = true;
         return onCreateView(inflater, container, savedInstanceState);
     }
 
@@ -2690,6 +2695,7 @@
         if (mLoaderManager != null) {
             mLoaderManager.doReportNextStart();
         }
+        mPerformedCreateView = false;
     }
 
     void performDestroy() {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 5a2c5e7..9ea3f83 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -387,7 +387,7 @@
      * Callback interface for listening to fragment state changes that happen
      * within a given FragmentManager.
      */
-    public abstract class FragmentLifecycleCallbacks {
+    public abstract static class FragmentLifecycleCallbacks {
         /**
          * Called right before the fragment's {@link Fragment#onAttach(Context)} method is called.
          * This is a good time to inject any required dependencies for the fragment before any of
@@ -1072,7 +1072,7 @@
         if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {
             newState = Fragment.STOPPED;
         }
-        if (f.mState < newState) {
+        if (f.mState <= newState) {
             // For fragments that are created from a layout, when restoring from
             // state we don't want to allow them to be created until they are
             // being reloaded from the layout.
@@ -1089,65 +1089,59 @@
             }
             switch (f.mState) {
                 case Fragment.INITIALIZING:
-                    if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
-                    if (f.mSavedFragmentState != null) {
-                        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
-                                FragmentManagerImpl.VIEW_STATE_TAG);
-                        f.mTarget = getFragment(f.mSavedFragmentState,
-                                FragmentManagerImpl.TARGET_STATE_TAG);
-                        if (f.mTarget != null) {
-                            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
-                                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
-                        }
-                        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
-                                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
-                        if (!f.mUserVisibleHint) {
-                            f.mDeferStart = true;
-                            if (newState > Fragment.STOPPED) {
-                                newState = Fragment.STOPPED;
+                    if (newState > Fragment.INITIALIZING) {
+                        if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
+                        if (f.mSavedFragmentState != null) {
+                            f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
+                                    FragmentManagerImpl.VIEW_STATE_TAG);
+                            f.mTarget = getFragment(f.mSavedFragmentState,
+                                    FragmentManagerImpl.TARGET_STATE_TAG);
+                            if (f.mTarget != null) {
+                                f.mTargetRequestCode = f.mSavedFragmentState.getInt(
+                                        FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
+                            }
+                            f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
+                                    FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
+                            if (!f.mUserVisibleHint) {
+                                f.mDeferStart = true;
+                                if (newState > Fragment.STOPPED) {
+                                    newState = Fragment.STOPPED;
+                                }
                             }
                         }
-                    }
-                    f.mHost = mHost;
-                    f.mParentFragment = mParent;
-                    f.mFragmentManager = mParent != null
-                            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
-                    dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
-                    f.mCalled = false;
-                    f.onAttach(mHost.getContext());
-                    if (!f.mCalled) {
-                        throw new SuperNotCalledException("Fragment " + f
-                                + " did not call through to super.onAttach()");
-                    }
-                    if (f.mParentFragment == null) {
-                        mHost.onAttachFragment(f);
-                    } else {
-                        f.mParentFragment.onAttachFragment(f);
-                    }
-                    dispatchOnFragmentAttached(f, mHost.getContext(), false);
-
-                    if (!f.mRetaining) {
-                        f.performCreate(f.mSavedFragmentState);
-                        dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
-                    } else {
-                        f.restoreChildFragmentState(f.mSavedFragmentState, true);
-                        f.mState = Fragment.CREATED;
-                    }
-                    f.mRetaining = false;
-                    if (f.mFromLayout) {
-                        // For fragments that are part of the content view
-                        // layout, we need to instantiate the view immediately
-                        // and the inflater will take care of adding it.
-                        f.mView = f.performCreateView(f.getLayoutInflater(
-                                f.mSavedFragmentState), null, f.mSavedFragmentState);
-                        if (f.mView != null) {
-                            f.mView.setSaveFromParentEnabled(false);
-                            if (f.mHidden) f.mView.setVisibility(View.GONE);
-                            f.onViewCreated(f.mView, f.mSavedFragmentState);
-                            dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
+                        f.mHost = mHost;
+                        f.mParentFragment = mParent;
+                        f.mFragmentManager = mParent != null
+                                ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
+                        dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
+                        f.mCalled = false;
+                        f.onAttach(mHost.getContext());
+                        if (!f.mCalled) {
+                            throw new SuperNotCalledException("Fragment " + f
+                                    + " did not call through to super.onAttach()");
                         }
+                        if (f.mParentFragment == null) {
+                            mHost.onAttachFragment(f);
+                        } else {
+                            f.mParentFragment.onAttachFragment(f);
+                        }
+                        dispatchOnFragmentAttached(f, mHost.getContext(), false);
+
+                        if (!f.mRetaining) {
+                            f.performCreate(f.mSavedFragmentState);
+                            dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
+                        } else {
+                            f.restoreChildFragmentState(f.mSavedFragmentState, true);
+                            f.mState = Fragment.CREATED;
+                        }
+                        f.mRetaining = false;
                     }
                 case Fragment.CREATED:
+                    // This is outside the if statement below on purpose; we want this to run
+                    // even if we do a moveToState from CREATED => *, CREATED => CREATED, and
+                    // * => CREATED as part of the case fallthrough above.
+                    ensureInflatedFragmentView(f);
+
                     if (newState > Fragment.CREATED) {
                         if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
                         if (!f.mFromLayout) {
@@ -1281,6 +1275,7 @@
                         }
                         f.mContainer = null;
                         f.mView = null;
+                        f.mInLayout = false;
                     }
                 case Fragment.CREATED:
                     if (newState < Fragment.CREATED) {
@@ -1340,6 +1335,19 @@
         moveToState(f, mCurState, 0, 0, false);
     }
 
+    void ensureInflatedFragmentView(Fragment f) {
+        if (f.mFromLayout && !f.mPerformedCreateView) {
+            f.mView = f.performCreateView(f.getLayoutInflater(
+                    f.mSavedFragmentState), null, f.mSavedFragmentState);
+            if (f.mView != null) {
+                f.mView.setSaveFromParentEnabled(false);
+                if (f.mHidden) f.mView.setVisibility(View.GONE);
+                f.onViewCreated(f.mView, f.mSavedFragmentState);
+                dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
+            }
+        }
+    }
+
     /**
      * Fragments that have been shown or hidden don't have their visibility changed or
      * animations run during the {@link #showFragment(Fragment)} or {@link #hideFragment(Fragment)}
@@ -1445,11 +1453,24 @@
         }
     }
 
-    void moveToState(int newState) {
+    /**
+     * Changes the state of the fragment manager to {@code newState}. If the fragment manager
+     * changes state or {@code always} is {@code true}, any fragments within it have their
+     * states updated as well.
+     *
+     * @param newState The new state for the fragment manager
+     * @param always If {@code true}, all fragments update their state, even
+     *               if {@code newState} matches the current fragment manager's state.
+     */
+    void moveToState(int newState, boolean always) {
         if (mHost == null && newState != Fragment.INITIALIZING) {
             throw new IllegalStateException("No activity");
         }
 
+        if (!always && mCurState == newState) {
+            return;
+        }
+
         mCurState = newState;
 
         if (mActive != null) {
@@ -2024,7 +2045,7 @@
             // need to run something now
             FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
                     postponeIndex, true);
-            moveToState(mCurState);
+            moveToState(mCurState, true);
         }
 
         for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
@@ -2117,7 +2138,7 @@
             FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true);
         }
         if (moveToState) {
-            moveToState(mCurState);
+            moveToState(mCurState, true);
         } else if (mActive != null) {
             final int numActive = mActive.size();
             for (int i = 0; i < numActive; i++) {
@@ -2691,40 +2712,40 @@
     
     public void dispatchCreate() {
         mStateSaved = false;
-        moveToState(Fragment.CREATED);
+        moveToState(Fragment.CREATED, false);
     }
     
     public void dispatchActivityCreated() {
         mStateSaved = false;
-        moveToState(Fragment.ACTIVITY_CREATED);
+        moveToState(Fragment.ACTIVITY_CREATED, false);
     }
     
     public void dispatchStart() {
         mStateSaved = false;
-        moveToState(Fragment.STARTED);
+        moveToState(Fragment.STARTED, false);
     }
     
     public void dispatchResume() {
         mStateSaved = false;
-        moveToState(Fragment.RESUMED);
+        moveToState(Fragment.RESUMED, false);
     }
     
     public void dispatchPause() {
-        moveToState(Fragment.STARTED);
+        moveToState(Fragment.STARTED, false);
     }
     
     public void dispatchStop() {
-        moveToState(Fragment.STOPPED);
+        moveToState(Fragment.STOPPED, false);
     }
     
     public void dispatchDestroyView() {
-        moveToState(Fragment.CREATED);
+        moveToState(Fragment.CREATED, false);
     }
 
     public void dispatchDestroy() {
         mDestroyed = true;
         execPendingActions();
-        moveToState(Fragment.INITIALIZING);
+        moveToState(Fragment.INITIALIZING, false);
         mHost = null;
         mContainer = null;
         mParent = null;
@@ -3249,7 +3270,9 @@
         }
 
         // If we haven't finished entering the CREATED state ourselves yet,
-        // push the inflated child fragment along.
+        // push the inflated child fragment along. This will ensureInflatedFragmentView
+        // at the right phase of the lifecycle so that we will have mView populated
+        // for compliant fragments below.
         if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
             moveToState(fragment, Fragment.CREATED, 0, 0, false);
         } else {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index d27dff5..088fd08 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -24,7 +24,8 @@
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
+
+import com.android.internal.view.OneShotPreDrawListener;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -320,16 +321,9 @@
                 && exitingFragment.mHidden && exitingFragment.mHiddenChanged) {
             exitingFragment.setHideReplaced(true);
             final View fragmentView = exitingFragment.getView();
-            final ViewGroup container = exitingFragment.mContainer;
-            container.getViewTreeObserver().addOnPreDrawListener(
-                    new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            container.getViewTreeObserver().removeOnPreDrawListener(this);
-                            setViewVisibility(exitingViews, View.INVISIBLE);
-                            return true;
-                        }
-                    });
+            OneShotPreDrawListener.add(exitingFragment.mContainer, () -> {
+                setViewVisibility(exitingViews, View.INVISIBLE);
+            });
             exitTransition.addListener(new Transition.TransitionListenerAdapter() {
                 @Override
                 public void onTransitionEnd(Transition transition) {
@@ -364,30 +358,22 @@
             final Transition enterTransition, final ArrayList<View> enteringViews,
             final Transition exitTransition, final ArrayList<View> exitingViews) {
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            if (enterTransition != null) {
+                enterTransition.removeTarget(nonExistentView);
+                ArrayList<View> views = configureEnteringExitingViews(
+                        enterTransition, inFragment, sharedElementsIn, nonExistentView);
+                enteringViews.addAll(views);
+            }
 
-                        if (enterTransition != null) {
-                            enterTransition.removeTarget(nonExistentView);
-                            ArrayList<View> views = configureEnteringExitingViews(
-                                    enterTransition, inFragment, sharedElementsIn, nonExistentView);
-                            enteringViews.addAll(views);
-                        }
-
-                        if (exitingViews != null) {
-                            ArrayList<View> tempExiting = new ArrayList<>();
-                            tempExiting.add(nonExistentView);
-                            replaceTargets(exitTransition, exitingViews, tempExiting);
-                            exitingViews.clear();
-                            exitingViews.add(nonExistentView);
-                        }
-
-                        return true;
-                    }
-                });
+            if (exitingViews != null) {
+                ArrayList<View> tempExiting = new ArrayList<>();
+                tempExiting.add(nonExistentView);
+                replaceTargets(exitTransition, exitingViews, tempExiting);
+                exitingViews.clear();
+                exitingViews.add(nonExistentView);
+            }
+        });
     }
 
     /**
@@ -541,19 +527,13 @@
             epicenterView = null;
         }
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
-                                inSharedElements, false);
-                        if (epicenterView != null) {
-                            epicenterView.getBoundsOnScreen(epicenter);
-                        }
-                        return true;
-                    }
-                });
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                    inSharedElements, false);
+            if (epicenterView != null) {
+                epicenterView.getBoundsOnScreen(epicenter);
+            }
+        });
         return sharedElementTransition;
     }
 
@@ -643,36 +623,30 @@
 
         TransitionSet finalSharedElementTransition = sharedElementTransition;
 
-        sceneRoot.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-                    @Override
-                    public boolean onPreDraw() {
-                        sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
-                        ArrayMap<String, View> inSharedElements = captureInSharedElements(
-                                nameOverrides, finalSharedElementTransition, fragments);
+        OneShotPreDrawListener.add(sceneRoot, () -> {
+            ArrayMap<String, View> inSharedElements = captureInSharedElements(
+                    nameOverrides, finalSharedElementTransition, fragments);
 
-                        if (inSharedElements != null) {
-                            sharedElementsIn.addAll(inSharedElements.values());
-                            sharedElementsIn.add(nonExistentView);
-                        }
+            if (inSharedElements != null) {
+                sharedElementsIn.addAll(inSharedElements.values());
+                sharedElementsIn.add(nonExistentView);
+            }
 
-                        callSharedElementStartEnd(inFragment, outFragment, inIsPop,
-                                inSharedElements, false);
-                        if (finalSharedElementTransition != null) {
-                            finalSharedElementTransition.getTargets().clear();
-                            finalSharedElementTransition.getTargets().addAll(sharedElementsIn);
-                            replaceTargets(finalSharedElementTransition, sharedElementsOut,
-                                    sharedElementsIn);
+            callSharedElementStartEnd(inFragment, outFragment, inIsPop,
+                    inSharedElements, false);
+            if (finalSharedElementTransition != null) {
+                finalSharedElementTransition.getTargets().clear();
+                finalSharedElementTransition.getTargets().addAll(sharedElementsIn);
+                replaceTargets(finalSharedElementTransition, sharedElementsOut,
+                        sharedElementsIn);
 
-                            final View inEpicenterView = getInEpicenterView(inSharedElements,
-                                    fragments, enterTransition, inIsPop);
-                            if (inEpicenterView != null) {
-                                inEpicenterView.getBoundsOnScreen(inEpicenter);
-                            }
-                        }
-                        return true;
-                    }
-                });
+                final View inEpicenterView = getInEpicenterView(inSharedElements,
+                        fragments, enterTransition, inIsPop);
+                if (inEpicenterView != null) {
+                    inEpicenterView.getBoundsOnScreen(inEpicenter);
+                }
+            }
+        });
         return sharedElementTransition;
     }
 
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index d63d37b..82be7ab 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -75,73 +75,78 @@
  * {@hide}
  */
 interface IActivityManager {
-    // 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.
+    // WARNING: when these transactions are updated, check if they are any callers on the native
+    // side. If so, make sure they are using the correct transaction ids.
+    // If a transaction which will also be used on the native side is being inserted, add it to
+    // below block of transactions.
+
+    // =============== Beginning of transactions used on native side as well ======================
+    ParcelFileDescriptor openContentUri(in String uriString);
+    // =============== End of transactions used on native side as well ============================
 
     // Special low-level communication with activity manager.
     void handleApplicationCrash(in IBinder app,
-            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 1;
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo);
     int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
             in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
-            int flags, in ProfilerInfo profilerInfo, in Bundle options) = 2;
-    void unhandledBack() = 3;
-    ParcelFileDescriptor openContentUri(in String uriString) = 4;
+            int flags, in ProfilerInfo profilerInfo, in Bundle options);
+    void unhandledBack();
 
-    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask) = 10;
+    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
     Intent registerReceiver(in IApplicationThread caller, in String callerPackage,
             in IIntentReceiver receiver, in IntentFilter filter,
-            in String requiredPermission, int userId) = 11;
-    void unregisterReceiver(in IIntentReceiver receiver) = 12;
+            in String requiredPermission, int userId);
+    void unregisterReceiver(in IIntentReceiver receiver);
     int broadcastIntent(in IApplicationThread caller, in Intent intent,
             in String resolvedType, in IIntentReceiver resultTo, int resultCode,
             in String resultData, in Bundle map, in String[] requiredPermissions,
-            int appOp, in Bundle options, boolean serialized, boolean sticky, int userId) = 13;
-    void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId) = 14;
+            int appOp, in Bundle options, boolean serialized, boolean sticky, int userId);
+    void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId);
     oneway void finishReceiver(in IBinder who, int resultCode, in String resultData, in Bundle map,
-            boolean abortBroadcast, int flags) = 15;
-    void attachApplication(in IApplicationThread app) = 16;
+            boolean abortBroadcast, int flags);
+    void attachApplication(in IApplicationThread app);
     oneway void activityIdle(in IBinder token, in Configuration config,
-            in boolean stopProfiling) = 17;
-    void activityPaused(in IBinder token) = 18;
+            in boolean stopProfiling);
+    void activityPaused(in IBinder token);
     oneway void activityStopped(in IBinder token, in Bundle state,
-            in PersistableBundle persistentState, in CharSequence description) = 19;
-    String getCallingPackage(in IBinder token) = 20;
-    ComponentName getCallingActivity(in IBinder token) = 21;
-    List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags) = 22;
-    void moveTaskToFront(int task, int flags, in Bundle options) = 23;
-    void moveTaskBackwards(int task) = 25;
-    int getTaskForActivity(in IBinder token, in boolean onlyRoot) = 26;
+            in PersistableBundle persistentState, in CharSequence description);
+    String getCallingPackage(in IBinder token);
+    ComponentName getCallingActivity(in IBinder token);
+    List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags);
+    void moveTaskToFront(int task, int flags, in Bundle options);
+    void moveTaskBackwards(int task);
+    int getTaskForActivity(in IBinder token, in boolean onlyRoot);
     ContentProviderHolder getContentProvider(in IApplicationThread caller,
-            in String name, int userId, boolean stable) = 28;
+            in String name, int userId, boolean stable);
     void publishContentProviders(in IApplicationThread caller,
-            in List<ContentProviderHolder> providers) = 29;
-    boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta) = 30;
-    void finishSubActivity(in IBinder token, in String resultWho, int requestCode) = 31;
-    PendingIntent getRunningServiceControlPanel(in ComponentName service) = 32;
+            in List<ContentProviderHolder> providers);
+    boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta);
+    void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
+    PendingIntent getRunningServiceControlPanel(in ComponentName service);
     ComponentName startService(in IApplicationThread caller, in Intent service,
-            in String resolvedType, in String callingPackage, int userId) = 33;
+            in String resolvedType, in String callingPackage, int userId);
     int stopService(in IApplicationThread caller, in Intent service,
-            in String resolvedType, int userId) = 34;
+            in String resolvedType, int userId);
     int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
             in String resolvedType, in IServiceConnection connection, int flags,
-            in String callingPackage, int userId) = 35;
-    boolean unbindService(in IServiceConnection connection) = 36;
-    void publishService(in IBinder token, in Intent intent, in IBinder service) = 37;
-    void activityResumed(in IBinder token) = 38;
-    void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent) = 41;
-    void setAlwaysFinish(boolean enabled) = 42;
+            in String callingPackage, int userId);
+    boolean unbindService(in IServiceConnection connection);
+    void publishService(in IBinder token, in Intent intent, in IBinder service);
+    void activityResumed(in IBinder token);
+    void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent);
+    void setAlwaysFinish(boolean enabled);
     boolean startInstrumentation(in ComponentName className, in String profileFile,
             int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
             in IUiAutomationConnection connection, int userId,
-            in String abiOverride) = 43;
+            in String abiOverride);
     void finishInstrumentation(in IApplicationThread target, int resultCode,
-            in Bundle results) = 44;
+            in Bundle results);
     /**
      * @return A copy of global {@link Configuration}, contains general settings for the entire
      *         system. Corresponds to the configuration of the default display.
      * @throws RemoteException
      */
-    Configuration getConfiguration() = 45;
+    Configuration getConfiguration();
     /**
      * Updates global configuration and applies changes to the entire system.
      * @param values Update values for global configuration. If null is passed it will request the
@@ -149,183 +154,183 @@
      * @throws RemoteException
      * @return Returns true if the configuration was updated.
      */
-    boolean updateConfiguration(in Configuration values) = 46;
-    boolean stopServiceToken(in ComponentName className, in IBinder token, int startId) = 47;
-    ComponentName getActivityClassForToken(in IBinder token) = 48;
-    String getPackageForToken(in IBinder token) = 49;
-    void setProcessLimit(int max) = 50;
-    int getProcessLimit() = 51;
-    int checkPermission(in String permission, int pid, int uid) = 52;
+    boolean updateConfiguration(in Configuration values);
+    boolean stopServiceToken(in ComponentName className, in IBinder token, int startId);
+    ComponentName getActivityClassForToken(in IBinder token);
+    String getPackageForToken(in IBinder token);
+    void setProcessLimit(int max);
+    int getProcessLimit();
+    int checkPermission(in String permission, int pid, int uid);
     int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
-            in IBinder callerToken) = 53;
+            in IBinder callerToken);
     void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
-            int mode, int userId) = 54;
-    void revokeUriPermission(in IApplicationThread caller, in Uri uri, int mode, int userId) = 55;
-    void setActivityController(in IActivityController watcher, boolean imAMonkey) = 56;
-    void showWaitingForDebugger(in IApplicationThread who, boolean waiting) = 57;
+            int mode, int userId);
+    void revokeUriPermission(in IApplicationThread caller, in Uri uri, int mode, int userId);
+    void setActivityController(in IActivityController watcher, boolean imAMonkey);
+    void showWaitingForDebugger(in IApplicationThread who, boolean waiting);
     /*
      * This will deliver the specified signal to all the persistent processes. Currently only
      * SIGUSR1 is delivered. All others are ignored.
      */
-    void signalPersistentProcesses(int signal) = 58;
+    void signalPersistentProcesses(int signal);
     ParceledListSlice getRecentTasks(int maxNum,
-            int flags, int userId) = 59;
-    oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res) = 60;
-    oneway void activityDestroyed(in IBinder token) = 61;
+            int flags, int userId);
+    oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res);
+    oneway void activityDestroyed(in IBinder token);
     IIntentSender getIntentSender(int type, in String packageName, in IBinder token,
             in String resultWho, int requestCode, in Intent[] intents, in String[] resolvedTypes,
-            int flags, in Bundle options, int userId) = 62;
-    void cancelIntentSender(in IIntentSender sender) = 63;
-    String getPackageForIntentSender(in IIntentSender sender) = 64;
-    void enterSafeMode() = 65;
+            int flags, in Bundle options, int userId);
+    void cancelIntentSender(in IIntentSender sender);
+    String getPackageForIntentSender(in IIntentSender sender);
+    void enterSafeMode();
     boolean startNextMatchingActivity(in IBinder callingActivity,
-            in Intent intent, in Bundle options) = 66;
+            in Intent intent, in Bundle options);
     void noteWakeupAlarm(in IIntentSender sender, int sourceUid,
-            in String sourcePkg, in String tag) = 67;
-    void removeContentProvider(in IBinder connection, boolean stable) = 68;
-    void setRequestedOrientation(in IBinder token, int requestedOrientation) = 69;
-    int getRequestedOrientation(in IBinder token) = 70;
-    void unbindFinished(in IBinder token, in Intent service, boolean doRebind) = 71;
-    void setProcessForeground(in IBinder token, int pid, boolean isForeground) = 72;
+            in String sourcePkg, in String tag);
+    void removeContentProvider(in IBinder connection, boolean stable);
+    void setRequestedOrientation(in IBinder token, int requestedOrientation);
+    int getRequestedOrientation(in IBinder token);
+    void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
+    void setProcessForeground(in IBinder token, int pid, boolean isForeground);
     void setServiceForeground(in ComponentName className, in IBinder token,
-            int id, in Notification notification, int flags) = 73;
-    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot) = 74;
-    void getMemoryInfo(out ActivityManager.MemoryInfo outInfo) = 75;
-    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() = 76;
+            int id, in Notification notification, int flags);
+    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
+    void getMemoryInfo(out ActivityManager.MemoryInfo outInfo);
+    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
     boolean clearApplicationUserData(in String packageName,
-            in IPackageDataObserver observer, int userId) = 77;
-    void forceStopPackage(in String packageName, int userId) = 78;
-    boolean killPids(in int[] pids, in String reason, boolean secure) = 79;
-    List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) = 80;
-    ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) = 81;
+            in IPackageDataObserver observer, int userId);
+    void forceStopPackage(in String packageName, int userId);
+    boolean killPids(in int[] pids, in String reason, boolean secure);
+    List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags);
+    ActivityManager.TaskThumbnail getTaskThumbnail(int taskId);
     // Retrieve running application processes in the system
-    List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() = 82;
+    List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses();
     // Get device configuration
-    ConfigurationInfo getDeviceConfigurationInfo() = 83;
-    IBinder peekService(in Intent service, in String resolvedType, in String callingPackage) = 84;
+    ConfigurationInfo getDeviceConfigurationInfo();
+    IBinder peekService(in Intent service, in String resolvedType, in String callingPackage);
     // Turn on/off profiling in a particular process.
     boolean profileControl(in String process, int userId, boolean start,
-            in ProfilerInfo profilerInfo, int profileType) = 85;
-    boolean shutdown(int timeout) = 86;
-    void stopAppSwitches() = 87;
-    void resumeAppSwitches() = 88;
-    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int userId) = 89;
-    void backupAgentCreated(in String packageName, in IBinder agent) = 90;
-    void unbindBackupAgent(in ApplicationInfo appInfo) = 91;
-    int getUidForIntentSender(in IIntentSender sender) = 92;
+            in ProfilerInfo profilerInfo, int profileType);
+    boolean shutdown(int timeout);
+    void stopAppSwitches();
+    void resumeAppSwitches();
+    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int userId);
+    void backupAgentCreated(in String packageName, in IBinder agent);
+    void unbindBackupAgent(in ApplicationInfo appInfo);
+    int getUidForIntentSender(in IIntentSender sender);
     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
-            boolean requireFull, in String name, in String callerPackage) = 93;
-    void addPackageDependency(in String packageName) = 94;
-    void killApplication(in String pkg, int appId, int userId, in String reason) = 95;
-    void closeSystemDialogs(in String reason) = 96;
-    Debug.MemoryInfo[] getProcessMemoryInfo(in int[] pids) = 97;
-    void killApplicationProcess(in String processName, int uid) = 98;
+            boolean requireFull, in String name, in String callerPackage);
+    void addPackageDependency(in String packageName);
+    void killApplication(in String pkg, int appId, int userId, in String reason);
+    void closeSystemDialogs(in String reason);
+    Debug.MemoryInfo[] getProcessMemoryInfo(in int[] pids);
+    void killApplicationProcess(in String processName, int uid);
     int startActivityIntentSender(in IApplicationThread caller,
             in IntentSender intent, in Intent fillInIntent, in String resolvedType,
             in IBinder resultTo, in String resultWho, int requestCode,
-            int flagsMask, int flagsValues, in Bundle options) = 99;
+            int flagsMask, int flagsValues, in Bundle options);
     void overridePendingTransition(in IBinder token, in String packageName,
-            int enterAnim, int exitAnim) = 100;
+            int enterAnim, int exitAnim);
     // Special low-level communication with activity manager.
     boolean handleApplicationWtf(in IBinder app, in String tag, boolean system,
-            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 101;
-    void killBackgroundProcesses(in String packageName, int userId) = 102;
-    boolean isUserAMonkey() = 103;
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo);
+    void killBackgroundProcesses(in String packageName, int userId);
+    boolean isUserAMonkey();
     WaitResult startActivityAndWait(in IApplicationThread caller, in String callingPackage,
             in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
             int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
-            int userId) = 104;
-    boolean willActivityBeVisible(in IBinder token) = 105;
+            int userId);
+    boolean willActivityBeVisible(in IBinder token);
     int startActivityWithConfig(in IApplicationThread caller, in String callingPackage,
             in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
             int requestCode, int startFlags, in Configuration newConfig,
-            in Bundle options, int userId) = 106;
+            in Bundle options, int userId);
     // Retrieve info of applications installed on external media that are currently
     // running.
-    List<ApplicationInfo> getRunningExternalApplications() = 107;
-    void finishHeavyWeightApp() = 108;
+    List<ApplicationInfo> getRunningExternalApplications();
+    void finishHeavyWeightApp();
     // A StrictMode violation to be handled.  The violationMask is a
     // subset of the original StrictMode policy bitmask, with only the
     // bit violated and penalty bits to be executed by the
     // ActivityManagerService remaining set.
     void handleApplicationStrictModeViolation(in IBinder app, int violationMask,
-            in StrictMode.ViolationInfo crashInfo) = 109;
-    boolean isImmersive(in IBinder token) = 110;
-    void setImmersive(in IBinder token, boolean immersive) = 111;
-    boolean isTopActivityImmersive() = 112;
-    void crashApplication(int uid, int initialPid, in String packageName, in String message) = 113;
-    String getProviderMimeType(in Uri uri, int userId) = 114;
-    IBinder newUriPermissionOwner(in String name) = 115;
+            in StrictMode.ViolationInfo crashInfo);
+    boolean isImmersive(in IBinder token);
+    void setImmersive(in IBinder token, boolean immersive);
+    boolean isTopActivityImmersive();
+    void crashApplication(int uid, int initialPid, in String packageName, in String message);
+    String getProviderMimeType(in Uri uri, int userId);
+    IBinder newUriPermissionOwner(in String name);
     void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg,
-            in Uri uri, int mode, int sourceUserId, int targetUserId) = 116;
-    void revokeUriPermissionFromOwner(in IBinder owner, in Uri uri, int mode, int userId) = 117;
+            in Uri uri, int mode, int sourceUserId, int targetUserId);
+    void revokeUriPermissionFromOwner(in IBinder owner, in Uri uri, int mode, int userId);
     int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri,
-            int modeFlags, int userId) = 118;
+            int modeFlags, int userId);
     // Cause the specified process to dump the specified heap.
     boolean dumpHeap(in String process, int userId, boolean managed, in String path,
-            in ParcelFileDescriptor fd) = 119;
+            in ParcelFileDescriptor fd);
     int startActivities(in IApplicationThread caller, in String callingPackage,
             in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo,
-            in Bundle options, int userId) = 120;
-    boolean isUserRunning(int userid, int flags) = 121;
-    oneway void activitySlept(in IBinder token) = 122;
-    int getFrontActivityScreenCompatMode() = 123;
-    void setFrontActivityScreenCompatMode(int mode) = 124;
-    int getPackageScreenCompatMode(in String packageName) = 125;
-    void setPackageScreenCompatMode(in String packageName, int mode) = 126;
-    boolean getPackageAskScreenCompat(in String packageName) = 127;
-    void setPackageAskScreenCompat(in String packageName, boolean ask) = 128;
-    boolean switchUser(int userid) = 129;
-    void setFocusedTask(int taskId) = 130;
-    boolean removeTask(int taskId) = 131;
-    void registerProcessObserver(in IProcessObserver observer) = 132;
-    void unregisterProcessObserver(in IProcessObserver observer) = 133;
-    boolean isIntentSenderTargetedToPackage(in IIntentSender sender) = 134;
-    void updatePersistentConfiguration(in Configuration values) = 135;
-    long[] getProcessPss(in int[] pids) = 136;
-    void showBootMessage(in CharSequence msg, boolean always) = 137;
-    void killAllBackgroundProcesses() = 139;
+            in Bundle options, int userId);
+    boolean isUserRunning(int userid, int flags);
+    oneway void activitySlept(in IBinder token);
+    int getFrontActivityScreenCompatMode();
+    void setFrontActivityScreenCompatMode(int mode);
+    int getPackageScreenCompatMode(in String packageName);
+    void setPackageScreenCompatMode(in String packageName, int mode);
+    boolean getPackageAskScreenCompat(in String packageName);
+    void setPackageAskScreenCompat(in String packageName, boolean ask);
+    boolean switchUser(int userid);
+    void setFocusedTask(int taskId);
+    boolean removeTask(int taskId);
+    void registerProcessObserver(in IProcessObserver observer);
+    void unregisterProcessObserver(in IProcessObserver observer);
+    boolean isIntentSenderTargetedToPackage(in IIntentSender sender);
+    void updatePersistentConfiguration(in Configuration values);
+    long[] getProcessPss(in int[] pids);
+    void showBootMessage(in CharSequence msg, boolean always);
+    void killAllBackgroundProcesses();
     ContentProviderHolder getContentProviderExternal(in String name, int userId,
-            in IBinder token) = 140;
-    void removeContentProviderExternal(in String name, in IBinder token) = 141;
+            in IBinder token);
+    void removeContentProviderExternal(in String name, in IBinder token);
     // Get memory information about the calling process.
-    void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo) = 142;
-    boolean killProcessesBelowForeground(in String reason) = 143;
-    UserInfo getCurrentUser() = 144;
-    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity) = 145;
+    void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
+    boolean killProcessesBelowForeground(in String reason);
+    UserInfo getCurrentUser();
+    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity);
     boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
-            in Intent resultData) = 146;
-    void setLockScreenShown(boolean showing) = 147;
-    boolean finishActivityAffinity(in IBinder token) = 148;
+            in Intent resultData);
+    void setLockScreenShown(boolean showing);
+    boolean finishActivityAffinity(in IBinder token);
     // This is not public because you need to be very careful in how you
     // manage your activity to make sure it is always the uid you expect.
-    int getLaunchedFromUid(in IBinder activityToken) = 149;
-    void unstableProviderDied(in IBinder connection) = 150;
-    boolean isIntentSenderAnActivity(in IIntentSender sender) = 151;
+    int getLaunchedFromUid(in IBinder activityToken);
+    void unstableProviderDied(in IBinder connection);
+    boolean isIntentSenderAnActivity(in IIntentSender sender);
     int startActivityAsUser(in IApplicationThread caller, in String callingPackage,
             in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
             int requestCode, int flags, in ProfilerInfo profilerInfo,
-            in Bundle options, int userId) = 152;
-    int stopUser(int userid, boolean force, in IStopUserCallback callback) = 153;
-    void registerUserSwitchObserver(in IUserSwitchObserver observer, in String name) = 154;
-    void unregisterUserSwitchObserver(in IUserSwitchObserver observer) = 155;
-    int[] getRunningUserIds() = 156;
-    void requestBugReport(int bugreportType) = 157;
-    long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason) = 158;
-    void clearPendingBackup() = 159;
-    Intent getIntentForIntentSender(in IIntentSender sender) = 160;
-    Bundle getAssistContextExtras(int requestType) = 161;
+            in Bundle options, int userId);
+    int stopUser(int userid, boolean force, in IStopUserCallback callback);
+    void registerUserSwitchObserver(in IUserSwitchObserver observer, in String name);
+    void unregisterUserSwitchObserver(in IUserSwitchObserver observer);
+    int[] getRunningUserIds();
+    void requestBugReport(int bugreportType);
+    long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason);
+    void clearPendingBackup();
+    Intent getIntentForIntentSender(in IIntentSender sender);
+    Bundle getAssistContextExtras(int requestType);
     void reportAssistContextExtras(in IBinder token, in Bundle extras,
-            in AssistStructure structure, in AssistContent content, in Uri referrer) = 162;
+            in AssistStructure structure, in AssistContent content, in Uri referrer);
     // This is not public because you need to be very careful in how you
     // manage your activity to make sure it is always the uid you expect.
-    String getLaunchedFromPackage(in IBinder activityToken) = 163;
-    void killUid(int appId, int userId, in String reason) = 164;
-    void setUserIsMonkey(boolean monkey) = 165;
-    void hang(in IBinder who, boolean allowRestart) = 166;
+    String getLaunchedFromPackage(in IBinder activityToken);
+    void killUid(int appId, int userId, in String reason);
+    void setUserIsMonkey(boolean monkey);
+    void hang(in IBinder who, boolean allowRestart);
     IActivityContainer createVirtualActivityContainer(in IBinder parentActivityToken,
-            in IActivityContainerCallback callback) = 167;
-    void moveTaskToStack(int taskId, int stackId, boolean toTop) = 168;
+            in IActivityContainerCallback callback);
+    void moveTaskToStack(int taskId, int stackId, boolean toTop);
     /**
      * Resizes the input stack id to the given bounds.
      *
@@ -341,129 +346,129 @@
      * @throws RemoteException
      */
     void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
-            boolean preserveWindows, boolean animate, int animationDuration) = 169;
-    List<ActivityManager.StackInfo> getAllStackInfos() = 170;
-    void setFocusedStack(int stackId) = 171;
-    ActivityManager.StackInfo getStackInfo(int stackId) = 172;
-    boolean convertFromTranslucent(in IBinder token) = 173;
-    boolean convertToTranslucent(in IBinder token, in Bundle options) = 174;
-    void notifyActivityDrawn(in IBinder token) = 175;
-    void reportActivityFullyDrawn(in IBinder token) = 176;
-    void restart() = 177;
-    void performIdleMaintenance() = 178;
-    void takePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 179;
-    void releasePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 180;
-    ParceledListSlice getPersistedUriPermissions(in String packageName, boolean incoming) = 181;
-    void appNotRespondingViaProvider(in IBinder connection) = 182;
-    Rect getTaskBounds(int taskId) = 183;
-    int getActivityDisplayId(in IBinder activityToken) = 184;
-    boolean setProcessMemoryTrimLevel(in String process, int uid, int level) = 186;
+            boolean preserveWindows, boolean animate, int animationDuration);
+    List<ActivityManager.StackInfo> getAllStackInfos();
+    void setFocusedStack(int stackId);
+    ActivityManager.StackInfo getStackInfo(int stackId);
+    boolean convertFromTranslucent(in IBinder token);
+    boolean convertToTranslucent(in IBinder token, in Bundle options);
+    void notifyActivityDrawn(in IBinder token);
+    void reportActivityFullyDrawn(in IBinder token);
+    void restart();
+    void performIdleMaintenance();
+    void takePersistableUriPermission(in Uri uri, int modeFlags, int userId);
+    void releasePersistableUriPermission(in Uri uri, int modeFlags, int userId);
+    ParceledListSlice getPersistedUriPermissions(in String packageName, boolean incoming);
+    void appNotRespondingViaProvider(in IBinder connection);
+    Rect getTaskBounds(int taskId);
+    int getActivityDisplayId(in IBinder activityToken);
+    boolean setProcessMemoryTrimLevel(in String process, int uid, int level);
 
 
     // Start of L transactions
-    String getTagForIntentSender(in IIntentSender sender, in String prefix) = 210;
-    boolean startUserInBackground(int userid) = 211;
-    boolean isInHomeStack(int taskId) = 212;
-    void startLockTaskModeById(int taskId) = 213;
-    void startLockTaskModeByToken(in IBinder token) = 214;
-    void stopLockTaskMode() = 215;
-    boolean isInLockTaskMode() = 216;
-    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values) = 217;
+    String getTagForIntentSender(in IIntentSender sender, in String prefix);
+    boolean startUserInBackground(int userid);
+    boolean isInHomeStack(int taskId);
+    void startLockTaskModeById(int taskId);
+    void startLockTaskModeByToken(in IBinder token);
+    void stopLockTaskMode();
+    boolean isInLockTaskMode();
+    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values);
     int startVoiceActivity(in String callingPackage, int callingPid, int callingUid,
             in Intent intent, in String resolvedType, in IVoiceInteractionSession session,
             in IVoiceInteractor interactor, int flags, in ProfilerInfo profilerInfo,
-            in Bundle options, int userId) = 218;
-    Bundle getActivityOptions(in IBinder token) = 219;
-    List<IBinder> getAppTasks(in String callingPackage) = 220;
-    void startSystemLockTaskMode(int taskId) = 221;
-    void stopSystemLockTaskMode() = 222;
-    void finishVoiceTask(in IVoiceInteractionSession session) = 223;
-    boolean isTopOfTask(in IBinder token) = 224;
-    boolean requestVisibleBehind(in IBinder token, boolean visible) = 225;
-    boolean isBackgroundVisibleBehind(in IBinder token) = 226;
-    void backgroundResourcesReleased(in IBinder token) = 227;
-    void notifyLaunchTaskBehindComplete(in IBinder token) = 228;
-    int startActivityFromRecents(int taskId, in Bundle options) = 229;
-    void notifyEnterAnimationComplete(in IBinder token) = 230;
+            in Bundle options, int userId);
+    Bundle getActivityOptions(in IBinder token);
+    List<IBinder> getAppTasks(in String callingPackage);
+    void startSystemLockTaskMode(int taskId);
+    void stopSystemLockTaskMode();
+    void finishVoiceTask(in IVoiceInteractionSession session);
+    boolean isTopOfTask(in IBinder token);
+    boolean requestVisibleBehind(in IBinder token, boolean visible);
+    boolean isBackgroundVisibleBehind(in IBinder token);
+    void backgroundResourcesReleased(in IBinder token);
+    void notifyLaunchTaskBehindComplete(in IBinder token);
+    int startActivityFromRecents(int taskId, in Bundle options);
+    void notifyEnterAnimationComplete(in IBinder token);
     int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
             in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
             int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
-            boolean ignoreTargetSecurity, int userId) = 232;
+            boolean ignoreTargetSecurity, int userId);
     int addAppTask(in IBinder activityToken, in Intent intent,
-            in ActivityManager.TaskDescription description, in Bitmap thumbnail) = 233;
-    Point getAppTaskThumbnailSize() = 234;
-    boolean releaseActivityInstance(in IBinder token) = 235;
-    void releaseSomeActivities(in IApplicationThread app) = 236;
-    void bootAnimationComplete() = 237;
-    Bitmap getTaskDescriptionIcon(in String filename, int userId) = 238;
+            in ActivityManager.TaskDescription description, in Bitmap thumbnail);
+    Point getAppTaskThumbnailSize();
+    boolean releaseActivityInstance(in IBinder token);
+    void releaseSomeActivities(in IApplicationThread app);
+    void bootAnimationComplete();
+    Bitmap getTaskDescriptionIcon(in String filename, int userId);
     boolean launchAssistIntent(in Intent intent, int requestType, in String hint, int userHandle,
-            in Bundle args) = 239;
-    void startInPlaceAnimationOnFrontMostApplication(in Bundle opts) = 240;
+            in Bundle args);
+    void startInPlaceAnimationOnFrontMostApplication(in Bundle opts);
     int checkPermissionWithToken(in String permission, int pid, int uid,
-            in IBinder callerToken) = 241;
-    void registerTaskStackListener(in ITaskStackListener listener) = 242;
+            in IBinder callerToken);
+    void registerTaskStackListener(in ITaskStackListener listener);
 
 
     // Start of M transactions
-    void notifyCleartextNetwork(int uid, in byte[] firstPacket) = 280;
-    IActivityContainer createStackOnDisplay(int displayId) = 281;
-    int getFocusedStackId() = 282;
-    void setTaskResizeable(int taskId, int resizeableMode) = 283;
+    void notifyCleartextNetwork(int uid, in byte[] firstPacket);
+    IActivityContainer createStackOnDisplay(int displayId);
+    int getFocusedStackId();
+    void setTaskResizeable(int taskId, int resizeableMode);
     boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver,
             in Bundle receiverExtras, in IBinder activityToken,
-            boolean focused, boolean newSessionId) = 284;
-    void resizeTask(int taskId, in Rect bounds, int resizeMode) = 285;
-    int getLockTaskModeState() = 286;
+            boolean focused, boolean newSessionId);
+    void resizeTask(int taskId, in Rect bounds, int resizeMode);
+    int getLockTaskModeState();
     void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize,
-            in String reportPackage) = 287;
-    void dumpHeapFinished(in String path) = 288;
-    void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake) = 289;
-    void updateLockTaskPackages(int userId, in String[] packages) = 290;
-    void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag) = 291;
-    void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag) = 292;
-    int getPackageProcessState(in String packageName, in String callingPackage) = 293;
-    oneway void showLockTaskEscapeMessage(in IBinder token) = 294;
-    void updateDeviceOwner(in String packageName) = 295;
+            in String reportPackage);
+    void dumpHeapFinished(in String path);
+    void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake);
+    void updateLockTaskPackages(int userId, in String[] packages);
+    void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag);
+    void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag);
+    int getPackageProcessState(in String packageName, in String callingPackage);
+    oneway void showLockTaskEscapeMessage(in IBinder token);
+    void updateDeviceOwner(in String packageName);
     /**
      * Notify the system that the keyguard is going away.
      *
      * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
      *              etc.
      */
-    void keyguardGoingAway(int flags) = 296;
+    void keyguardGoingAway(int flags);
     void registerUidObserver(in IUidObserver observer, int which, int cutpoint,
-            String callingPackage) = 297;
-    void unregisterUidObserver(in IUidObserver observer) = 298;
-    boolean isAssistDataAllowedOnCurrentActivity() = 299;
-    boolean showAssistFromActivity(in IBinder token, in Bundle args) = 300;
-    boolean isRootVoiceInteraction(in IBinder token) = 301;
+            String callingPackage);
+    void unregisterUidObserver(in IUidObserver observer);
+    boolean isAssistDataAllowedOnCurrentActivity();
+    boolean showAssistFromActivity(in IBinder token, in Bundle args);
+    boolean isRootVoiceInteraction(in IBinder token);
 
 
     // Start of N transactions
     // Start Binder transaction tracking for all applications.
-    boolean startBinderTracking() = 340;
+    boolean startBinderTracking();
     // Stop Binder transaction tracking for all applications and dump trace data to the given file
     // descriptor.
-    boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 341;
-    void positionTaskInStack(int taskId, int stackId, int position) = 342;
-    int getActivityStackId(in IBinder token) = 343;
-    void exitFreeformMode(in IBinder token) = 344;
+    boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
+    void positionTaskInStack(int taskId, int stackId, int position);
+    int getActivityStackId(in IBinder token);
+    void exitFreeformMode(in IBinder token);
     void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
-            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations) = 345;
+            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
     boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
-            in Rect initialBounds, boolean moveHomeStackFront) = 346;
-    void suppressResizeConfigChanges(boolean suppress) = 347;
-    void moveTasksToFullscreenStack(int fromStackId, boolean onTop) = 348;
-    boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds) = 349;
-    int getAppStartMode(int uid, in String packageName) = 350;
+            in Rect initialBounds, boolean moveHomeStackFront);
+    void suppressResizeConfigChanges(boolean suppress);
+    void moveTasksToFullscreenStack(int fromStackId, boolean onTop);
+    boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds);
+    int getAppStartMode(int uid, in String packageName);
     boolean unlockUser(int userid, in byte[] token, in byte[] secret,
-            in IProgressListener listener) = 351;
-    boolean isInMultiWindowMode(in IBinder token) = 352;
-    boolean isInPictureInPictureMode(in IBinder token) = 353;
-    void killPackageDependents(in String packageName, int userId) = 354;
-    void enterPictureInPictureMode(in IBinder token) = 355;
-    void activityRelaunched(in IBinder token) = 356;
-    IBinder getUriPermissionOwnerForActivity(in IBinder activityToken) = 357;
+            in IProgressListener listener);
+    boolean isInMultiWindowMode(in IBinder token);
+    boolean isInPictureInPictureMode(in IBinder token);
+    void killPackageDependents(in String packageName, int userId);
+    void enterPictureInPictureMode(in IBinder token);
+    void activityRelaunched(in IBinder token);
+    IBinder getUriPermissionOwnerForActivity(in IBinder activityToken);
     /**
      * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
      *
@@ -485,22 +490,22 @@
      */
     void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
             in Rect tempDockedTaskInsetBounds,
-            in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds) = 358;
-    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName) = 359;
+            in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);
+    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName);
     // Gets the URI permissions granted to an arbitrary package.
     // NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package
     // granted to another packages (instead of those granted to it).
-    ParceledListSlice getGrantedUriPermissions(in String packageName, int userId) = 360;
+    ParceledListSlice getGrantedUriPermissions(in String packageName, int userId);
     // Clears the URI permissions granted to an arbitrary package.
-    void clearGrantedUriPermissions(in String packageName, int userId) = 361;
-    boolean isAppForeground(int uid) = 362;
-    void startLocalVoiceInteraction(in IBinder token, in Bundle options) = 363;
-    void stopLocalVoiceInteraction(in IBinder token) = 364;
-    boolean supportsLocalVoiceInteraction() = 365;
-    void notifyPinnedStackAnimationEnded() = 366;
-    void removeStack(int stackId) = 367;
-    void makePackageIdle(String packageName, int userId) = 368;
-    int getMemoryTrimLevel() = 369;
+    void clearGrantedUriPermissions(in String packageName, int userId);
+    boolean isAppForeground(int uid);
+    void startLocalVoiceInteraction(in IBinder token, in Bundle options);
+    void stopLocalVoiceInteraction(in IBinder token);
+    boolean supportsLocalVoiceInteraction();
+    void notifyPinnedStackAnimationEnded();
+    void removeStack(int stackId);
+    void makePackageIdle(String packageName, int userId);
+    int getMemoryTrimLevel();
     /**
      * Resizes the pinned stack.
      *
@@ -510,24 +515,24 @@
      *                             flexibility while resizing, or {@code null} if they should be the
      *                             same as the stack bounds.
      */
-    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds) = 370;
-    boolean isVrModePackageEnabled(in ComponentName packageName) = 371;
+    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds);
+    boolean isVrModePackageEnabled(in ComponentName packageName);
     /**
      * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the
      * fullscreen stack into the docked stack.
      */
-    void swapDockedAndFullscreenStack() = 372;
-    void notifyLockedProfile(int userId) = 373;
-    void startConfirmDeviceCredentialIntent(in Intent intent) = 374;
-    void sendIdleJobTrigger() = 375;
+    void swapDockedAndFullscreenStack();
+    void notifyLockedProfile(int userId);
+    void startConfirmDeviceCredentialIntent(in Intent intent);
+    void sendIdleJobTrigger();
     int sendIntentSender(in IIntentSender target, int code, in Intent intent,
             in String resolvedType, in IIntentReceiver finishedReceiver,
-            in String requiredPermission, in Bundle options) = 376;
+            in String requiredPermission, in Bundle options);
 
 
     // Start of N MR1 transactions
-    void setVrThread(int tid) = 377;
-    void setRenderThread(int tid) = 378;
+    void setVrThread(int tid);
+    void setRenderThread(int tid);
     /**
      * Lets activity manager know whether the calling process is currently showing "top-level" UI
      * that is not an activity, i.e. windows on the screen the user is currently interacting with.
@@ -536,7 +541,7 @@
      *
      * @param hasTopUi Whether the calling process has "top-level" UI.
      */
-    void setHasTopUi(boolean hasTopUi) = 379;
+    void setHasTopUi(boolean hasTopUi);
     /**
      * Returns if the target of the PendingIntent can be fired directly, without triggering
      * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
@@ -547,10 +552,10 @@
      *     otherwise.
      * @throws RemoteException
      */
-    boolean canBypassWorkChallenge(in PendingIntent intent) = 380;
+    boolean canBypassWorkChallenge(in PendingIntent intent);
 
     // Start of O transactions
-    void requestActivityRelaunch(in IBinder token) = 400;
+    void requestActivityRelaunch(in IBinder token);
     /**
      * Updates override configuration applied to specific display.
      * @param values Update values for display configuration. If null is passed it will request the
@@ -559,14 +564,16 @@
      * @throws RemoteException
      * @return Returns true if the configuration was updated.
      */
-    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId) = 401;
-    void unregisterTaskStackListener(ITaskStackListener listener) = 402;
-    void moveStackToDisplay(int stackId, int displayId) = 403;
-    void enterPictureInPictureModeWithAspectRatio(in IBinder token, float aspectRatio) = 404;
-    void setPictureInPictureAspectRatio(in IBinder token, float aspectRatio) = 405;
+    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId);
+    void unregisterTaskStackListener(ITaskStackListener listener);
+    void moveStackToDisplay(int stackId, int displayId);
+    void enterPictureInPictureModeWithAspectRatio(in IBinder token, float aspectRatio);
+    void setPictureInPictureAspectRatio(in IBinder token, float aspectRatio);
     boolean requestAutoFillData(in IResultReceiver receiver, in Bundle receiverExtras,
-            in IBinder activityToken) = 406;
+            in IBinder activityToken);
 
-    // 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.
-}
+    // WARNING: when these transactions are updated, check if they are any callers on the native
+    // side. If so, make sure they are using the correct transaction ids.
+    // If a transaction which will also be used on the native side is being inserted, add it
+    // alongside with other transactions of this kind at the top of this file.
+}
\ No newline at end of file
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index c2b5b93..6b962b9 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -51,35 +51,31 @@
  * {@hide}
  */
 oneway interface IApplicationThread {
-    /**
-     * 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.
-     */
     void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges, boolean dontReport) = 0;
+            int configChanges, boolean dontReport);
     void scheduleStopActivity(IBinder token, boolean showWindow,
-            int configChanges) = 2;
-    void scheduleWindowVisibility(IBinder token, boolean showWindow) = 3;
+            int configChanges);
+    void scheduleWindowVisibility(IBinder token, boolean showWindow);
     void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
-            in Bundle resumeArgs) = 4;
-    void scheduleSendResult(IBinder token, in List<ResultInfo> results) = 5;
+            in Bundle resumeArgs);
+    void scheduleSendResult(IBinder token, in List<ResultInfo> results);
     void scheduleLaunchActivity(in Intent intent, IBinder token, int ident,
             in ActivityInfo info, in Configuration curConfig, in Configuration overrideConfig,
             in CompatibilityInfo compatInfo, in String referrer, IVoiceInteractor voiceInteractor,
             int procState, in Bundle state, in PersistableBundle persistentState,
             in List<ResultInfo> pendingResults, in List<ReferrerIntent> pendingNewIntents,
-            boolean notResumed, boolean isForward, in ProfilerInfo profilerInfo) = 6;
+            boolean notResumed, boolean isForward, in ProfilerInfo profilerInfo);
     void scheduleNewIntent(
-            in List<ReferrerIntent> intent, IBinder token, boolean andPause) = 7;
+            in List<ReferrerIntent> intent, IBinder token, boolean andPause);
     void scheduleDestroyActivity(IBinder token, boolean finished,
-            int configChanges) = 8;
+            int configChanges);
     void scheduleReceiver(in Intent intent, in ActivityInfo info,
             in CompatibilityInfo compatInfo,
             int resultCode, in String data, in Bundle extras, boolean sync,
-            int sendingUser, int processState) = 9;
+            int sendingUser, int processState);
     void scheduleCreateService(IBinder token, in ServiceInfo info,
-            in CompatibilityInfo compatInfo, int processState) = 10;
-    void scheduleStopService(IBinder token) = 11;
+            in CompatibilityInfo compatInfo, int processState);
+    void scheduleStopService(IBinder token);
     void bindApplication(in String packageName, in ApplicationInfo info,
             in List<ProviderInfo> providers, in ComponentName testName,
             in ProfilerInfo profilerInfo, in Bundle testArguments,
@@ -87,77 +83,73 @@
             int debugMode, boolean enableBinderTracking, boolean trackAllocation,
             boolean restrictedBackupMode, boolean persistent, in Configuration config,
             in CompatibilityInfo compatInfo, in Map services,
-            in Bundle coreSettings, in String buildSerial) = 12;
-    void scheduleExit() = 13;
-    void scheduleConfigurationChanged(in Configuration config) = 15;
+            in Bundle coreSettings, in String buildSerial);
+    void scheduleExit();
+    void scheduleConfigurationChanged(in Configuration config);
     void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-            int flags, in Intent args) = 16;
-    void updateTimeZone() = 17;
-    void processInBackground() = 18;
+            int flags, in Intent args);
+    void updateTimeZone();
+    void processInBackground();
     void scheduleBindService(IBinder token,
-            in Intent intent, boolean rebind, int processState) = 19;
+            in Intent intent, boolean rebind, int processState);
     void scheduleUnbindService(IBinder token,
-            in Intent intent) = 20;
+            in Intent intent);
     void dumpService(in ParcelFileDescriptor fd, IBinder servicetoken,
-            in String[] args) = 21;
+            in String[] args);
     void scheduleRegisteredReceiver(IIntentReceiver receiver, in Intent intent,
             int resultCode, in String data, in Bundle extras, boolean ordered,
-            boolean sticky, int sendingUser, int processState) = 22;
-    void scheduleLowMemory() = 23;
+            boolean sticky, int sendingUser, int processState);
+    void scheduleLowMemory();
     void scheduleActivityConfigurationChanged(IBinder token, in Configuration overrideConfig,
-            boolean reportToActivity) = 24;
+            boolean reportToActivity);
     void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults,
             in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed,
-            in Configuration config, in Configuration overrideConfig, boolean preserveWindow) = 25;
-    void scheduleSleeping(IBinder token, boolean sleeping) = 26;
-    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType) = 27;
-    void setSchedulingGroup(int group) = 28;
+            in Configuration config, in Configuration overrideConfig, boolean preserveWindow);
+    void scheduleSleeping(IBinder token, boolean sleeping);
+    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType);
+    void setSchedulingGroup(int group);
     void scheduleCreateBackupAgent(in ApplicationInfo app, in CompatibilityInfo compatInfo,
-            int backupMode) = 29;
+            int backupMode);
     void scheduleDestroyBackupAgent(in ApplicationInfo app,
-            in CompatibilityInfo compatInfo) = 30;
-    void scheduleOnNewActivityOptions(IBinder token, in Bundle options) = 31;
-    void scheduleSuicide() = 32;
-    void dispatchPackageBroadcast(int cmd, in String[] packages) = 33;
-    void scheduleCrash(in String msg) = 34;
-    void dumpHeap(boolean managed, in String path, in ParcelFileDescriptor fd) = 35;
+            in CompatibilityInfo compatInfo);
+    void scheduleOnNewActivityOptions(IBinder token, in Bundle options);
+    void scheduleSuicide();
+    void dispatchPackageBroadcast(int cmd, in String[] packages);
+    void scheduleCrash(in String msg);
+    void dumpHeap(boolean managed, in String path, in ParcelFileDescriptor fd);
     void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
-            in String[] args) = 36;
-    void clearDnsCache() = 37;
+            in String[] args);
+    void clearDnsCache();
     void setHttpProxy(in String proxy, in String port, in String exclList,
-            in Uri pacFileUrl) = 38;
-    void setCoreSettings(in Bundle coreSettings) = 39;
-    void updatePackageCompatibilityInfo(in String pkg, in CompatibilityInfo info) = 40;
-    void scheduleTrimMemory(int level) = 41;
+            in Uri pacFileUrl);
+    void setCoreSettings(in Bundle coreSettings);
+    void updatePackageCompatibilityInfo(in String pkg, in CompatibilityInfo info);
+    void scheduleTrimMemory(int level);
     void dumpMemInfo(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem, boolean checkin,
             boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
-            in String[] args) = 42;
-    void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args) = 43;
+            in String[] args);
+    void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args);
     void dumpProvider(in ParcelFileDescriptor fd, IBinder servicetoken,
-            in String[] args) = 44;
-    void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args) = 45;
-    void unstableProviderDied(IBinder provider) = 46;
+            in String[] args);
+    void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args);
+    void unstableProviderDied(IBinder provider);
     void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
-            int requestType, int sessionId) = 47;
-    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) = 48;
-    void setProcessState(int state) = 49;
-    void scheduleInstallProvider(in ProviderInfo provider) = 50;
-    void updateTimePrefs(boolean is24Hour) = 51;
-    void scheduleCancelVisibleBehind(IBinder token) = 52;
-    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) = 53;
-    void scheduleEnterAnimationComplete(IBinder token) = 54;
-    void notifyCleartextNetwork(in byte[] firstPacket) = 55;
-    void startBinderTracking() = 56;
-    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 57;
-    void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) = 58;
+            int requestType, int sessionId);
+    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout);
+    void setProcessState(int state);
+    void scheduleInstallProvider(in ProviderInfo provider);
+    void updateTimePrefs(int timeFormatPreference);
+    void scheduleCancelVisibleBehind(IBinder token);
+    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled);
+    void scheduleEnterAnimationComplete(IBinder token);
+    void notifyCleartextNetwork(in byte[] firstPacket);
+    void startBinderTracking();
+    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
+    void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode);
     void schedulePictureInPictureModeChanged(IBinder token,
-            boolean isInPictureInPictureMode) = 59;
+            boolean isInPictureInPictureMode);
     void scheduleLocalVoiceInteractionStarted(IBinder token,
-            IVoiceInteractor voiceInteractor) = 60;
-    void handleTrustStorageUpdate() = 61;
-    void attachAgent(String path) = 62;
-    /**
-     * 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.
-     */
-}
\ No newline at end of file
+            IVoiceInteractor voiceInteractor);
+    void handleTrustStorageUpdate();
+    void attachAgent(String path);
+}
diff --git a/core/java/android/app/IEphemeralResolver.aidl b/core/java/android/app/IEphemeralResolver.aidl
index e0cef83..260b80c 100644
--- a/core/java/android/app/IEphemeralResolver.aidl
+++ b/core/java/android/app/IEphemeralResolver.aidl
@@ -23,6 +23,6 @@
     void getEphemeralResolveInfoList(IRemoteCallback callback, in int[] digestPrefix,
             int sequence);
 
-    void getEphemeralIntentFilterList(IRemoteCallback callback, in int[] digestPrefix,
+    void getEphemeralIntentFilterList(IRemoteCallback callback, String hostName,
             int sequence);
 }
diff --git a/core/java/android/app/IInstrumentationWatcher.aidl b/core/java/android/app/IInstrumentationWatcher.aidl
index 6c8c4d6..405a3d8 100644
--- a/core/java/android/app/IInstrumentationWatcher.aidl
+++ b/core/java/android/app/IInstrumentationWatcher.aidl
@@ -21,7 +21,7 @@
 import android.os.Bundle;
 
 /** @hide */
-interface IInstrumentationWatcher
+oneway interface IInstrumentationWatcher
 {
     void instrumentationStatus(in ComponentName name, int resultCode,
             in Bundle results);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index f934a9f..cc7981c 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1505,7 +1505,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
@@ -1565,7 +1565,7 @@
                 intents[i].prepareToLeaveProcess(who);
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
                         token, options, userId);
             checkStartActivityResult(result, intents[0]);
@@ -1624,7 +1624,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target, requestCode, 0, null, options);
@@ -1684,7 +1684,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
@@ -1723,7 +1723,7 @@
         try {
             intent.migrateExtraStreamToClipData();
             intent.prepareToLeaveProcess(who);
-            int result = ActivityManagerNative.getDefault()
+            int result = ActivityManager.getService()
                 .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index da99e80..725cc29 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -21,6 +21,7 @@
 import android.app.trust.ITrustManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.RemoteException;
@@ -45,6 +46,7 @@
     private IWindowManager mWM;
     private ITrustManager mTrustManager;
     private IUserManager mUserManager;
+    private Context mContext;
 
     /**
      * Intent used to prompt user for device credentials.
@@ -87,8 +89,12 @@
         Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
         intent.putExtra(EXTRA_TITLE, title);
         intent.putExtra(EXTRA_DESCRIPTION, description);
-        // For security reasons, only allow this to come from system settings.
-        intent.setPackage("com.android.settings");
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            intent.setPackage("com.google.android.apps.wearable.settings");
+        } else {
+            // For security reasons, only allow this to come from system settings.
+            intent.setPackage("com.android.settings");
+        }
         return intent;
     }
 
@@ -109,8 +115,12 @@
         intent.putExtra(EXTRA_TITLE, title);
         intent.putExtra(EXTRA_DESCRIPTION, description);
         intent.putExtra(Intent.EXTRA_USER_ID, userId);
-        // For security reasons, only allow this to come from system settings.
-        intent.setPackage("com.android.settings");
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            intent.setPackage("com.google.android.apps.wearable.settings");
+        } else {
+            // For security reasons, only allow this to come from system settings.
+            intent.setPackage("com.android.settings");
+        }
         return intent;
     }
 
@@ -193,7 +203,8 @@
     }
 
 
-    KeyguardManager() throws ServiceNotFoundException {
+    KeyguardManager(Context context) throws ServiceNotFoundException {
+        mContext = context;
         mWM = WindowManagerGlobal.getWindowManagerService();
         mTrustManager = ITrustManager.Stub.asInterface(
                 ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE));
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 7754244..94d24e4 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -339,39 +339,43 @@
          * concatenation of both apps' shared library lists.
          */
 
-        String instrumentationPackageName = activityThread.mInstrumentationPackageName;
-        String instrumentationAppDir = activityThread.mInstrumentationAppDir;
-        String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
-        String instrumentationLibDir = activityThread.mInstrumentationLibDir;
-
-        String instrumentedAppDir = activityThread.mInstrumentedAppDir;
-        String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
-        String instrumentedLibDir = activityThread.mInstrumentedLibDir;
         String[] instrumentationLibs = null;
+        // activityThread will be null when called from the WebView zygote; just assume
+        // no instrumentation applies in this case.
+        if (activityThread != null) {
+            String instrumentationPackageName = activityThread.mInstrumentationPackageName;
+            String instrumentationAppDir = activityThread.mInstrumentationAppDir;
+            String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
+            String instrumentationLibDir = activityThread.mInstrumentationLibDir;
 
-        if (appDir.equals(instrumentationAppDir)
-                || appDir.equals(instrumentedAppDir)) {
-            outZipPaths.clear();
-            outZipPaths.add(instrumentationAppDir);
-            if (instrumentationSplitAppDirs != null) {
-                Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
-            }
-            if (!instrumentationAppDir.equals(instrumentedAppDir)) {
-                outZipPaths.add(instrumentedAppDir);
-                if (instrumentedSplitAppDirs != null) {
-                    Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
+            String instrumentedAppDir = activityThread.mInstrumentedAppDir;
+            String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
+            String instrumentedLibDir = activityThread.mInstrumentedLibDir;
+
+            if (appDir.equals(instrumentationAppDir)
+                    || appDir.equals(instrumentedAppDir)) {
+                outZipPaths.clear();
+                outZipPaths.add(instrumentationAppDir);
+                if (instrumentationSplitAppDirs != null) {
+                    Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
                 }
-            }
-
-            if (outLibPaths != null) {
-                outLibPaths.add(instrumentationLibDir);
-                if (!instrumentationLibDir.equals(instrumentedLibDir)) {
-                    outLibPaths.add(instrumentedLibDir);
+                if (!instrumentationAppDir.equals(instrumentedAppDir)) {
+                    outZipPaths.add(instrumentedAppDir);
+                    if (instrumentedSplitAppDirs != null) {
+                        Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
+                    }
                 }
-            }
 
-            if (!instrumentedAppDir.equals(instrumentationAppDir)) {
-                instrumentationLibs = getLibrariesFor(instrumentationPackageName);
+                if (outLibPaths != null) {
+                    outLibPaths.add(instrumentationLibDir);
+                    if (!instrumentationLibDir.equals(instrumentedLibDir)) {
+                        outLibPaths.add(instrumentedLibDir);
+                    }
+                }
+
+                if (!instrumentedAppDir.equals(instrumentationAppDir)) {
+                    instrumentationLibs = getLibrariesFor(instrumentationPackageName);
+                }
             }
         }
 
@@ -452,7 +456,7 @@
 
         if (mRegisterPackage) {
             try {
-                ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
+                ActivityManager.getService().addPackageDependency(mPackageName);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -891,7 +895,7 @@
                         StrictMode.onIntentReceiverLeaked(leak);
                     }
                     try {
-                        ActivityManagerNative.getDefault().unregisterReceiver(
+                        ActivityManager.getService().unregisterReceiver(
                                 rd.getIIntentReceiver());
                     } catch (RemoteException e) {
                         throw e.rethrowFromSystemServer();
@@ -917,7 +921,7 @@
                         StrictMode.onServiceConnectionLeaked(leak);
                     }
                     try {
-                        ActivityManagerNative.getDefault().unbindService(
+                        ActivityManager.getService().unbindService(
                                 sd.getIServiceConnection());
                     } catch (RemoteException e) {
                         throw e.rethrowFromSystemServer();
@@ -1046,7 +1050,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 +1099,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 +1213,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/Notification.java b/core/java/android/app/Notification.java
index 261fde2..1fd082f4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2803,10 +2803,6 @@
          * It will be played using the {@link #AUDIO_ATTRIBUTES_DEFAULT default audio attributes}
          * for notifications.
          *
-         * <p>
-         * A notification that is noisy is more likely to be presented as a heads-up notification.
-         * </p>
-         *
          * @see Notification#sound
          */
         public Builder setSound(Uri sound) {
@@ -2820,9 +2816,6 @@
          *
          * See {@link android.media.AudioManager} for the <code>STREAM_</code> constants.
          *
-         * <p>
-         * A notification that is noisy is more likely to be presented as a heads-up notification.
-         * </p>
          * @deprecated use {@link #setSound(Uri, AudioAttributes)} instead.
          * @see Notification#sound
          */
@@ -2837,10 +2830,6 @@
          * Set the sound to play, along with specific {@link AudioAttributes audio attributes} to
          * use during playback.
          *
-         * <p>
-         * A notification that is noisy is more likely to be presented as a heads-up notification.
-         * </p>
-         *
          * @see Notification#sound
          */
         public Builder setSound(Uri sound, AudioAttributes audioAttributes) {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index f259c6d..bfabc0d 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -48,8 +48,9 @@
     private static final String ATT_IMPORTANCE = "importance";
     private static final String ATT_LIGHTS = "lights";
     private static final String ATT_VIBRATION = "vibration";
-    private static final String ATT_RINGTONE = "ringtone";
-    private static final String ATT_USER_APPROVED = "approved";
+    private static final String ATT_SOUND = "sound";
+    //TODO: add audio attributes support
+    private static final String ATT_AUDIO_ATTRIBUTES = "audio_attributes";
     private static final String ATT_USER_LOCKED = "locked";
 
     /**
@@ -81,7 +82,7 @@
      * @hide
      */
     @SystemApi
-    public static final int USER_LOCKED_RINGTONE = 0x00000020;
+    public static final int USER_LOCKED_SOUND = 0x00000020;
 
     private static final int DEFAULT_VISIBILITY =
             NotificationManager.VISIBILITY_NO_OVERRIDE;
@@ -93,7 +94,7 @@
     private int mImportance = DEFAULT_IMPORTANCE;
     private boolean mBypassDnd;
     private int mLockscreenVisibility = DEFAULT_VISIBILITY;
-    private Uri mRingtone;
+    private Uri mSound;
     private boolean mLights;
     private boolean mVibration;
     private int mUserLockedFields;
@@ -124,9 +125,9 @@
         mBypassDnd = in.readByte() != 0;
         mLockscreenVisibility = in.readInt();
         if (in.readByte() != 0) {
-            mRingtone = Uri.CREATOR.createFromParcel(in);
+            mSound = Uri.CREATOR.createFromParcel(in);
         } else {
-            mRingtone = null;
+            mSound = null;
         }
         mLights = in.readByte() != 0;
         mVibration = in.readByte() != 0;
@@ -145,9 +146,9 @@
         dest.writeInt(mImportance);
         dest.writeByte(mBypassDnd ? (byte) 1 : (byte) 0);
         dest.writeInt(mLockscreenVisibility);
-        if (mRingtone != null) {
+        if (mSound != null) {
             dest.writeByte((byte) 1);
-            mRingtone.writeToParcel(dest, 0);
+            mSound.writeToParcel(dest, 0);
         } else {
             dest.writeByte((byte) 0);
         }
@@ -202,12 +203,12 @@
     // Modifiable by apps on channel creation.
 
     /**
-     * Sets the ringtone that should be played for notifications posted to this channel if
-     * the notifications don't supply a ringtone. Only modifiable before the channel is submitted
+     * Sets the sound that should be played for notifications posted to this channel if
+     * the notifications don't supply a sound. Only modifiable before the channel is submitted
      * to the NotificationManager.
      */
-    public void setRingtone(Uri ringtone) {
-        this.mRingtone = ringtone;
+    public void setSound(Uri sound) {
+        this.mSound = sound;
     }
 
     /**
@@ -261,8 +262,8 @@
     /**
      * Returns the notification sound for this channel.
      */
-    public Uri getRingtone() {
-        return mRingtone;
+    public Uri getSound() {
+        return mSound;
     }
 
     /**
@@ -304,7 +305,7 @@
         setBypassDnd(Notification.PRIORITY_DEFAULT
                 != safeInt(parser, ATT_PRIORITY, Notification.PRIORITY_DEFAULT));
         setLockscreenVisibility(safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY));
-        setRingtone(safeUri(parser, ATT_RINGTONE));
+        setSound(safeUri(parser, ATT_SOUND));
         setLights(safeBool(parser, ATT_LIGHTS, false));
         setVibration(safeBool(parser, ATT_VIBRATION, false));
         lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
@@ -330,8 +331,8 @@
             out.attribute(null, ATT_VISIBILITY,
                     Integer.toString(getLockscreenVisibility()));
         }
-        if (getRingtone() != null) {
-            out.attribute(null, ATT_RINGTONE, getRingtone().toString());
+        if (getSound() != null) {
+            out.attribute(null, ATT_SOUND, getSound().toString());
         }
         if (shouldShowLights()) {
             out.attribute(null, ATT_LIGHTS, Boolean.toString(shouldShowLights()));
@@ -364,8 +365,8 @@
         if (getLockscreenVisibility() != DEFAULT_VISIBILITY) {
             record.put(ATT_VISIBILITY, Notification.visibilityToString(getLockscreenVisibility()));
         }
-        if (getRingtone() != null) {
-            record.put(ATT_RINGTONE, getRingtone().toString());
+        if (getSound() != null) {
+            record.put(ATT_SOUND, getSound().toString());
         }
         record.put(ATT_LIGHTS, Boolean.toString(shouldShowLights()));
         record.put(ATT_VIBRATION, Boolean.toString(shouldVibrate()));
@@ -432,8 +433,8 @@
         if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
         if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null)
             return false;
-        return getRingtone() != null ? getRingtone().equals(
-                that.getRingtone()) : that.getRingtone() == null;
+        return getSound() != null ? getSound().equals(
+                that.getSound()) : that.getSound() == null;
 
     }
 
@@ -444,7 +445,7 @@
         result = 31 * result + getImportance();
         result = 31 * result + (mBypassDnd ? 1 : 0);
         result = 31 * result + getLockscreenVisibility();
-        result = 31 * result + (getRingtone() != null ? getRingtone().hashCode() : 0);
+        result = 31 * result + (getSound() != null ? getSound().hashCode() : 0);
         result = 31 * result + (mLights ? 1 : 0);
         result = 31 * result + (mVibration ? 1 : 0);
         result = 31 * result + getUserLockedFields();
@@ -459,7 +460,7 @@
                 ", mImportance=" + mImportance +
                 ", mBypassDnd=" + mBypassDnd +
                 ", mLockscreenVisibility=" + mLockscreenVisibility +
-                ", mRingtone=" + mRingtone +
+                ", mSound=" + mSound +
                 ", mLights=" + mLights +
                 ", mVibration=" + mVibration +
                 ", mUserLockedFields=" + mUserLockedFields +
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/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index f38c0d8..3ecc309 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -322,10 +322,10 @@
             }});
 
         registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class,
-                new StaticServiceFetcher<KeyguardManager>() {
+                new CachedServiceFetcher<KeyguardManager>() {
             @Override
-            public KeyguardManager createService() throws ServiceNotFoundException {
-                return new KeyguardManager();
+            public KeyguardManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+                return new KeyguardManager(ctx);
             }});
 
         registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
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 5ca39b0..0196312 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6749,4 +6749,54 @@
             throw re.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Called by the system to get the time at which the device owner last retrieved security
+     * logging entries.
+     *
+     * @return the time at which the device owner most recently retrieved security logging entries,
+     *         in milliseconds since epoch; -1 if security logging entries were never retrieved.
+     *
+     * @hide
+     */
+    public long getLastSecurityLogRetrievalTime() {
+        try {
+            return mService.getLastSecurityLogRetrievalTime();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Called by the system to get the time at which the device owner last requested a bug report.
+     *
+     * @return the time at which the device owner most recently requested a bug report, in
+     *         milliseconds since epoch; -1 if a bug report was never requested.
+     *
+     * @hide
+     */
+    public long getLastBugReportRequestTime() {
+        try {
+            return mService.getLastBugReportRequestTime();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Called by the system to get the time at which the device owner last retrieved network logging
+     * events.
+     *
+     * @return the time at which the device owner most recently retrieved network logging events, in
+     *         milliseconds since epoch; -1 if network logging events were never retrieved.
+     *
+     * @hide
+     */
+    public long getLastNetworkLogRetrievalTime() {
+        try {
+            return mService.getLastNetworkLogRetrievalTime();
+        } 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 a2546c0..d14e0d0 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -325,4 +325,8 @@
     boolean bindDeviceAdminServiceAsUser(in ComponentName admin,
         IApplicationThread caller, IBinder token, in Intent service,
         IServiceConnection connection, int flags, int targetUserId);
+
+    long getLastSecurityLogRetrievalTime();
+    long getLastBugReportRequestTime();
+    long getLastNetworkLogRetrievalTime();
 }
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 10e6fb2..231dace 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -16,7 +16,7 @@
 
 package android.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.IActivityManager;
 import android.app.QueuedWork;
@@ -366,7 +366,7 @@
          */
         public final void finish() {
             if (mType == TYPE_COMPONENT) {
-                final IActivityManager mgr = ActivityManagerNative.getDefault();
+                final IActivityManager mgr = ActivityManager.getService();
                 if (QueuedWork.hasPendingWork()) {
                     // If this is a broadcast component, we need to make sure any
                     // queued work is complete before telling AM we are done, so
@@ -393,7 +393,7 @@
             } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
                 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                         "Finishing broadcast to " + mToken);
-                final IActivityManager mgr = ActivityManagerNative.getDefault();
+                final IActivityManager mgr = ActivityManager.getService();
                 sendFinished(mgr);
             }
         }
@@ -519,7 +519,7 @@
      * Context#startService(Intent)} for more information.
      */
     public IBinder peekService(Context myContext, Intent service) {
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         IBinder binder = null;
         try {
             service.prepareToLeaveProcess(myContext);
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 49b5853..f369409 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1131,7 +1131,6 @@
      *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
      *            canceled the refresh request.
      * @return true if the provider actually tried refreshing.
-     * @hide
      */
     public boolean refresh(Uri uri, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) {
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 857610d..fd6cddb 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -147,13 +147,7 @@
             if (cursor == null) {
                 return null;
             }
-
-            if ("com.google.android.gms".equals(mPackageName)) {
-                // They're casting to a concrete subclass, sigh
-                return cursor;
-            } else {
-                return new CursorWrapperInner(cursor);
-            }
+            return new CursorWrapperInner(cursor);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 705c091..54dcd0a 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -23,7 +23,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -397,7 +397,7 @@
         }
 
         try {
-            String type = ActivityManagerNative.getDefault().getProviderMimeType(
+            String type = ActivityManager.getService().getProviderMimeType(
                     ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
             return type;
         } catch (RemoteException e) {
@@ -673,19 +673,13 @@
     }
 
     /**
-     * Implement this to support refresh of content identified by {@code uri}. By default, this
-     * method returns false; providers who wish to implement this should return true to signal the
-     * client that the provider has tried refreshing with its own implementation.
-     * <p>
      * This allows clients to request an explicit refresh of content identified by {@code uri}.
      * <p>
      * Client code should only invoke this method when there is a strong indication (such as a user
      * initiated pull to refresh gesture) that the content is stale.
      * <p>
-     * Remember to send {@link ContentResolver#notifyChange(Uri, android.database.ContentObserver)}
-     * notifications when content changes.
      *
-     * @param uri The Uri identifying the data to refresh.
+     * @param url The Uri identifying the data to refresh.
      * @param args Additional options from the client. The definitions of these are specific to the
      *            content provider being called.
      * @param cancellationSignal A signal to cancel the operation in progress, or {@code null} if
@@ -693,7 +687,6 @@
      *            {@link CancellationSignal#throwIfCanceled()} to check whether the client has
      *            canceled the refresh request.
      * @return true if the provider actually tried refreshing.
-     * @hide
      */
     public final boolean refresh(@NonNull Uri url, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) {
@@ -1849,7 +1842,7 @@
             @Intent.AccessUriMode int modeFlags) {
         Preconditions.checkNotNull(uri, "uri");
         try {
-            ActivityManagerNative.getDefault().takePersistableUriPermission(
+            ActivityManager.getService().takePersistableUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
@@ -1867,7 +1860,7 @@
             @Intent.AccessUriMode int modeFlags) {
         Preconditions.checkNotNull(uri, "uri");
         try {
-            ActivityManagerNative.getDefault().releasePersistableUriPermission(
+            ActivityManager.getService().releasePersistableUriPermission(
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri));
         } catch (RemoteException e) {
         }
@@ -1885,7 +1878,7 @@
      */
     public @NonNull List<UriPermission> getPersistedUriPermissions() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, true).getList();
         } catch (RemoteException e) {
             throw new RuntimeException("Activity manager has died", e);
@@ -1901,7 +1894,7 @@
      */
     public @NonNull List<UriPermission> getOutgoingPersistedUriPermissions() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, false).getList();
         } catch (RemoteException e) {
             throw new RuntimeException("Activity manager has died", e);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 821b0f8..5fa4275 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2337,7 +2337,7 @@
      * matches <var>filter</var>, in the main application thread.
      *
      * <p>The system may broadcast Intents that are "sticky" -- these stay
-     * around after the broadcast as finished, to be sent to any later
+     * around after the broadcast has finished, to be sent to any later
      * registrations. If your IntentFilter matches one of these sticky
      * Intents, that Intent will be returned by this function
      * <strong>and</strong> sent to your <var>receiver</var> as if it had just
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a9e987a..50589fe 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3835,6 +3835,18 @@
     public static final String EXTRA_EPHEMERAL_FAILURE = "android.intent.extra.EPHEMERAL_FAILURE";
 
     /**
+     * The host name that triggered an ephemeral resolution.
+     * @hide
+     */
+    public static final String EXTRA_EPHEMERAL_HOSTNAME = "android.intent.extra.EPHEMERAL_HOSTNAME";
+
+    /**
+     * An opaque token to track ephemeral resolution.
+     * @hide
+     */
+    public static final String EXTRA_EPHEMERAL_TOKEN = "android.intent.extra.EPHEMERAL_TOKEN";
+
+    /**
      * A Bundle forming a mapping of potential target package names to different extras Bundles
      * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
      * {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
@@ -4174,13 +4186,21 @@
             = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
 
     /**
-     * Optional boolean extra for {@link #ACTION_TIME_CHANGED} that indicates the
-     * user has set their time format preferences to the 24 hour format.
+     * Optional int extra for {@link #ACTION_TIME_CHANGED} that indicates the
+     * user has set their time format preference. See {@link #EXTRA_TIME_PREF_VALUE_USE_12_HOUR},
+     * {@link #EXTRA_TIME_PREF_VALUE_USE_24_HOUR} and
+     * {@link #EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT}. The value must not be negative.
      *
      * @hide for internal use only.
      */
     public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT =
             "android.intent.extra.TIME_PREF_24_HOUR_FORMAT";
+    /** @hide */
+    public static final int EXTRA_TIME_PREF_VALUE_USE_12_HOUR = 0;
+    /** @hide */
+    public static final int EXTRA_TIME_PREF_VALUE_USE_24_HOUR = 1;
+    /** @hide */
+    public static final int EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT = 2;
 
     /** {@hide} */
     public static final String EXTRA_REASON = "android.intent.extra.REASON";
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 32ca6c2..4adb5b7 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,7 +16,7 @@
 
 package android.content;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.Handler;
@@ -187,7 +187,7 @@
             String resolvedType = intent != null ?
                     intent.resolveTypeIfNeeded(context.getContentResolver())
                     : null;
-            int res = ActivityManagerNative.getDefault().sendIntentSender(mTarget,
+            int res = ActivityManager.getService().sendIntentSender(mTarget,
                     code, intent, resolvedType,
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
@@ -207,7 +207,7 @@
     @Deprecated
     public String getTargetPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -226,7 +226,7 @@
      */
     public String getCreatorPackage() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getPackageForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -245,7 +245,7 @@
      */
     public int getCreatorUid() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
         } catch (RemoteException e) {
             // Should never happen.
@@ -266,7 +266,7 @@
      */
     public UserHandle getCreatorUserHandle() {
         try {
-            int uid = ActivityManagerNative.getDefault()
+            int uid = ActivityManager.getService()
                 .getUidForIntentSender(mTarget);
             return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null;
         } catch (RemoteException e) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 74ec8e4..9b99bbf 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -489,6 +489,13 @@
     public static final int PRIVATE_FLAG_DIRECT_BOOT_AWARE = 1 << 6;
 
     /**
+     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
+     * and for most purposes is considered as not installed.
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 7;
+
+    /**
      * When set, at least one component inside this application is direct boot
      * aware.
      *
@@ -496,12 +503,6 @@
      */
     public static final int PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE = 1 << 8;
 
-    /**
-     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
-     * and for most purposes is considered as not installed.
-     * {@hide}
-     */
-    public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 9;
 
     /**
      * When set, signals that the application is required for the system user and should not be
@@ -509,7 +510,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER = 1 << 10;
+    public static final int PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER = 1 << 9;
 
     /**
      * When set, the application explicitly requested that its activities by resizeable by default.
@@ -517,7 +518,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET = 1 << 11;
+    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET = 1 << 10;
 
     /**
      * The application isn't requesting explicitly requesting for its activities to be resizeable or
@@ -531,7 +532,7 @@
      *
      * @hide
      */
-    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION = 1 << 12;
+    public static final int PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION = 1 << 11;
 
     /**
      * Value for {@link #privateFlags}: {@code true} means the OS should go ahead and
@@ -539,7 +540,7 @@
      * foreground-equivalent run state.  Defaults to {@code false} if unspecified.
      * @hide
      */
-    public static final int PRIVATE_FLAG_BACKUP_IN_FOREGROUND = 1 << 13;
+    public static final int PRIVATE_FLAG_BACKUP_IN_FOREGROUND = 1 << 12;
 
     /**
      * Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
@@ -1219,5 +1220,5 @@
     /** {@hide} */ public String[] getSplitCodePaths() { return splitSourceDirs; }
     /** {@hide} */ public String getResourcePath() { return scanPublicSourceDir; }
     /** {@hide} */ public String getBaseResourcePath() { return publicSourceDir; }
-    /** {@hide} */ public String[] getSplitResourcePaths() { return splitSourceDirs; }
+    /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
 }
diff --git a/core/java/android/content/pm/EphemeralRequest.java b/core/java/android/content/pm/EphemeralRequest.java
new file mode 100644
index 0000000..7f2b3ee1
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralRequest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.Intent;
+
+/**
+ * Information needed to make an ephemeral application resolution request.
+ * @hide
+ */
+public final class EphemeralRequest {
+    /** Response from the first phase of ephemeral application resolution */
+    public final EphemeralResponse responseObj;
+    /** The original intent that triggered ephemeral application resolution */
+    public final Intent origIntent;
+    /** Resolved type of the intent */
+    public final String resolvedType;
+    /** The intent that would launch if there were no ephemeral applications */
+    public final Intent launchIntent;
+    /** The name of the package requesting the ephemeral application */
+    public final String callingPackage;
+    /** ID of the user requesting the ephemeral application */
+    public final int userId;
+
+    public EphemeralRequest(EphemeralResponse responseObj, Intent origIntent,
+            String resolvedType, Intent launchIntent, String callingPackage, int userId) {
+        this.responseObj = responseObj;
+        this.origIntent = origIntent;
+        this.resolvedType = resolvedType;
+        this.launchIntent = launchIntent;
+        this.callingPackage = callingPackage;
+        this.userId = userId;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/EphemeralResolveInfo.java b/core/java/android/content/pm/EphemeralResolveInfo.java
index 3bed06b..f620088 100644
--- a/core/java/android/content/pm/EphemeralResolveInfo.java
+++ b/core/java/android/content/pm/EphemeralResolveInfo.java
@@ -137,28 +137,6 @@
         }
     };
 
-    /** @hide */
-    public static final class EphemeralResolveIntentInfo extends IntentFilter {
-        private final EphemeralResolveInfo mResolveInfo;
-        private final String mSplitName;
-
-        public EphemeralResolveIntentInfo(@NonNull IntentFilter orig,
-                @NonNull EphemeralResolveInfo resolveInfo,
-                @Nullable String splitName) {
-            super(orig);
-            mResolveInfo = resolveInfo;
-            mSplitName = splitName;
-        }
-
-        public EphemeralResolveInfo getEphemeralResolveInfo() {
-            return mResolveInfo;
-        }
-
-        public String getSplitName() {
-            return mSplitName;
-        }
-    }
-
     /**
      * Helper class to generate and store each of the digests and prefixes
      * sent to the Ephemeral Resolver.
diff --git a/core/java/android/content/pm/EphemeralResponse.java b/core/java/android/content/pm/EphemeralResponse.java
new file mode 100644
index 0000000..6e569f7
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralResponse.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.IntentFilter;
+
+/**
+ * Ephemeral application resolution response.
+ * @hide
+ */
+public final class EphemeralResponse extends IntentFilter {
+    /** Resolved information returned from the external ephemeral resolver */
+    public final EphemeralResolveInfo resolveInfo;
+    /** The resolved package. Copied from {@link #resolveInfo}. */
+    public final String packageName;
+    /** The resolve split. Copied from the matched filter in {@link #resolveInfo}. */
+    public final String splitName;
+    /** Whether or not ephemeral resolution needs the second phase */
+    public final boolean needsPhase2;
+    /** Opaque token to track the ephemeral application resolution */
+    public final String token;
+
+    public EphemeralResponse(@NonNull EphemeralResolveInfo resolveInfo,
+            @NonNull IntentFilter orig,
+            @Nullable String splitName,
+            @NonNull String token,
+            boolean needsPhase2) {
+        super(orig);
+        this.resolveInfo = resolveInfo;
+        this.packageName = resolveInfo.getPackageName();
+        this.splitName = splitName;
+        this.token = token;
+        this.needsPhase2 = needsPhase2;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 11f0eb6..d753a6e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -492,7 +492,7 @@
     /**
      * Update status of external media on the package manager to scan and
      * install packages installed on the external media. Like say the
-     * MountService uses this to call into the package manager to update
+     * StorageManagerService uses this to call into the package manager to update
      * status of sdcard.
      */
     void updateExternalMediaStatus(boolean mounted, boolean reportStatus);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 052fa61..b3dd0e5 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3514,6 +3514,36 @@
     public abstract List<ApplicationInfo> getInstalledApplications(@ApplicationInfoFlags int flags);
 
     /**
+     * Return a List of all application packages that are installed on the device, for a specific
+     * user. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all applications including
+     * those deleted with {@code DONT_DELETE_DATA} (partially installed apps with data directory)
+     * will be returned.
+     *
+     * @param flags Additional option flags. Use any combination of
+     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
+     * {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
+     * to modify the data returned.
+     * @param userId The user for whom the installed applications are to be listed
+     *
+     * @return A List of ApplicationInfo objects, one for each installed application.
+     *         In the unlikely case there are no installed packages, an empty list
+     *         is returned. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set, the
+     *         application information is retrieved from the list of uninstalled
+     *         applications (which includes installed applications as well as
+     *         applications with data directory i.e. applications which had been
+     *         deleted with {@code DONT_DELETE_DATA} flag set).
+     * @hide
+     *
+     * @see #GET_META_DATA
+     * @see #GET_SHARED_LIBRARY_FILES
+     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
+     * @see #MATCH_SYSTEM_ONLY
+     * @see #MATCH_UNINSTALLED_PACKAGES
+     */
+    public abstract List<ApplicationInfo> getInstalledApplicationsAsUser(
+            @ApplicationInfoFlags int flags, @UserIdInt int userId);
+
+    /**
      * Gets the ephemeral applications the user recently used. Requires
      * holding "android.permission.ACCESS_EPHEMERAL_APPS".
      *
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 2aa7ac6..ad0a6b2 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.util.SparseArray;
 
@@ -208,4 +209,16 @@
      */
     public abstract String getNameForUid(int uid);
 
+    /**
+     * Request to perform the second phase of ephemeral resolution.
+     * @param responseObj The response of the first phase of ephemeral resolution
+     * @param origIntent The original intent that triggered ephemeral resolution
+     * @param resolvedType The resolved type of the intent
+     * @param launchIntent The intent that would launch if there was no ephemeral application
+     * @param callingPackage The name of the package requesting the ephemeral application
+     * @param userId The ID of the user that triggered ephemeral resolution
+     */
+    public abstract void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+            Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage,
+            int userId);
 }
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 86dbe8a..f8b4570 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName;
 import android.content.IntentFilter;
-import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -66,7 +65,7 @@
      * only be set in specific circumstances.
      * @hide
      */
-    public EphemeralResolveIntentInfo ephemeralIntentInfo;
+    public EphemeralResponse ephemeralResponse;
 
     /**
      * The IntentFilter that was matched for this ResolveInfo.
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index f17fd55..cdf7013 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -19,7 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Binder;
 import android.os.CancellationSignal;
@@ -892,7 +892,7 @@
 
     private int getCurrentUserId() {
         try {
-            return ActivityManagerNative.getDefault().getCurrentUser().id;
+            return ActivityManager.getService().getCurrentUser().id;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 45aeb4a..025d46d 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -88,10 +88,10 @@
     /* Returns true if the specified USB function is enabled. */
     boolean isFunctionEnabled(String function);
 
-    /* Sets the current USB function as well as whether USB data 
-     * (for example, MTP exposed pictures) should be made available 
+    /* Sets the current USB function as well as whether USB data
+     * (for example, MTP exposed pictures) should be made available
      * on the USB connection. Unlocking data should only be done with
-     * user involvement, since exposing pictures or other data could 
+     * user involvement, since exposing pictures or other data could
      * leak sensitive user information.
      */
     void setCurrentFunction(String function, boolean usbDataUnlocked);
diff --git a/core/java/android/net/RoughtimeClient.java b/core/java/android/net/RoughtimeClient.java
new file mode 100644
index 0000000..cf4d8a2
--- /dev/null
+++ b/core/java/android/net/RoughtimeClient.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+
+/**
+ * {@hide}
+ *
+ * Simple Roughtime client class for retrieving network time.
+ */
+public class RoughtimeClient
+{
+    private static final String TAG = "RoughtimeClient";
+    private static final boolean ENABLE_DEBUG = true;
+
+    private static final int ROUGHTIME_PORT = 5333;
+
+    private static final int MIN_REQUEST_SIZE = 1024;
+
+    private static final int NONCE_SIZE = 64;
+
+    private static final int MAX_DATAGRAM_SIZE = 65507;
+
+    private final SecureRandom random = new SecureRandom();
+
+    /**
+     * Tag values. Exposed for use in tests only.
+     */
+    protected static enum Tag {
+        /**
+         * Nonce used to initiate a transaction.
+         */
+        NONC(0x434e4f4e),
+
+        /**
+         * Signed portion of a response.
+         **/
+        SREP(0x50455253),
+
+        /**
+         * Pad data. Always the largest tag lexicographically.
+         */
+        PAD(0xff444150),
+
+        /**
+         * A signature for a neighboring SREP.
+         */
+        SIG(0x474953),
+
+        /**
+         * Server certificate.
+         */
+        CERT(0x54524543),
+
+        /**
+         * Position in the Merkle tree.
+         */
+        INDX(0x58444e49),
+
+        /**
+         * Upward path in the Merkle tree.
+         */
+        PATH(0x48544150),
+
+        /**
+         * Midpoint of the time interval in the response.
+         */
+        MIDP(0x5044494d),
+
+        /**
+         * Radius of the time interval in the response.
+         */
+        RADI(0x49444152),
+
+        /**
+         * Root of the Merkle tree.
+         */
+        ROOT(0x544f4f52),
+
+        /**
+         * Delegation from the long term key to an online key.
+         */
+        DELE(0x454c4544),
+
+        /**
+         * Online public key.
+         */
+        PUBK(0x4b425550),
+
+        /**
+         * Earliest midpoint time the given PUBK can authenticate.
+         */
+        MINT(0x544e494d),
+
+        /**
+         * Latest midpoint time the given PUBK can authenticate.
+         */
+        MAXT(0x5458414d);
+
+        private final int value;
+
+        Tag(int value) {
+            this.value = value;
+        }
+
+        private int value() {
+            return value;
+        }
+    }
+
+    /**
+     * A result retrieved from a roughtime server.
+     */
+    private static class Result {
+        public long midpoint;
+        public int radius;
+        public long collectionTime;
+    }
+
+    /**
+     * A Roughtime protocol message. Functionally a serializable map from Tags
+     * to byte arrays.
+     */
+    protected static class Message {
+        private HashMap<Integer,byte[]> items = new HashMap<Integer,byte[]>();
+        public int padSize = 0;
+
+        public Message() {}
+
+        /**
+         * Set the given data for the given tag.
+         */
+        public void put(Tag tag, byte[] data) {
+            put(tag.value(), data);
+        }
+
+        private void put(int tag, byte[] data) {
+            items.put(tag, data);
+        }
+
+        /**
+         * Get the data associated with the given tag.
+         */
+        public byte[] get(Tag tag) {
+            return items.get(tag.value());
+        }
+
+        /**
+         * Get the data associated with the given tag and decode it as a 64-bit
+         * integer.
+         */
+        public long getLong(Tag tag) {
+            ByteBuffer b = ByteBuffer.wrap(get(tag));
+            return b.getLong();
+        }
+
+        /**
+         * Get the data associated with the given tag and decode it as a 32-bit
+         * integer.
+         */
+        public int getInt(Tag tag) {
+            ByteBuffer b = ByteBuffer.wrap(get(tag));
+            return b.getInt();
+        }
+
+        /**
+         * Encode the given long value as a 64-bit little-endian value and
+         * associate it with the given tag.
+         */
+        public void putLong(Tag tag, long l) {
+            ByteBuffer b = ByteBuffer.allocate(8);
+            b.putLong(l);
+            put(tag, b.array());
+        }
+
+        /**
+         * Encode the given int value as a 32-bit little-endian value and
+         * associate it with the given tag.
+         */
+        public void putInt(Tag tag, int l) {
+            ByteBuffer b = ByteBuffer.allocate(4);
+            b.putInt(l);
+            put(tag, b.array());
+        }
+
+        /**
+         * Get a packed representation of this message suitable for the wire.
+         */
+        public byte[] serialize() {
+            if (items.size() == 0) {
+                if (padSize > 4)
+                    return new byte[padSize];
+                else
+                    return new byte[4];
+            }
+
+            int size = 0;
+
+            ArrayList<Integer> offsets = new ArrayList<Integer>();
+            ArrayList<Integer> tagList = new ArrayList<Integer>(items.keySet());
+            Collections.sort(tagList);
+
+            boolean first = true;
+            for (int tag : tagList) {
+                if (! first) {
+                    offsets.add(size);
+                }
+
+                first = false;
+                size += items.get(tag).length;
+            }
+
+            ByteBuffer dataBuf = ByteBuffer.allocate(size);
+            dataBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+            int valueDataSize = size;
+            size += 4 + offsets.size() * 4 + tagList.size() * 4;
+
+            int tagCount = items.size();
+
+            if (size < padSize) {
+                offsets.add(valueDataSize);
+                tagList.add(Tag.PAD.value());
+
+                if (size + 8 > padSize) {
+                    size = size + 8;
+                } else {
+                    size = padSize;
+                }
+
+                tagCount += 1;
+            }
+
+            ByteBuffer buf = ByteBuffer.allocate(size);
+            buf.order(ByteOrder.LITTLE_ENDIAN);
+            buf.putInt(tagCount);
+
+            for (int offset : offsets) {
+                buf.putInt(offset);
+            }
+
+            for (int tag : tagList) {
+                buf.putInt(tag);
+
+                if (tag != Tag.PAD.value()) {
+                    dataBuf.put(items.get(tag));
+                }
+            }
+
+            buf.put(dataBuf.array());
+
+            return buf.array();
+        }
+
+        /**
+         * Given a byte stream from the wire, unpack it into a Message object.
+         */
+        public static Message deserialize(byte[] data) {
+            ByteBuffer buf = ByteBuffer.wrap(data);
+            buf.order(ByteOrder.LITTLE_ENDIAN);
+
+            Message msg = new Message();
+
+            int count = buf.getInt();
+
+            if (count == 0) {
+                return msg;
+            }
+
+            ArrayList<Integer> offsets = new ArrayList<Integer>();
+            offsets.add(0);
+
+            for (int i = 1; i < count; i++) {
+                offsets.add(buf.getInt());
+            }
+
+            ArrayList<Integer> tags = new ArrayList<Integer>();
+            for (int i = 0; i < count; i++) {
+                int tag = buf.getInt();
+                tags.add(tag);
+            }
+
+            offsets.add(buf.remaining());
+
+            for (int i = 0; i < count; i++) {
+                int tag = tags.get(i);
+                int start = offsets.get(i);
+                int end = offsets.get(i+1);
+                byte[] content = new byte[end - start];
+
+                buf.get(content);
+                if (tag != Tag.PAD.value()) {
+                    msg.put(tag, content);
+                }
+            }
+
+            return msg;
+        }
+
+        /**
+         * Send this message over the given socket to the given address and port.
+         */
+        public void send(DatagramSocket socket, InetAddress address, int port)
+                throws IOException {
+            byte[] buffer = serialize();
+            DatagramPacket message = new DatagramPacket(buffer, buffer.length,
+                    address, port);
+            socket.send(message);
+        }
+
+        /**
+         * Receive a Message object from the given socket.
+         */
+        public static Message receive(DatagramSocket socket)
+                throws IOException {
+            byte[] buffer = new byte[MAX_DATAGRAM_SIZE];
+            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
+
+            socket.receive(packet);
+
+            return deserialize(Arrays.copyOf(buffer, packet.getLength()));
+        }
+    }
+
+    private MessageDigest messageDigest = null;
+
+    private final ArrayList<Result> results = new ArrayList<Result>();
+    private long lastRequest = 0;
+
+    private Message createRequestMessage() {
+        byte[] nonce = new byte[NONCE_SIZE];
+        random.nextBytes(nonce); // TODO: Chain nonces
+
+        assert nonce.length == NONCE_SIZE :
+            "Nonce must be " + NONCE_SIZE + " bytes.";
+
+        Message msg = new Message();
+
+        msg.put(Tag.NONC, nonce);
+        msg.padSize = MIN_REQUEST_SIZE;
+
+        return msg;
+    }
+
+    /**
+     * Contact the Roughtime server at the given address and port and collect a
+     * result time to add to our collection.
+     *
+     * @param host host name of the server.
+     * @param timeout network timeout in milliseconds.
+     * @return true if the transaction was successful.
+     */
+    public boolean requestTime(String host, int timeout) {
+        InetAddress address = null;
+        try {
+            address = InetAddress.getByName(host);
+        } catch (Exception e) {
+            if (ENABLE_DEBUG) {
+                Log.d(TAG, "request time failed", e);
+            }
+
+            return false;
+        }
+        return requestTime(address, ROUGHTIME_PORT, timeout);
+    }
+
+    /**
+     * Contact the Roughtime server at the given address and port and collect a
+     * result time to add to our collection.
+     *
+     * @param address address for the server.
+     * @param port port to talk to the server on.
+     * @param timeout network timeout in milliseconds.
+     * @return true if the transaction was successful.
+     */
+    public boolean requestTime(InetAddress address, int port, int timeout) {
+
+        final long rightNow = SystemClock.elapsedRealtime();
+
+        if ((rightNow - lastRequest) > timeout) {
+            results.clear();
+        }
+
+        lastRequest = rightNow;
+
+        DatagramSocket socket = null;
+        try {
+            if (messageDigest == null) {
+                messageDigest = MessageDigest.getInstance("SHA-512");
+            }
+
+            socket = new DatagramSocket();
+            socket.setSoTimeout(timeout);
+            final long startTime = SystemClock.elapsedRealtime();
+            Message request = createRequestMessage();
+            request.send(socket, address, port);
+            final long endTime = SystemClock.elapsedRealtime();
+            Message response = Message.receive(socket);
+            byte[] signedData = response.get(Tag.SREP);
+            Message signedResponse = Message.deserialize(signedData);
+
+            final Result result = new Result();
+            result.midpoint = signedResponse.getLong(Tag.MIDP);
+            result.radius = signedResponse.getInt(Tag.RADI);
+            result.collectionTime = (startTime + endTime) / 2;
+
+            final byte[] root = signedResponse.get(Tag.ROOT);
+            final byte[] path = response.get(Tag.PATH);
+            final byte[] nonce = request.get(Tag.NONC);
+            final int index = response.getInt(Tag.INDX);
+
+            if (! verifyNonce(root, path, nonce, index)) {
+                Log.w(TAG, "failed to authenticate roughtime response.");
+                return false;
+            }
+
+            results.add(result);
+        } catch (Exception e) {
+            if (ENABLE_DEBUG) {
+                Log.d(TAG, "request time failed", e);
+            }
+
+            return false;
+        } finally {
+            if (socket != null) {
+                socket.close();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Verify that a reply message corresponds to the nonce sent in the request.
+     *
+     * @param root  Root of the Merkle tree used to sign the nonce. Received in
+     *              the ROOT tag of the reply.
+     * @param path  Sibling hashes along the path to the root of the Merkle tree.
+     *              Received in the PATH tag of the reply.
+     * @param nonce The nonce we sent in the request.
+     * @param index Bitfield indicating whether chunks of the path are left or
+     *              right children.
+     * @return true if the verification is successful.
+     */
+    private boolean verifyNonce(byte[] root, byte[] path, byte[] nonce,
+            int index) {
+        messageDigest.update(new byte[]{ 0 });
+        byte[] hash = messageDigest.digest(nonce);
+        int pos = 0;
+        byte[] one = new byte[]{ 1 };
+
+        while (pos < path.length) {
+            messageDigest.update(one);
+
+            if ((index&1) != 0) {
+                messageDigest.update(path, pos, 64);
+                hash = messageDigest.digest(hash);
+            } else {
+                messageDigest.update(hash);
+                messageDigest.update(path, pos, 64);
+                hash = messageDigest.digest();
+            }
+
+            pos += 64;
+            index >>>= 1;
+        }
+
+        return Arrays.equals(root, hash);
+    }
+}
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 1ac9fca..e7436be 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -108,6 +108,26 @@
      */
     public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
 
+    /** @hide */
+    public static final int TAG_SYSTEM_DHCP = 0xFFFFFF05;
+    /** @hide */
+    public static final int TAG_SYSTEM_NTP = 0xFFFFFF06;
+    /** @hide */
+    public static final int TAG_SYSTEM_PROBE = 0xFFFFFF07;
+    /** @hide */
+    public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF08;
+    /** @hide */
+    public static final int TAG_SYSTEM_GPS = 0xFFFFFF09;
+    /** @hide */
+    public static final int TAG_SYSTEM_PAC = 0xFFFFFF0A;
+
+    /**
+     * Sockets that are strictly local on device; never hits network.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_LOCAL = 0xFFFFFFAA;
+
     private static INetworkStatsService sStatsService;
 
     private synchronized static INetworkStatsService getStatsService() {
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 bca9156..0946906 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5870,7 +5870,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 83b2065..5f27e34 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -15,7 +15,6 @@
  */
 package android.service.autofill;
 
-import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.app.Activity;
 import android.app.Service;
@@ -34,9 +33,6 @@
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.os.SomeArgs;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * Top-level service of the current auto-fill service for a given user.
  *
@@ -56,9 +52,9 @@
     @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_AUTO_FILL = 2;
-    private static final int MSG_SHUTDOWN = 3;
+    private static final int MSG_CONNECT = 1;
+    private static final int MSG_AUTO_FILL_ACTIVITY = 2;
+    private static final int MSG_DISCONNECT = 3;
 
     private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
         @Override
@@ -70,15 +66,15 @@
                     .getBinder(VoiceInteractionSession.KEY_AUTO_FILL_CALLBACK);
 
             mHandlerCaller
-                .obtainMessageOO(MSG_AUTO_FILL, structure, binder).sendToTarget();
+                .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
@@ -87,8 +83,8 @@
         }
 
         @Override
-        public void shutdown() {
-            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_SHUTDOWN));
+        public void onDisconnected() {
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DISCONNECT));
         }
     };
 
@@ -97,17 +93,17 @@
         @Override
         public void executeMessage(Message msg) {
             switch (msg.what) {
-                case MSG_READY: {
-                    onReady();
+                case MSG_CONNECT: {
+                    onConnected();
                     break;
-                } case MSG_AUTO_FILL: {
+                } case MSG_AUTO_FILL_ACTIVITY: {
                     final SomeArgs args = (SomeArgs) msg.obj;
                     final AssistStructure structure = (AssistStructure) args.arg1;
                     final IBinder binder = (IBinder) args.arg2;
-                    autoFillActivity(structure, binder);
+                    requestAutoFill(structure, binder);
                     break;
-                } case MSG_SHUTDOWN: {
-                    onShutdown();
+                } case MSG_DISCONNECT: {
+                    onDisconnected();
                     break;
                 } default: {
                     Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
@@ -118,6 +114,11 @@
 
     private HandlerCaller mHandlerCaller;
 
+    /**
+     * {@inheritDoc}
+     *
+     * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}.
+     */
     @Override
     public void onCreate() {
         super.onCreate();
@@ -135,14 +136,12 @@
     }
 
     /**
-     * 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}.
      */
-    // TODO: rename to onConnect() / update javadoc
-    public void onReady() {
-        if (DEBUG) Log.d(TAG, "onReady()");
+    public void onConnected() {
+        if (DEBUG) Log.d(TAG, "onConnected()");
     }
 
     /**
@@ -155,21 +154,18 @@
     public abstract void onFillRequest(AssistStructure structure,
             CancellationSignal cancellationSignal, FillCallback callback);
 
-    private void autoFillActivity(AssistStructure structure, IBinder binder) {
+    private void requestAutoFill(AssistStructure structure, IBinder binder) {
         final FillCallback callback = new FillCallback(binder);
         // TODO: hook up the cancelationSignal
         onFillRequest(structure, new CancellationSignal(), callback);
     }
 
     /**
-     * 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}.
      */
-    // TODO: rename to onDisconnected() / update javadoc
-    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
index bdcc93b..2308440 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -62,9 +62,6 @@
         }
     }
 
-    /**
-     * Notifies the activity that the auto-fill request failed.
-     */
     public void onFailure(CharSequence message) {
         if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
 
diff --git a/core/java/android/service/autofill/IAutoFillCallback.aidl b/core/java/android/service/autofill/IAutoFillCallback.aidl
index db8ef96..d6d4f39 100644
--- a/core/java/android/service/autofill/IAutoFillCallback.aidl
+++ b/core/java/android/service/autofill/IAutoFillCallback.aidl
@@ -21,7 +21,7 @@
 /**
  * @hide
  */
-interface IAutoFillCallback {
+oneway 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 a91841b..76a2561 100644
--- a/core/java/android/service/autofill/IAutoFillManagerService.aidl
+++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl
@@ -23,16 +23,13 @@
  *
  * {@hide}
  */
-interface IAutoFillManagerService {
+oneway interface IAutoFillManagerService {
 
     /**
      * Request auto-fill on the top activity of a given user.
      *
      * @param userId user handle.
      * @param activityToken optional token of activity that needs to be on top.
-     *
-     * @return whether the request succeeded  (for example, if the activity's
-     *         user does not have an auto-fill service associated with, it will return false).
      */
-    boolean requestAutoFill(int userId, IBinder activityToken);
+    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 dca3c70..bb122e5 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -25,8 +25,7 @@
  * @hide
  */
 interface IAutoFillService {
-    // TODO: rename to onConnected() / onDisconnected()
-    void ready();
-    void shutdown();
+    oneway void onConnected();
+    oneway void onDisconnected();
     IResultReceiver getAssistReceiver();
 }
diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index 455e1b2..813acc2 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -107,12 +107,12 @@
      * <p>
      * Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * Or the calling app has carrier privileges.
-     *   @see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}
+     * or the calling app has carrier privileges.
      *
      * @param active Whether the carrier network change is or shortly will be
      *               active. Set this value to true to begin showing
      *               alternative UI and false to stop.
+     * @see android.telephony.TelephonyManager#hasCarrierPrivileges
      */
     public final void notifyCarrierNetworkChange(boolean active) {
         try {
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 479f493..6e4d78d 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -242,14 +242,20 @@
 
         Transition mTransition;
         ViewGroup mSceneRoot;
+        final ViewTreeObserver mViewTreeObserver;
 
         MultiListener(Transition transition, ViewGroup sceneRoot) {
             mTransition = transition;
             mSceneRoot = sceneRoot;
+            mViewTreeObserver = mSceneRoot.getViewTreeObserver();
         }
 
         private void removeListeners() {
-            mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+            if (mViewTreeObserver.isAlive()) {
+                mViewTreeObserver.removeOnPreDrawListener(this);
+            } else {
+                mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+            }
             mSceneRoot.removeOnAttachStateChangeListener(this);
         }
 
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 7a3c95e..8eca431 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -26,6 +26,8 @@
 
 import dalvik.annotation.optimization.FastNative;
 
+import libcore.util.NativeAllocationRegistry;
+
 /**
  * <p>A display list records a series of graphics related operations and can replay
  * them later. Display lists are usually built by recording operations on a
@@ -130,13 +132,20 @@
  */
 public class RenderNode {
 
+    // Use a Holder to allow static initialization in the boot image.
+    private static class NoImagePreloadHolder {
+        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+                RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
+    }
+
     private boolean mValid;
     // Do not access directly unless you are ThreadedRenderer
-    long mNativeRenderNode;
+    final long mNativeRenderNode;
     private final View mOwningView;
 
     private RenderNode(String name, View owningView) {
         mNativeRenderNode = nCreate(name);
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
         mOwningView = owningView;
     }
 
@@ -145,6 +154,7 @@
      */
     private RenderNode(long nativePtr) {
         mNativeRenderNode = nativePtr;
+        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
         mOwningView = null;
     }
 
@@ -154,19 +164,7 @@
      * is not feasible.
      */
     public void destroy() {
-        if (mNativeRenderNode != 0) {
-            nFinalize(mNativeRenderNode);
-            mNativeRenderNode = 0;
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroy();
-        } finally {
-            super.finalize();
-        }
+        // TODO: Removed temporarily
     }
 
     /**
@@ -835,7 +833,6 @@
 
     // Intentionally not static because it acquires a reference to 'this'
     private native long nCreate(String name);
-    private native void nFinalize(long renderNode);
 
     private static native long nGetNativeFinalizer();
     private static native void nSetDisplayList(long renderNode, long newData);
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 0bb84cc..5012215 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -18,7 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -921,7 +921,7 @@
         private static void initSched(Context context, long renderProxy) {
             try {
                 int tid = nGetRenderThreadTid(renderProxy);
-                ActivityManagerNative.getDefault().setRenderThread(tid);
+                ActivityManager.getService().setRenderThread(tid);
             } catch (Throwable t) {
                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
             }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cdd8b6a..1ff8fb0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -26,7 +26,7 @@
 import android.Manifest;
 import android.animation.LayoutTransition;
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ResourcesManager;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -7084,7 +7084,7 @@
 
         private static int checkCallingPermission(String permission) {
             try {
-                return ActivityManagerNative.getDefault().checkPermission(
+                return ActivityManager.getService().checkPermission(
                         permission, Binder.getCallingPid(), Binder.getCallingUid());
             } catch (RemoteException e) {
                 return PackageManager.PERMISSION_DENIED;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4195d91..82379c4 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -672,7 +672,7 @@
      * button bar.
      */
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the display height available after excluding any screen
@@ -680,7 +680,7 @@
      * button bar.
      */
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the available screen width that we should report for the
@@ -689,7 +689,7 @@
      * that to account for more transient decoration like a status bar.
      */
     public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return the available screen height that we should report for the
@@ -698,7 +698,7 @@
      * that to account for more transient decoration like a status bar.
      */
     public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode);
+            int uiMode, int displayId);
 
     /**
      * Return whether the given window can become the Keyguard window. Typically returns true for
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index f4ea90b..eb0c44c 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;
@@ -57,7 +57,9 @@
 @SystemApi
 public final class WebViewFactory {
 
-    private static final String CHROMIUM_WEBVIEW_FACTORY =
+    // visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote.
+    /** @hide */
+    public static final String CHROMIUM_WEBVIEW_FACTORY =
             "com.android.webview.chromium.WebViewChromiumFactoryProvider";
 
     private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create";
@@ -292,7 +294,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/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index bc6e7b4..c206974 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -16,14 +16,19 @@
 
 package android.webkit;
 
+import android.app.LoadedApk;
 import android.content.pm.PackageInfo;
 import android.os.Build;
 import android.os.SystemService;
 import android.os.ZygoteProcess;
+import android.text.TextUtils;
 import android.util.Log;
 
+import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.TimeoutException;
 
 /** @hide */
@@ -122,11 +127,21 @@
         try {
             sZygote = new ZygoteProcess("webview_zygote", null);
 
-            String packagePath = sPackage.applicationInfo.sourceDir;
-            String libsPath = sPackage.applicationInfo.nativeLibraryDir;
+            // All the work below is usually done by LoadedApk, but the zygote can't talk to
+            // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so
+            // doesn't have an ActivityThread and can't use Binder.
+            // Instead, figure out the paths here, in the system server where we have access to
+            // the package manager. Reuse the logic from LoadedApk to determine the correct
+            // paths and pass them to the zygote as strings.
+            final List<String> zipPaths = new ArrayList<>(10);
+            final List<String> libPaths = new ArrayList<>(10);
+            LoadedApk.makePaths(null, sPackage.applicationInfo, zipPaths, libPaths);
+            final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
+            final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
+                    TextUtils.join(File.pathSeparator, zipPaths);
 
-            Log.d(LOGTAG, "Preloading package " + packagePath + " " + libsPath);
-            sZygote.preloadPackageForAbi(packagePath, libsPath, Build.SUPPORTED_ABIS[0]);
+            Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
+            sZygote.preloadPackageForAbi(zip, librarySearchPath, Build.SUPPORTED_ABIS[0]);
         } catch (Exception e) {
             Log.e(LOGTAG, "Error connecting to " + serviceName, e);
             sZygote = null;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 5eaabe7..541fbe0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -111,6 +111,8 @@
 import android.widget.TextView.OnEditorActionListener;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 import com.android.internal.util.Preconditions;
@@ -1119,14 +1121,26 @@
             getInsertionController().show();
             mIsInsertionActionModeStartPending = true;
             handled = true;
+            MetricsLogger.action(
+                    mTextView.getContext(),
+                    MetricsEvent.TEXT_LONGPRESS,
+                    TextViewMetrics.SUBTYPE_LONG_PRESS_OTHER);
         }
 
         if (!handled && mTextActionMode != null) {
             if (touchPositionIsInSelection()) {
                 startDragAndDrop();
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_DRAG_AND_DROP);
             } else {
                 stopTextActionMode();
                 selectCurrentWordAndStartDrag();
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_SELECTION);
             }
             handled = true;
         }
@@ -1134,6 +1148,12 @@
         // Start a new selection
         if (!handled) {
             handled = selectCurrentWordAndStartDrag();
+            if (handled) {
+                MetricsLogger.action(
+                        mTextView.getContext(),
+                        MetricsEvent.TEXT_LONGPRESS,
+                        TextViewMetrics.SUBTYPE_LONG_PRESS_SELECTION);
+            }
         }
 
         return handled;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 18ce260..a9268d4 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -404,6 +404,7 @@
         // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache
         mBitmapCache = new BitmapCache();
         setBitmapCache(mBitmapCache);
+        recalculateMemoryUsage();
     }
 
     private class SetEmptyView extends Action {
@@ -2117,26 +2118,8 @@
             return mMemoryUsage;
         }
 
-        @SuppressWarnings("deprecation")
         public void addBitmapMemory(Bitmap b) {
-            final Bitmap.Config c = b.getConfig();
-            // If we don't know, be pessimistic and assume 4
-            int bpp = 4;
-            if (c != null) {
-                switch (c) {
-                    case ALPHA_8:
-                        bpp = 1;
-                        break;
-                    case RGB_565:
-                    case ARGB_4444:
-                        bpp = 2;
-                        break;
-                    case ARGB_8888:
-                        bpp = 4;
-                        break;
-                }
-            }
-            increment(b.getWidth() * b.getHeight() * bpp);
+            increment(b.getAllocationByteCount());
         }
 
         int mMemoryUsage;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5426a37..69f463c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -148,6 +148,8 @@
 import android.widget.RemoteViews.RemoteView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.FastMath;
 import com.android.internal.widget.EditableInputConnection;
 
@@ -9685,6 +9687,11 @@
         if (handled) {
             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
             if (mEditor != null) mEditor.mDiscardNextActionUp = true;
+        } else {
+            MetricsLogger.action(
+                    mContext,
+                    MetricsEvent.TEXT_LONGPRESS,
+                    TextViewMetrics.SUBTYPE_LONG_PRESS_OTHER);
         }
 
         return handled;
diff --git a/core/java/android/widget/TextViewMetrics.java b/core/java/android/widget/TextViewMetrics.java
new file mode 100644
index 0000000..0a14d3e
--- /dev/null
+++ b/core/java/android/widget/TextViewMetrics.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+/**
+ * {@link com.android.internal.logging.MetricsLogger} values for TextView.
+ *
+ * @hide
+ */
+final class TextViewMetrics {
+
+    private TextViewMetrics() {}
+
+    /**
+     * Long press on TextView - no special classification.
+     */
+    static final int SUBTYPE_LONG_PRESS_OTHER = 0;
+    /**
+     * Long press on TextView - selection started.
+     */
+    static final int SUBTYPE_LONG_PRESS_SELECTION = 1;
+    /**
+     * Long press on TextView - drag and drop started.
+     */
+    static final int SUBTYPE_LONG_PRESS_DRAG_AND_DROP = 2;
+}
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index 83ad9dc..459071b 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -19,7 +19,7 @@
 import com.android.internal.R;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
@@ -122,7 +122,7 @@
     private OnClickListener mSwitchOldListener = new OnClickListener() {
         public void onClick(View v) {
             try {
-                ActivityManagerNative.getDefault().moveTaskToFront(mCurTask, 0, null);
+                ActivityManager.getService().moveTaskToFront(mCurTask, 0, null);
             } catch (RemoteException e) {
             }
             finish();
@@ -132,7 +132,7 @@
     private OnClickListener mSwitchNewListener = new OnClickListener() {
         public void onClick(View v) {
             try {
-                ActivityManagerNative.getDefault().finishHeavyWeightApp();
+                ActivityManager.getService().finishHeavyWeightApp();
             } catch (RemoteException e) {
             }
             try {
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 015e60d..0b27c60 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -19,7 +19,7 @@
 import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
@@ -110,9 +110,9 @@
                 int launchedFromUid = -1;
                 String launchedFromPackage = "?";
                 try {
-                    launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+                    launchedFromUid = ActivityManager.getService().getLaunchedFromUid(
                             getActivityToken());
-                    launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                    launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
                             getActivityToken());
                 } catch (RemoteException ignored) {
                 }
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 472f583..9936ed5 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -18,7 +18,7 @@
 
 import com.android.internal.R;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.ListFragment;
 import android.app.backup.BackupManager;
@@ -269,7 +269,7 @@
      */
     public static void updateLocales(LocaleList locales) {
         try {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             final Configuration config = am.getConfiguration();
 
             config.setLocales(locales);
@@ -290,7 +290,7 @@
      */
     public static LocaleList getLocales() {
         try {
-            return ActivityManagerNative.getDefault()
+            return ActivityManager.getService()
                     .getConfiguration().getLocales();
         } catch (RemoteException e) {
             // If something went wrong
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 72a40b7..dd8ef18 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -35,7 +35,6 @@
 import com.android.internal.content.PackageMonitor;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
@@ -245,7 +244,7 @@
         setProfileSwitchMessageId(intent.getContentUserHint());
 
         try {
-            mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+            mLaunchedFromUid = ActivityManager.getService().getLaunchedFromUid(
                     getActivityToken());
         } catch (RemoteException e) {
             mLaunchedFromUid = -1;
@@ -864,7 +863,7 @@
         } catch (RuntimeException e) {
             String launchedFromPackage;
             try {
-                launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
                         getActivityToken());
             } catch (RemoteException e2) {
                 launchedFromPackage = "??";
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 4e3c3fc..a3134b3b 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -29,7 +29,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
 import android.os.storage.StorageVolume;
@@ -53,7 +53,7 @@
 /**
  * Constants used internally between the PackageManager
  * and media container service transports.
- * Some utility methods to invoke MountService api.
+ * Some utility methods to invoke StorageManagerService api.
  */
 public class PackageHelper {
     public static final int RECOMMEND_INSTALL_INTERNAL = 1;
@@ -74,13 +74,13 @@
     public static final int APP_INSTALL_INTERNAL = 1;
     public static final int APP_INSTALL_EXTERNAL = 2;
 
-    public static IMountService getMountService() throws RemoteException {
+    public static IStorageManager getStorageManager() throws RemoteException {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
-            throw new RemoteException("Could not contact mount service");
+            Log.e(TAG, "Can't get storagemanager service");
+            throw new RemoteException("Could not contact storagemanager service");
         }
     }
 
@@ -89,23 +89,23 @@
         // Round up to nearest MB, plus another MB for filesystem overhead
         final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
         try {
-            IMountService mountService = getMountService();
+            IStorageManager storageManager = getStorageManager();
 
             if (localLOGV)
                 Log.i(TAG, "Size of container " + sizeMb + " MB");
 
-            int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
+            int rc = storageManager.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
                     isExternal);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.e(TAG, "Failed to create secure container " + cid);
                 return null;
             }
-            String cachePath = mountService.getSecureContainerPath(cid);
+            String cachePath = storageManager.getSecureContainerPath(cid);
             if (localLOGV) Log.i(TAG, "Created secure container " + cid +
                     " at " + cachePath);
                 return cachePath;
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         return null;
     }
@@ -114,13 +114,13 @@
         // Round up to nearest MB, plus another MB for filesystem overhead
         final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
         try {
-            IMountService mountService = getMountService();
-            int rc = mountService.resizeSecureContainer(cid, sizeMb, sdEncKey);
+            IStorageManager storageManager = getStorageManager();
+            int rc = storageManager.resizeSecureContainer(cid, sizeMb, sdEncKey);
             if (rc == StorageResultCode.OperationSucceeded) {
                 return true;
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         Log.e(TAG, "Failed to create secure container " + cid);
         return false;
@@ -132,35 +132,35 @@
 
     public static String mountSdDir(String cid, String key, int ownerUid, boolean readOnly) {
         try {
-            int rc = getMountService().mountSecureContainer(cid, key, ownerUid, readOnly);
+            int rc = getStorageManager().mountSecureContainer(cid, key, ownerUid, readOnly);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to mount container " + cid + " rc : " + rc);
                 return null;
             }
-            return getMountService().getSecureContainerPath(cid);
+            return getStorageManager().getSecureContainerPath(cid);
         } catch (RemoteException e) {
-            Log.e(TAG, "MountService running?");
+            Log.e(TAG, "StorageManagerService running?");
         }
         return null;
     }
 
    public static boolean unMountSdDir(String cid) {
     try {
-        int rc = getMountService().unmountSecureContainer(cid, true);
+        int rc = getStorageManager().unmountSecureContainer(cid, true);
         if (rc != StorageResultCode.OperationSucceeded) {
             Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
             return false;
         }
         return true;
     } catch (RemoteException e) {
-        Log.e(TAG, "MountService running?");
+        Log.e(TAG, "StorageManagerService running?");
     }
         return false;
    }
 
    public static boolean renameSdDir(String oldId, String newId) {
        try {
-           int rc = getMountService().renameSecureContainer(oldId, newId);
+           int rc = getStorageManager().renameSecureContainer(oldId, newId);
            if (rc != StorageResultCode.OperationSucceeded) {
                Log.e(TAG, "Failed to rename " + oldId + " to " +
                        newId + "with rc " + rc);
@@ -176,7 +176,7 @@
 
    public static String getSdDir(String cid) {
        try {
-            return getMountService().getSecureContainerPath(cid);
+            return getStorageManager().getSecureContainerPath(cid);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get container path for " + cid +
                 " with exception " + e);
@@ -186,7 +186,7 @@
 
    public static String getSdFilesystem(String cid) {
        try {
-            return getMountService().getSecureContainerFilesystemPath(cid);
+            return getStorageManager().getSecureContainerFilesystemPath(cid);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get container path for " + cid +
                 " with exception " + e);
@@ -196,7 +196,7 @@
 
     public static boolean finalizeSdDir(String cid) {
         try {
-            int rc = getMountService().finalizeSecureContainer(cid);
+            int rc = getStorageManager().finalizeSecureContainer(cid);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to finalize container " + cid);
                 return false;
@@ -212,7 +212,7 @@
     public static boolean destroySdDir(String cid) {
         try {
             if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid);
-            int rc = getMountService().destroySecureContainer(cid, true);
+            int rc = getStorageManager().destroySecureContainer(cid, true);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to destroy container " + cid);
                 return false;
@@ -227,7 +227,7 @@
 
     public static String[] getSecureContainerList() {
         try {
-            return getMountService().getSecureContainerList();
+            return getStorageManager().getSecureContainerList();
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get secure container list with exception" +
                     e);
@@ -237,7 +237,7 @@
 
    public static boolean isContainerMounted(String cid) {
        try {
-           return getMountService().isSecureContainerMounted(cid);
+           return getStorageManager().isSecureContainerMounted(cid);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to find out if container " + cid + " mounted");
        }
@@ -325,7 +325,7 @@
 
     public static boolean fixSdPermissions(String cid, int gid, String filename) {
         try {
-            int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename);
+            int rc = getStorageManager().fixPermissionsSecureContainer(cid, gid, filename);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to fixperms container " + cid);
                 return false;
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 80c55fb..7591488 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -27,6 +27,8 @@
             SystemProperties.getInt("ro.debuggable", 0) == 1;
     public static final int FACTORYTEST =
             SystemProperties.getInt("ro.factorytest", 0);
+    public static final boolean CONTROL_PRIVAPP_PERMISSIONS =
+            SystemProperties.getBoolean("ro.control_privapp_permissions", false);
 
     // ------ ro.config.* -------- //
     public static final boolean CONFIG_LOW_RAM =
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index e57a224..304c31d 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.os;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
 import android.os.Build;
@@ -113,7 +113,7 @@
                 }
 
                 // Bring up crash dialog, wait for it to be dismissed
-                ActivityManagerNative.getDefault().handleApplicationCrash(
+                ActivityManager.getService().handleApplicationCrash(
                         mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
             } catch (Throwable t2) {
                 if (t2 instanceof DeadObjectException) {
@@ -379,7 +379,7 @@
      */
     public static void wtf(String tag, Throwable t, boolean system) {
         try {
-            if (ActivityManagerNative.getDefault().handleApplicationWtf(
+            if (ActivityManager.getService().handleApplicationWtf(
                     mApplicationObject, tag, system,
                     new ApplicationErrorReport.ParcelableCrashInfo(t))) {
                 // The Activity Manager has already written us off -- now exit.
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 11dd0e8..d968e3c 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -16,14 +16,17 @@
 
 package com.android.internal.os;
 
+import android.app.ApplicationLoaders;
 import android.net.LocalSocket;
 import android.os.Build;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
 import android.util.Log;
+import android.webkit.WebViewFactory;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 
 /**
  * Startup class for the WebView zygote process.
@@ -52,7 +55,27 @@
 
         @Override
         protected boolean handlePreloadPackage(String packagePath, String libsPath) {
-            // TODO: Use preload information to setup the ClassLoader.
+            // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
+            // our children will reuse the same classloader instead of creating their own.
+            // This enables us to preload Java and native code in the webview zygote process and
+            // have the preloaded versions actually be used post-fork.
+            ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
+                    packagePath, libsPath);
+
+            // Once we have the classloader, look up the WebViewFactoryProvider implementation and
+            // call preloadInZygote() on it to give it the opportunity to preload the native library
+            // and perform any other initialisation work that should be shared among the children.
+            try {
+                Class providerClass = Class.forName(WebViewFactory.CHROMIUM_WEBVIEW_FACTORY, true,
+                                                    loader);
+                Object result = providerClass.getMethod("preloadInZygote").invoke(null);
+                if (!((Boolean)result).booleanValue()) {
+                    Log.e(TAG, "preloadInZygote returned false");
+                }
+            } catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
+                     IllegalAccessException | InvocationTargetException e) {
+                Log.e(TAG, "Exception while preloading package", e);
+            }
             return false;
         }
     }
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/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 4748e6f..7ee5170 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -268,6 +268,45 @@
     }
 
     /**
+     * Finds a suitable color such that there's enough contrast.
+     *
+     * @param color the color to start searching from.
+     * @param other the color to ensure contrast against. Assumed to be darker than {@param color}
+     * @param findFg if true, we assume {@param color} is a foreground, otherwise a background.
+     * @param minRatio the minimum contrast ratio required.
+     * @return a color with the same hue as {@param color}, potentially darkened to meet the
+     *          contrast ratio.
+     */
+    public static int findContrastColorAgainstDark(int color, int other, boolean findFg,
+            double minRatio) {
+        int fg = findFg ? color : other;
+        int bg = findFg ? other : color;
+        if (ColorUtilsFromCompat.calculateContrast(fg, bg) >= minRatio) {
+            return color;
+        }
+
+        double[] lab = new double[3];
+        ColorUtilsFromCompat.colorToLAB(findFg ? fg : bg, lab);
+
+        double low = lab[0], high = 100;
+        final double a = lab[1], b = lab[2];
+        for (int i = 0; i < 15 && high - low > 0.00001; i++) {
+            final double l = (low + high) / 2;
+            if (findFg) {
+                fg = ColorUtilsFromCompat.LABToColor(l, a, b);
+            } else {
+                bg = ColorUtilsFromCompat.LABToColor(l, a, b);
+            }
+            if (ColorUtilsFromCompat.calculateContrast(fg, bg) > minRatio) {
+                high = l;
+            } else {
+                low = l;
+            }
+        }
+        return ColorUtilsFromCompat.LABToColor(high, a, b);
+    }
+
+    /**
      * Finds a text color with sufficient contrast over bg that has the same hue as the original
      * color, assuming it is for large text.
      */
diff --git a/core/java/com/android/internal/util/ToBooleanFunction.java b/core/java/com/android/internal/util/ToBooleanFunction.java
new file mode 100644
index 0000000..83866c2
--- /dev/null
+++ b/core/java/com/android/internal/util/ToBooleanFunction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.util;
+
+import java.util.function.Function;
+
+/**
+ * Represents a function that produces an boolean-valued result.  This is the
+ * {@code boolean}-producing primitive specialization for {@link Function}.
+ *
+ * <p>This is a <a href="package-summary.html">functional interface</a>
+ * whose functional method is {@link #apply(Object)}.
+ *
+ * @param <T> the type of the input to the function
+ *
+ * @see Function
+ * @since 1.8
+ */
+@FunctionalInterface
+public interface ToBooleanFunction<T> {
+
+    /**
+     * Applies this function to the given argument.
+     *
+     * @param value the function argument
+     * @return the function result
+     */
+    boolean apply(T value);
+}
diff --git a/core/java/com/android/internal/view/OneShotPreDrawListener.java b/core/java/com/android/internal/view/OneShotPreDrawListener.java
new file mode 100644
index 0000000..98ffd82
--- /dev/null
+++ b/core/java/com/android/internal/view/OneShotPreDrawListener.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.view;
+
+import android.view.View;
+import android.view.ViewTreeObserver;
+
+/**
+ * An OnPreDrawListener that will remove itself after one OnPreDraw call. Typical
+ * usage is:
+ * <pre><code>
+ *     OneShotPreDrawListener.add(view, () -> { view.doSomething(); })
+ * </code></pre>
+ * <p>
+ * The onPreDraw always returns true.
+ * <p>
+ * The listener will also remove itself from the ViewTreeObserver when the view
+ * is detached from the view hierarchy. In that case, the Runnable will never be
+ * executed.
+ */
+public class OneShotPreDrawListener implements ViewTreeObserver.OnPreDrawListener,
+        View.OnAttachStateChangeListener {
+    private final View mView;
+    private ViewTreeObserver mViewTreeObserver;
+    private final Runnable mRunnable;
+
+    private OneShotPreDrawListener(View view, Runnable runnable) {
+        mView = view;
+        mViewTreeObserver = view.getViewTreeObserver();
+        mRunnable = runnable;
+    }
+
+    /**
+     * Creates a OneShotPreDrawListener and adds it to view's ViewTreeObserver.
+     * @param view The view whose ViewTreeObserver the OnPreDrawListener should listen.
+     * @param runnable The Runnable to execute in the OnPreDraw (once)
+     * @return The added OneShotPreDrawListener. It can be removed prior to
+     * the onPreDraw by calling {@link #removeListener()}.
+     */
+    public static OneShotPreDrawListener add(View view, Runnable runnable) {
+        OneShotPreDrawListener listener = new OneShotPreDrawListener(view, runnable);
+        view.getViewTreeObserver().addOnPreDrawListener(listener);
+        view.addOnAttachStateChangeListener(listener);
+        return listener;
+    }
+
+    @Override
+    public boolean onPreDraw() {
+        removeListener();
+        mRunnable.run();
+        return true;
+    }
+
+    /**
+     * Removes the listener from the ViewTreeObserver. This is useful to call if the
+     * callback should be removed prior to {@link #onPreDraw()}.
+     */
+    public void removeListener() {
+        if (mViewTreeObserver.isAlive()) {
+            mViewTreeObserver.removeOnPreDrawListener(this);
+        } else {
+            mView.getViewTreeObserver().removeOnPreDrawListener(this);
+        }
+        mView.removeOnAttachStateChangeListener(this);
+    }
+
+    @Override
+    public void onViewAttachedToWindow(View v) {
+        mViewTreeObserver = v.getViewTreeObserver();
+    }
+
+    @Override
+    public void onViewDetachedFromWindow(View v) {
+        removeListener();
+    }
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 71252fb..b0bc81b 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -36,7 +36,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -682,10 +682,10 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
             Log.d(TAG, "Setting owner info");
-            mountService.setField(StorageManager.OWNER_INFO_KEY, ownerInfo);
+            storageManager.setField(StorageManager.OWNER_INFO_KEY, ownerInfo);
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing user info", e);
         }
@@ -746,9 +746,9 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... dummy) {
-                IMountService mountService = IMountService.Stub.asInterface(service);
+                IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
                 try {
-                    mountService.changeEncryptionPassword(type, password);
+                    storageManager.changeEncryptionPassword(type, password);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error changing encryption password", e);
                 }
@@ -1122,9 +1122,9 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
-            mountService.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0");
+            storageManager.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0");
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing pattern visible state", e);
         }
@@ -1145,9 +1145,9 @@
             return;
         }
 
-        IMountService mountService = IMountService.Stub.asInterface(service);
+        IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
         try {
-            mountService.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0");
+            storageManager.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0");
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing password visible state", e);
         }
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 429131b..168da5f 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -25,6 +25,7 @@
 import android.os.Environment;
 import android.os.Process;
 import android.os.storage.StorageManager;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -129,6 +130,9 @@
     final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
             new ArrayMap<>();
 
+
+    final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
+
     public static SystemConfig getInstance() {
         synchronized (SystemConfig.class) {
             if (sInstance == null) {
@@ -194,6 +198,10 @@
         return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
     }
 
+    public ArraySet<String> getPrivAppPermissions(String packageName) {
+        return mPrivAppPermissions.get(packageName);
+    }
+
     SystemConfig() {
         // Read configuration from system
         readPermissions(Environment.buildPath(
@@ -507,6 +515,8 @@
                         associatedPkgs.add(pkgname);
                     }
                     XmlUtils.skipCurrentTag(parser);
+                } else if ("privapp-permissions".equals(name) && allowAppConfigs) {
+                    readPrivAppPermissions(parser);
                 } else {
                     XmlUtils.skipCurrentTag(parser);
                     continue;
@@ -584,4 +594,32 @@
             XmlUtils.skipCurrentTag(parser);
         }
     }
+
+    void readPrivAppPermissions(XmlPullParser parser) throws IOException, XmlPullParserException {
+        String packageName = parser.getAttributeValue(null, "package");
+        if (TextUtils.isEmpty(packageName)) {
+            Slog.w(TAG, "package is required for <privapp-permissions> in "
+                    + parser.getPositionDescription());
+            return;
+        }
+
+        ArraySet<String> permissions = mPrivAppPermissions.get(packageName);
+        if (permissions == null) {
+            permissions = new ArraySet<>();
+        }
+        int depth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, depth)) {
+            String name = parser.getName();
+            if ("permission".equals(name)) {
+                String permName = parser.getAttributeValue(null, "name");
+                if (TextUtils.isEmpty(permName)) {
+                    Slog.w(TAG, "name is required for <permission> in "
+                            + parser.getPositionDescription());
+                    continue;
+                }
+                permissions.add(permName);
+            }
+        }
+        mPrivAppPermissions.put(packageName, permissions);
+    }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index f5429a1..a4e9576 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -277,7 +277,8 @@
     libradio_metadata \
     libnativeloader \
     libmemunreachable \
-    libhidl \
+    libhidlbase \
+    libhidltransport \
     libhwbinder \
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index e10fdbd..3456839 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -915,6 +915,16 @@
         paint->setLetterSpacing(letterSpacing);
     }
 
+    static jfloat getWordSpacing(jlong paintHandle) {
+        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        return paint->getWordSpacing();
+    }
+
+    static void setWordSpacing(jlong paintHandle, jfloat wordSpacing) {
+        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        paint->setWordSpacing(wordSpacing);
+    }
+
     static jint getHyphenEdit(jlong paintHandle, jint hyphen) {
         Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         return paint->getHyphenEdit();
@@ -1043,6 +1053,8 @@
     {"nSetTextSkewX","(JF)V", (void*) PaintGlue::setTextSkewX},
     {"nGetLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
     {"nSetLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
+    {"nGetWordSpacing","(J)F", (void*) PaintGlue::getWordSpacing},
+    {"nSetWordSpacing","(JF)V", (void*) PaintGlue::setWordSpacing},
     {"nGetHyphenEdit", "(J)I", (void*) PaintGlue::getHyphenEdit},
     {"nSetHyphenEdit", "(JI)V", (void*) PaintGlue::setHyphenEdit},
     {"nAscent","(JJ)F", (void*) PaintGlue::ascent},
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 0de46e6..7e417b4 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -93,7 +93,7 @@
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+        android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
     }
 
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 7fc79d2..c920b8d 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -70,7 +70,7 @@
 
 static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
     Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
-    return Typeface::setDefault(face);
+    Typeface::setDefault(face);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index fbccfd5..4391d93 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -16,26 +16,26 @@
 
 #include "context_hub.h"
 
+#undef LOG_NDEBUG
+#undef LOG_TAG
 #define LOG_NDEBUG 0
 #define LOG_TAG "ContextHubService"
 
 #include <inttypes.h>
 #include <jni.h>
-#include <mutex>
-#include <string.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-
-// TOOD: On master, alphabetize these and move <mutex> into this
-//     grouping.
-#include <chrono>
-#include <unordered_map>
-#include <queue>
+#include <string.h>
 
 #include <android-base/macros.h>
 #include <cutils/log.h>
 
+#include <chrono>
+#include <mutex>
+#include <queue>
+#include <unordered_map>
+
 #include "JNIHelp.h"
 #include "core_jni_helpers.h"
 
@@ -1180,7 +1180,6 @@
     }
 
     if (setAddressSuccess && hubId >= 0) {
-        ALOGD("Asking HAL to remove app");
         retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg);
     } else {
       ALOGD("Could not find app instance %" PRId32 " on hubHandle %" PRId32
diff --git a/core/jni/android_os_HwBlob.h b/core/jni/android_os_HwBlob.h
index 6bd82e9..0920488 100644
--- a/core/jni/android_os_HwBlob.h
+++ b/core/jni/android_os_HwBlob.h
@@ -20,6 +20,7 @@
 #include <android-base/macros.h>
 #include <jni.h>
 #include <hidl/HidlSupport.h>
+#include <hwbinder/Parcel.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index f909580..a10d807 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -26,6 +26,7 @@
 
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
 #include <nativehelper/ScopedLocalRef.h>
 
@@ -383,7 +384,7 @@
     hardware::Parcel *parcel =
         JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
-    status_t err = status.writeToParcel(parcel);
+    status_t err = ::android::hardware::writeToParcel(status, parcel);
     signalExceptionForError(env, err);
 }
 
@@ -394,7 +395,7 @@
         JHwParcel::GetNativeContext(env, thiz)->getParcel();
 
     Status status;
-    status_t err = status.readFromParcel(*parcel);
+    status_t err = ::android::hardware::readFromParcel(&status, *parcel);
     signalExceptionForError(env, err);
 }
 
@@ -425,8 +426,8 @@
     status_t err = parcel->writeBuffer(s, sizeof(*s), &parentHandle);
 
     if (err == OK) {
-        err = s->writeEmbeddedToParcel(
-                parcel, parentHandle, 0 /* parentOffset */);
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *s, parcel, parentHandle, 0 /* parentOffset */);
     }
 
     signalExceptionForError(env, err);
@@ -453,7 +454,8 @@
     if (err == OK) {                                                           \
         size_t childHandle;                                                    \
                                                                                \
-        err = vec->writeEmbeddedToParcel(                                      \
+        err = ::android::hardware::writeEmbeddedToParcel(                      \
+                *vec,                                                          \
                 parcel,                                                        \
                 parentHandle,                                                  \
                 0 /* parentOffset */,                                          \
@@ -508,7 +510,8 @@
     if (err == OK) {
         size_t childHandle;
 
-        err = vec->writeEmbeddedToParcel(
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *vec,
                 parcel,
                 parentHandle,
                 0 /* parentOffset */,
@@ -568,7 +571,8 @@
         return NULL;
     }
 
-    status_t err = const_cast<hidl_string *>(s)->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+            const_cast<hidl_string *>(s),
             *parcel, parentHandle, 0 /* parentOffset */);
 
     if (err != OK) {
@@ -597,8 +601,8 @@
                                                                                \
     size_t childHandle;                                                        \
                                                                                \
-    status_t err = const_cast<hidl_vec<Type> *>(vec)                           \
-        ->readEmbeddedFromParcel(                                              \
+    status_t err = ::android::hardware::readEmbeddedFromParcel(                \
+                const_cast<hidl_vec<Type> *>(vec),                             \
                 *parcel,                                                       \
                 parentHandle,                                                  \
                 0 /* parentOffset */,                                          \
@@ -639,8 +643,8 @@
 
     size_t childHandle;
 
-    status_t err = const_cast<hidl_vec<bool> *>(vec)
-        ->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+                const_cast<hidl_vec<bool> *>(vec),
                 *parcel,
                 parentHandle,
                 0 /* parentOffset */,
@@ -701,12 +705,13 @@
     }
 
     size_t childHandle;
-    status_t err = const_cast<string_vec *>(vec)->readEmbeddedFromParcel(
+    status_t err = ::android::hardware::readEmbeddedFromParcel(
+            const_cast<string_vec *>(vec),
             *parcel, parentHandle, 0 /* parentOffset */, &childHandle);
 
     for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
-        err = const_cast<hidl_vec<hidl_string> *>(vec)
-            ->readEmbeddedFromParcel(
+        err = android::hardware::readEmbeddedFromParcel(
+                    const_cast<hidl_vec<hidl_string> *>(vec),
                     *parcel,
                     childHandle,
                     i * sizeof(hidl_string),
@@ -760,14 +765,16 @@
 
     if (err == OK) {
         size_t childHandle;
-        err = vec->writeEmbeddedToParcel(
+        err = ::android::hardware::writeEmbeddedToParcel(
+                *vec,
                 parcel,
                 parentHandle,
                 0 /* parentOffset */,
                 &childHandle);
 
         for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
-            err = (*vec)[i].writeEmbeddedToParcel(
+            err = ::android::hardware::writeEmbeddedToParcel(
+                    (*vec)[i],
                     parcel,
                     childHandle,
                     i * sizeof(hidl_string));
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
index 1743731..b9376d8 100644
--- a/core/jni/android_view_GraphicBuffer.cpp
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -111,7 +111,7 @@
     }
 
     status_t error;
-    sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error));
+    sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, 1, usage, &error));
     if (buffer == NULL) {
         if (kDebugGraphicBuffer) {
             ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index f88de51..dd2a7a9 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -124,10 +124,6 @@
     renderNode->decStrong(0);
 }
 
-static void android_view_RenderNode_finalize(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
-    releaseRenderNode(reinterpret_cast<RenderNode*>(renderNodePtr));
-}
-
 static jlong android_view_RenderNode_getNativeFinalizer(JNIEnv* env,
         jobject clazz) {
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseRenderNode));
@@ -654,7 +650,6 @@
 // Regular JNI
 // ----------------------------------------------------------------------------
     { "nCreate",               "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
-    { "nFinalize",             "(J)V",   (void*) android_view_RenderNode_finalize },
     { "nGetNativeFinalizer",   "()J",    (void*) android_view_RenderNode_getNativeFinalizer },
     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
     { "nOutput",               "(J)V",    (void*) android_view_RenderNode_output },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0f7b5a5..fbad143 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -501,6 +501,10 @@
 
     <protected-broadcast android:name="android.intent.action.DEVICE_LOCKED_CHANGED" />
 
+    <!-- Added in O -->
+    <!-- TODO: temporary broadcast used by AutoFillManagerServiceImpl; will be removed -->
+    <protected-broadcast android:name="com.android.internal.autofill.action.REQUEST_AUTOFILL" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -717,6 +721,7 @@
         android:priority="400" />
 
     <!-- Allows an app to access precise location.
+         Alternatively, you might want {@link #ACCESS_COARSE_LOCATION}.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
@@ -726,6 +731,7 @@
         android:protectionLevel="dangerous|ephemeral" />
 
     <!-- Allows an app to access approximate location.
+         Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
          <p>Protection level: dangerous
     -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
diff --git a/core/res/res/drawable/watch_switch_track_material.xml b/core/res/res/color/watch_switch_track_color_material.xml
similarity index 73%
rename from core/res/res/drawable/watch_switch_track_material.xml
rename to core/res/res/color/watch_switch_track_color_material.xml
index 79e92a3..c7dc5d3 100644
--- a/core/res/res/drawable/watch_switch_track_material.xml
+++ b/core/res/res/color/watch_switch_track_color_material.xml
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2016 The Android Open Source Project
+
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
+
           http://www.apache.org/licenses/LICENSE-2.0
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -12,10 +15,8 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false">
-        <bitmap android:alpha="0.1" android:src="@drawable/watch_switch_track_mtrl_alpha" />
-    </item>
-    <item>
-        <bitmap android:alpha="0.2" android:src="@drawable/watch_switch_track_mtrl_alpha" />
-    </item>
-</selector>
+    <item android:state_enabled="false"
+          android:alpha="?attr/disabledAlpha"
+          android:color="?android:colorPrimary" />
+    <item android:color="?android:colorPrimary" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-hdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-hdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-hdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-xhdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-xhdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/watch_switch_track_mtrl_alpha.png b/core/res/res/drawable-xxhdpi/watch_switch_track_mtrl.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/watch_switch_track_mtrl_alpha.png
rename to core/res/res/drawable-xxhdpi/watch_switch_track_mtrl.png
Binary files differ
diff --git a/core/res/res/layout-watch/preference_widget_switch.xml b/core/res/res/layout-watch/preference_widget_switch.xml
index 5881cf0..a1a845a 100644
--- a/core/res/res/layout-watch/preference_widget_switch.xml
+++ b/core/res/res/layout-watch/preference_widget_switch.xml
@@ -24,7 +24,8 @@
     android:thumb="@drawable/watch_switch_thumb_material_anim"
     android:thumbTint="@color/watch_switch_thumb_color_material"
     android:thumbTintMode="multiply"
-    android:track="@drawable/watch_switch_track_material"
+    android:track="@drawable/watch_switch_track_mtrl"
+    android:trackTint="@color/watch_switch_track_color_material"
     android:focusable="false"
     android:clickable="false"
     android:background="@null" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 5ca9f43..e43f1ba 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Kennisgewing-volume"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Verstekluitoon"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Verstekluitoon (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Luitone"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Onbekende luitoon"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi netwerke beskikbaar</item>
       <item quantity="one">Wi-Fi-netwerk beskikbaar</item>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 18fc6dd..af8c592 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"የማህደረ መረጃ ክፍልፍል"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"የማሳወቂያ ክፍልፍል"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ነባሪ የስልክ ላይ ጥሪ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>) ነባሪ የስልክ ላይ ጥሪ"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ምንም"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ጥሪ ድምፆች"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"ያልታወቀ የስልክ ጥሪ ድምፅ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">የWi-Fi አውታረ መረቦች አሉ</item>
       <item quantity="other">የWi-Fi አውታረ መረቦች አሉ</item>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3451bcc..b3c24e5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1151,10 +1151,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"مستوى صوت الوسائط"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"مستوى صوت الإشعار"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"نغمة الرنين الافتراضية"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"نغمة الرنين الافتراضية (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"لا شيء"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"نغمات الرنين"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"نغمة رنين غير معروفة"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="zero">‏لا تتوفر أية شبكات Wi-Fi</item>
       <item quantity="two">‏تتوفر شبكتا Wi-Fi</item>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 1f0d164..7e9c508 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Media həcmi"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildiriş səsi"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Defolt rinqton"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Defolt rinqton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Heç biri"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Zəng səsləri"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Naməlum rinqton"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Əlçatan Wi-Fi şəbəkələri</item>
       <item quantity="one">Əlçatan Wi-Fi şəbəkəsi</item>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 2509eae..6caf561 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1082,10 +1082,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka medija"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka obaveštenja"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Podrazumevani zvuk zvona"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Podrazumevani zvuk zvona (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Zvukovi zvona"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznati zvuk zvona"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi mreže su dostupne</item>
       <item quantity="few">Wi-Fi mreže su dostupne</item>
diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml
index f5f1e62..c076db2 100644
--- a/core/res/res/values-be-rBY/strings.xml
+++ b/core/res/res/values-be-rBY/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Гучнасць прайгравальніка"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучнасць апавяшчэнняў"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Стандартны рынгтон"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандартны рынгтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Няма"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Рынгтоны"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Невядомы рынгтон"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">сетка Wi-Fi даступная</item>
       <item quantity="few">сеткі Wi-Fi даступныя</item>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f6eb810..2d6bdb2 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Сила на звука"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Сила на звука при известие"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Стандартна мелодия"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандартна мелодия (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Без"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Неизвестна мелодия"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Има достъпни Wi-Fi мрежи</item>
       <item quantity="one">Има достъпна Wi-Fi мрежа</item>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 993d49b..21b737a 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"মিডিয়ার ভলিউম"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"বিজ্ঞপ্তির ভলিউম"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ডিফল্ট রিংটোন"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ডিফল্ট রিংটোন (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"কোনো কিছুই নয়"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"রিংটোনগুলি"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"অজানা রিংটোন"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
       <item quantity="other">ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index 7cb46fe..80ee407 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -1084,10 +1084,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zadano zvono (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznato zvono"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi mreže su dostupne</item>
       <item quantity="few">Wi-Fi mreže su dostupne</item>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c63ec41..35b2918 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>
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volum de multimèdia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum de notificació"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"So predeterminat"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"So predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Cap"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Sons"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"So desconegut"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Xarxes Wi-Fi disponibles</item>
       <item quantity="one">Xarxa Wi-Fi disponible</item>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0e6ba82..95a6728 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitost médií"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitost oznámení"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Výchozí vyzváněcí tón"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Výchozí tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Žádný"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Neznámý vyzváněcí tón"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="few">K dispozici jsou sítě Wi-Fi</item>
       <item quantity="many">K dispozici jsou sítě Wi-Fi</item>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 628f9bb..a628e42 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medielydstyrke"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Lydstyrke for meddelelser"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standardringetone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standardringetone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringetoner"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Ukendt ringetone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Tilgængelige Wi-Fi-netværk</item>
       <item quantity="other">Tilgængelige Wi-Fi-netværk</item>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 9d8c98b..86f2070 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medienlautstärke"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Benachrichtigungslautstärke"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standard-Klingelton"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standard-Klingelton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ohne"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Klingeltöne"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Unbekannter Klingelton"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">WLAN-Netzwerke verfügbar</item>
       <item quantity="one">WLAN-Netzwerk verfügbar</item>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4283827..4ce3a1f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Ένταση ήχου πολυμέσων"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ένταση ήχου ειδοποιήσεων"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Προεπιλεγμένος ήχος κλήσης"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Προεπ. ήχος (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Κανένας"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ήχοι κλήσης"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Άγνωστος ήχος κλήσης"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Υπάρχουν διαθέσιμα δίκτυα Wi-Fi</item>
       <item quantity="one">Υπάρχει διαθέσιμο δίκτυο Wi-Fi</item>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 38f2b88..72c1271 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi networks available</item>
       <item quantity="one">Wi-Fi network available</item>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 38f2b88..72c1271 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi networks available</item>
       <item quantity="one">Wi-Fi network available</item>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 38f2b88..72c1271 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi networks available</item>
       <item quantity="one">Wi-Fi network available</item>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1277acc..738af8c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen de los medios"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificación"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Tono predeterminado"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tono predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos de llamada"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Tono de llamada desconocido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">redes de Wi-Fi disponibles</item>
       <item quantity="one">red de Wi-Fi disponible</item>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 77b43b1..3c2915d 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>
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen multimedia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificaciones"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Tono por defecto"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tono predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Tono desconocido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Redes Wi-Fi disponibles</item>
       <item quantity="one">Red Wi-Fi disponible</item>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index d7ee50c..96b060f 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Meediumi helitugevus"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Teatise helitugevus"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Vaikehelin"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Vaikehelin (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Puudub"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Helinad"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Tundmatu helin"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">WiFi-võrgud on saadaval</item>
       <item quantity="one">WiFi-võrk on saadaval</item>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index e7f3f02..6ccd864 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Euskarriaren bolumena"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jakinarazpenen bolumena"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Tonu lehenetsia"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tonu lehenetsia (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Bat ere ez"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonuak"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Tonu ezezaguna"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi sareak erabilgarri</item>
       <item quantity="one">Wi-Fi sarea erabilgarri</item>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 374183f..e8e61f4 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"میزان صدای رسانه"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"میزان صدای اعلان"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"آهنگ زنگ پیش‌فرض"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"آهنگ زنگ پیش‌فرض (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"هیچ‌کدام"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"آهنگ‌های زنگ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"آهنگ زنگ ناشناس"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">‏شبکه Wi-Fi در دسترس</item>
       <item quantity="other">‏شبکه‌ Wi-Fi در دسترس</item>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 9b6d57c..dbfd8ba 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Median äänenvoimakkuus"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ilmoituksen äänenvoimakkuus"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Oletussoittoääni"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Oletussoittoääni (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ei mitään"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Soittoäänet"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Tuntematon soittoääni"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi-verkkoja käytettävissä</item>
       <item quantity="one">Wi-Fi-verkko käytettävissä</item>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 034b291..501627d 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Réseau Wi-Fi à proximité</item>
       <item quantity="other">Réseaux Wi-Fi à proximité</item>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1e5f6a1..ccff4f3 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Réseau Wi-Fi disponible</item>
       <item quantity="other">Réseaux Wi-Fi disponibles</item>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 704667a..89a9471 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume dos elementos multimedia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume das notificacións"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Ton de chamada predeterminado"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ningún"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tons de chamada"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Ton de chamada descoñecido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Redes wifi dispoñibles</item>
       <item quantity="one">Rede wifi dispoñible</item>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index cd3e7be..cbb0d9e4a4 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"મીડિયા વોલ્યુમ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"સૂચના વૉલ્યૂમ"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ડિફોલ્ટ રિંગટોન"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ડિફોલ્ટ રિંગટોન (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"કોઈ નહીં"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"રિંગટોન્સ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"અજાણ રિંગટોન"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
       <item quantity="other">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c8b3256..e833052 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -347,14 +347,14 @@
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर संवेदक एक्सेस करें (जैसे हृदय गति मॉनीटर)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्‍थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्‍सेस करने देती है."</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर ईवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर इवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ऐप्स  को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके टेबलेट पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे निजता या संवेदनशीलता पर ध्यान दिए बिना, ऐप्स  आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ऐप को, मित्रों और सहकर्मियों के कैलेंडर ईवेंट सहित, आपके टीवी पर संग्रहीत सभी कैलेंडर ईवेंट पढ़ने देती है. इससे ऐप को निजता या संवेदनशीलता पर ध्‍यान दिए बिना, आपका कैलेडर डेटा साझा करने या सहेजने की अनुमति मिल जाती है."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ऐप को, मित्रों और सहकर्मियों के कैलेंडर इवेंट सहित, आपके टीवी पर संग्रहीत सभी कैलेंडर इवेंट पढ़ने देती है. इससे ऐप को निजता या संवेदनशीलता पर ध्‍यान दिए बिना, आपका कैलेडर डेटा साझा करने या सहेजने की अनुमति मिल जाती है."</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ऐप्स  को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके फ़ोन पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे निजता या संवेदनशीलता पर ध्यान दिए बिना, ऐप्स  आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बि‍ना कैलेंडर ईवेंट जोड़ें या संशोधि‍त करें और अति‍थि‍यों को ईमेल भेजें"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ऐप्स  को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे ऐप्स ,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ऐप को ऐसे ईवेंट जोड़ने, निकालने, बदलने देती है जिन्हें आप अपने डिवाइस पर बदल सकते हैं, जिनमें मित्रों या सहकर्मियों के ईवेंट शामिल हैं. इससे ऐप ऐसे संदेश भेज सकता है जो कैलेंडर स्वामी से आते हुए प्रतीत होते हैं या ऐप स्वामी की जानकारी के बिना ईवेंट बदल सकता है."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ऐप्स  को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे ऐप्स , अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बि‍ना कैलेंडर इवेंट जोड़ें या संशोधि‍त करें और अति‍थि‍यों को ईमेल भेजें"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ऐप्स  को मित्रों या सहकर्मियों के इवेंट के साथ ही वे इवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे ऐप्स ,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या इवेंट संशोधित कर सकता है."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ऐप को ऐसे इवेंट जोड़ने, निकालने, बदलने देती है जिन्हें आप अपने डिवाइस पर बदल सकते हैं, जिनमें मित्रों या सहकर्मियों के इवेंट शामिल हैं. इससे ऐप ऐसे संदेश भेज सकता है जो कैलेंडर स्वामी से आते हुए प्रतीत होते हैं या ऐप स्वामी की जानकारी के बिना इवेंट बदल सकता है."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ऐप्स  को मित्रों या सहकर्मियों के इवेंट के साथ ही वे इवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे ऐप्स , अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या इवेंट संशोधित कर सकता है."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्‍थान प्रदाता आदेशों में पहुंचे"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप्स को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देती है. इससे ऐप्स GPS या अन्य स्थान स्रोतों के संचालन में अवरोध पहुंचा सकता है."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"सटीक स्थान एक्सेस करें (GPS और नेटवर्क-आधारित)"</string>
@@ -459,7 +459,7 @@
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्‍वयन बंद या चालू टॉगल करें"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ऐप्स  को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग ऐप्स  का समन्‍वयन किसी खाते से सक्षम करने में हो सकता है."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स  को किसी खाते के समन्वयन आंकड़े, साथ ही समन्‍वयित ईवेंट का इतिहास और समन्‍वयित डेटा की मात्रा पढ़ने देता है."</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स  को किसी खाते के समन्वयन आंकड़े, साथ ही समन्‍वयित इवेंट का इतिहास और समन्‍वयित डेटा की मात्रा पढ़ने देता है."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"अपने USB मेमोरी की सामग्री पढ़ें"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"अपने SD कार्ड की सामग्री पढ़ें"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"एप्‍लिकेशन को आपके USB मेमोरी की सामग्री पढ़ने की अनुमति देता है."</string>
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्‍यूम"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफिकेशन वॉल्‍यूम"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्‍ट रिंगटोन"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"डिफ़ॉल्‍ट रिंगटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"कोई नहीं"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिंगटोन"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
       <item quantity="other">वाई-फ़ाई नेटवर्क उपलब्‍ध</item>
@@ -1614,7 +1620,7 @@
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"बंद रहने का समय"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"सप्ताह की रात"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string>
-    <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ईवेंट"</string>
+    <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इवेंट"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा म्यूट किया गया"</string>
     <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई और यह तब तक अस्‍थिर रह सकता है, जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते हैं."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3fc3346..e811b94 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1082,10 +1082,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Glasnoća medija"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Glasnoća obavijesti"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zadana melodija zvona (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ništa"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznata melodija zvona"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Dostupne su Wi-Fi mreže</item>
       <item quantity="few">Dostupne su Wi-Fi mreže</item>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 825672b..b0ce160 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Média hangereje"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Értesítés hangereje"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Alapértelmezett csengőhang"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Alap csengőhang (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Egyik sem"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Csengőhangok"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Ismeretlen csengőhang"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi hálózatok érhetők el</item>
       <item quantity="one">Van elérhető Wi-Fi hálózat</item>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index af7aaaf..2ba22af 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Մեդիա ձայնի բարձրություն"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ծանուցումների ձայնի ուժգնությունը"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Կանխադրված զանգերանգ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Կանխադրված զանգերանգ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ոչ մեկը"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Զանգերանգներ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Անհայտ զանգերանգ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Հասանելի են Wi-Fi ցանցեր</item>
       <item quantity="other">Հասանելի են Wi-Fi ցանցեր</item>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 05fe8d0..09223cd 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume media"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume pemberitahuan"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Nada dering default"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nada dering default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Tidak Ada"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nada dering tidak dikenal"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Jaringan Wi-Fi tersedia</item>
       <item quantity="one">Jaringan Wi-Fi tersedia</item>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index cd41f51..105a647 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Hljóðstyrkur efnisspilunar"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hljóðstyrkur tilkynninga"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Sjálfgefinn hringitónn"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sjálfg. hringitónn (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ekkert"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Hringitónar"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Óþekktur hringitónn"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi net í boði</item>
       <item quantity="other">Wi-Fi net í boði</item>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ec7f8f9..564472e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume contenuti multimediali"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume notifiche"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Suoneria predefinita"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Suoneria predefinita (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nessuna"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Suonerie"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Suoneria sconosciuta"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Reti Wi-Fi disponibili</item>
       <item quantity="one">Rete Wi-Fi disponibile</item>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 290a31f..d4b9bf1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"עוצמת קול של מדיה"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת קול של התראות"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"רינגטון ברירת מחדל"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון ברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ללא"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"רינגטונים"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"רינגטון לא ידוע"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="two">‏יש רשתות Wi-Fi זמינות</item>
       <item quantity="many">‏יש רשתות Wi-Fi זמינות</item>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 02736ec..e2432f1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"メディアの音量"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"プリセット着信音"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"端末の基本着信音(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"なし"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"着信音"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"不明な着信音"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">複数のWi-Fiネットワークが利用できます</item>
       <item quantity="one">Wi-Fiネットワークが利用できます</item>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 1e34347..5e069b6 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"მედიის ხმა"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"შეტყობინების ხმა"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ნაგულისხმევი ზარი"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ნაგულის.ზარი (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"არც ერთი"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ზარები"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"უცნობი ზარი"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">ხელმისაწვდომია Wi-Fi ქსელები</item>
       <item quantity="one">ხელმისაწვდომია Wi-Fi ქსელი</item>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 9a227c4..729f726 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Meдиа дыбысының қаттылығы"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Хабар дыбысының қаттылығы"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Әдепкі рингтон"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Әдепкі рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ешқандай"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Қоңырау әуендері"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Белгісіз қоңырау әуені"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi желілері қол жетімді</item>
       <item quantity="one">Wi-Fi желісі қол жетімді</item>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 2491f82..c3e939e 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1061,10 +1061,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"កម្រិត​សំឡេង​មេឌៀ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"កម្រិត​សំឡេង​ការ​ជូន​ដំណឹង"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"សំឡេង​រោទ៍​លំនាំដើម"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"សំឡេង​រោទ៍​លំនាំដើម (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"គ្មាន"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"សំឡេង​រោទ៍"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"សំឡេង​រោទ៍​មិន​ស្គាល់"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">មានបណ្តាញ Wi-Fi</item>
       <item quantity="one">មានបណ្តាញ Wi-Fi</item>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 732a321..7f80a29 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ಅಧಿಸೂಚನೆಯ ವಾಲ್ಯೂಮ್"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ಡಿಫಾಲ್ಟ್ ರಿಂಗ್‌ಟೋನ್"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ಡಿಫಾಲ್ಟ್ ರಿಂಗ್‌ಟೋನ್ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ಯಾವುದೂ ಇಲ್ಲ"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ರಿಂಗ್‌ಟೋನ್‌ಗಳು"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"ಅಪರಿಚಿತ ರಿಂಗ್‌ಟೋನ್"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
       <item quantity="other">ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ಲಭ್ಯವಿವೆ</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 6e1012a..444c83d 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"미디어 볼륨"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"알림 볼륨"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"기본 벨소리"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"기본 벨소리(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"없음"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"벨소리"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"알 수 없는 벨소리"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi 네트워크 사용 가능</item>
       <item quantity="one">Wi-Fi 네트워크 사용 가능</item>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 7a48ae5..2b592bd 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа үнүнүн деңгээли"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Эскертме үнүнүн деңгээли"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Демейки рингтон"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Демейки рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Эч бир"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ринтондор"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Белгисиз рингтон"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi тармагы жеткиликтүү</item>
       <item quantity="one">Wi-Fi тармагы жеткиликтүү</item>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 26c9053..3a96743 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ລະດັບສຽງຂອງສື່"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ລະດັບສຽງການແຈ້ງເຕືອນ"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ຣິງໂທນເລີ່ມຕົ້ນ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ຣິງໂທນເລີ່ມຕົ້ນ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ບໍ່ມີ"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ຣິງໂທນ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"ຣິງໂທນທີ່ບໍ່ຮູ້ຈັກ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">ເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item>
       <item quantity="one">ເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index c7806f2..d60a010 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medijos garsumas"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Pranešimo apimtis"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Numatytasis skambėjimo tonas"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Numatytasis skambėjimo tonas („<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>“)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nėra"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Skambėjimo tonai"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nežinomas skambėjimo tonas"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Pasiekiami „Wi-Fi“ tinklai</item>
       <item quantity="few">Pasiekiami „Wi-Fi“ tinklai</item>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 6ea7d6b..7afb2ce 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1082,10 +1082,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Multivides skaļums"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Paziņojumu skaļums"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Noklusējuma zvana signāls"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Noklusējuma zvana signāls (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nav"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Zvana signāli"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nezināms zvana signāls"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="zero">Pieejami Wi-Fi tīkli</item>
       <item quantity="one">Pieejami Wi-Fi tīkli</item>
diff --git a/core/res/res/values-mcc204-mnc04/config.xml b/core/res/res/values-mcc204-mnc04/config.xml
index 1d7a45b..c66ed12 100755
--- a/core/res/res/values-mcc204-mnc04/config.xml
+++ b/core/res/res/values-mcc204-mnc04/config.xml
@@ -25,12 +25,15 @@
     -->
     <integer name="config_mobile_mtu">1358</integer>
 
-    <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
-          when evaluating RSRP for LTE antenna bar display
-           0. Strict threshold
-           1. Lenient threshold
-    -->
-    <integer name="config_LTE_RSRP_threshold_type">0</integer>
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-105</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-95</item>     <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-85</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
 
     <string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">true;BAE0000000000000</string>
 </resources>
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index a0a361b..a210f5b 100755
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -50,12 +50,15 @@
 
     <bool name="config_auto_attach_data_on_creation">false</bool>
 
-    <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
-          when evaluating RSRP for LTE antenna bar display
-           0. Strict threshold
-           1. Lenient threshold
-    -->
-    <integer name="config_LTE_RSRP_threshold_type">0</integer>
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-105</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-95</item>     <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-85</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
 
     <string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">true</string>
 
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 3f228203..139e02a 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина на звук на медиуми"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина на звук на известување"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Стандардна мелодија"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандардна мелодија (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ниедна"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Непозната мелодија"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi мрежи се достапни</item>
       <item quantity="other">Wi-Fi мрежи се достапни</item>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index beb6a67..fc3eb40 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"മീഡിയ വോളിയം"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"അറിയിപ്പ് വോളിയം"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ഡിഫോൾട്ട് റിംഗ്‌ടോൺ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ഡിഫോൾട്ട് റിംഗ്‌ടോൺ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ഒന്നും വേണ്ട"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"റിംഗ്ടോണുകൾ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"അജ്ഞാത റിംഗ്‌ടോൺ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">വൈഫൈ നെറ്റ്‌വർക്കുകൾ ലഭ്യമാണ്</item>
       <item quantity="one">വൈഫൈ നെറ്റ്‌വർക്ക് ലഭ്യമാണ്</item>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index bd80f84..2faf1634 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа дууны хэмжээ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Мэдэгдлийн дууны хэмжээ"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Үндсэн хонхны ая"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Үндсэн хонхны ая (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Алийг нь ч биш"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Хонхны ая"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Үл мэдэгдэх хонхны ая"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi сүлжээ ашиглах боломжтой</item>
       <item quantity="one">Wi-Fi сүлжээ ашиглах боломжтой</item>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 758b21b..99465cc 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया व्हॉल्यूम"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना व्हॉल्यूम"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"डीफॉल्ट रिंगटोन"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"डीफॉल्ट रिंगटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"काहीही नाही"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिंगटोन"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">वाय-फाय नेटवर्क उपलब्ध</item>
       <item quantity="other">वाय-फाय नेटवर्क उपलब्ध</item>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 60330e5..1e7e281 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Kelantangan media"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Kelantangan pemberitahuan"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Nada dering lalai"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nada dering lalai (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Tiada"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nada dering tidak diketahui"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Rangkaian Wi-Fi tersedia</item>
       <item quantity="one">Rangkaian Wi-Fi tersedia</item>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index c18ff7f..99d6423 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"မီဒီယာအသံအတိုးအကျယ်"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"မူရင်းမြည်သံ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"မူရင်းမြည်သံ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"တစ်ခုမှမဟုတ်"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"မြည်သံများ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"မသိသောမြည်သံ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်</item>
       <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်</item>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0371543..324f0d7 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medievolum"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Varslingsvolum"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standard ringetone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standard ringetone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringelyder"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Ukjent ringetone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi-nettverk er tilgjengelig</item>
       <item quantity="one">Wi-Fi-nettverk er tilgjengelig</item>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index e039927..caf3688 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1065,10 +1065,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"मिडियाको मात्रा"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना भोल्युम"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"पूर्वनिर्धारित रिङटोन"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"पूर्वनिर्धारित रिङटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"कुनै पनि होइन"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"रिङटोनहरू"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिङटोन"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi सञ्जालहरू उपलब्ध छन्</item>
       <item quantity="one">Wi-Fi सञ्जाल उपलब्ध छ</item>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9c26340..0848304 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -204,9 +204,9 @@
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Je tv wordt uitgeschakeld.."</string>
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Je horloge wordt uitgeschakeld."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Je telefoon wordt uitgeschakeld."</string>
-    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Wilt u afsluiten?"</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Wil je afsluiten?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Opnieuw opstarten in veilige modus"</string>
-    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Wilt u opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Wil je opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
     <string name="no_recent_tasks" msgid="8794906658732193473">"Geen recente apps."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Tabletopties"</string>
@@ -356,9 +356,9 @@
     <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op je tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van GPS of andere locatiebronnen te verstoren."</string>
-    <string name="permlab_accessFineLocation" msgid="251034415460950944">"toegang tot precieze locatie (GPS- en netwerkgebaseerd)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van gps of andere locatiebronnen te verstoren."</string>
+    <string name="permlab_accessFineLocation" msgid="251034415460950944">"toegang tot precieze locatie (gps- en netwerkgebaseerd)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via gps (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"toegang tot geschatte locatie (netwerkgebaseerd)"</string>
     <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over je geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"je audio-instellingen wijzigen"</string>
@@ -804,7 +804,7 @@
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van je voicemail."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"geolocatiemachtigingen voor browser aanpassen"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Hiermee kan de app de geolocatiemachtigingen van de browser aanpassen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string>
-    <string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
+    <string name="save_password_message" msgid="767344687139195790">"Wil je dat de browser dit wachtwoord onthoudt?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Nooit"</string>
@@ -1010,7 +1010,7 @@
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Melden"</string>
     <string name="wait" msgid="7147118217226317732">"Wachten"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer.\n\nWilt u de pagina sluiten?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer.\n\nWil je de pagina sluiten?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App verplaatst"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Meldingsvolume"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standaardbeltoon"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standaardbeltoon (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Beltonen"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Onbekende beltoon"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wifi-netwerken beschikbaar</item>
       <item quantity="one">Wifi-netwerk beschikbaar</item>
@@ -1111,7 +1117,7 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"De verbinding met het wifi-netwerk wordt tijdelijk uitgeschakeld terwijl de telefoon verbonden is met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="select_character" msgid="3365550120617701745">"Teken invoegen"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS-berichten verzenden"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; verzendt moment een groot aantal sms-berichten. Wilt u toestaan ​​dat deze app berichten blijft verzenden?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; verzendt moment een groot aantal sms-berichten. Wil je toestaan ​​dat deze app berichten blijft verzenden?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string>
     <string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wil graag een bericht verzenden naar &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
@@ -1220,7 +1226,7 @@
     <string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Contact maken\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot je account, nu en in de toekomst."</string>
-    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wilt u dit verzoek toestaan?"</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wil je dit verzoek toestaan?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Verzoek om toegang"</string>
     <string name="allow" msgid="7225948811296386551">"Toestaan"</string>
     <string name="deny" msgid="2081879885755434506">"Weigeren"</string>
@@ -1277,7 +1283,7 @@
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nee"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"Verwijderingslimiet overschreden"</string>
-    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Wat wilt u doen?"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Wat wil je doen?"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"De items verwijderen."</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"Verwijderingen ongedaan maken"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"Nu niets doen."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index d3476aa..3e886bc 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ਕੋਈ ਨਹੀਂ"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ਰਿੰਗਟੋਨਾਂ"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"ਅਗਿਆਤ ਰਿੰਗਟੋਨ"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item>
       <item quantity="other">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index a7571ef..92a2e2a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Głośność multimediów"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Głośność powiadomień"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Dzwonek domyślny"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Dzwonek domyślny (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Brak"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Dzwonki"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nieznany dzwonek"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="few">Dostępne są sieci Wi-Fi</item>
       <item quantity="many">Dostępne są sieci Wi-Fi</item>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 24265ee..bf9e15d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Redes Wi-Fi disponíveis</item>
       <item quantity="other">Redes Wi-Fi disponíveis</item>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 6270210..e09daa5 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume de multimédia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume de notificações"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Toque predefinido"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque predefinido (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nada"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Redes Wi-Fi disponíveis</item>
       <item quantity="one">Rede Wi-Fi disponível</item>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 24265ee..bf9e15d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Redes Wi-Fi disponíveis</item>
       <item quantity="other">Redes Wi-Fi disponíveis</item>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 29c0a59..7f96d2e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1082,10 +1082,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumul media"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum notificare"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Ton de apel prestabilit"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de apel prestabilit (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Niciunul"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonuri de sonerie"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Ton de apel necunoscut"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="few">Rețele Wi-Fi disponibile</item>
       <item quantity="other">Rețele Wi-Fi disponibile</item>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ed6c798..9e25bb7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Громкость мультимедиа"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Громкость уведомлений"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Мелодия по умолчанию"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"По умолчанию (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Неизвестная мелодия"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Есть доступные сети Wi-Fi</item>
       <item quantity="few">Есть доступные сети Wi-Fi</item>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 91d5bbe..b106464 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1061,10 +1061,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"මාධ්‍ය ශබ්දය"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"දැනුම්දීමේ ශබ්ද ත්‍රීවතාව"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"සුපුරුදු රින්ටෝනය සකසන්න"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"සුපුරුදු රින්ටෝනය (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"කිසිවක් නැත"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"රිගින්ටෝන"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"නොදන්නා රින්ටෝනය"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi ජාල තිබේ</item>
       <item quantity="other">Wi-Fi ජාල තිබේ</item>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 5c129af..50af3cc 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitosť médií"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitosť upozornení"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Predvolený tón zvonenia"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Predvolený tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Žiadny"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Tóny zvonenia"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Neznámy tón zvonenia"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="few">K dispozícii sú siete Wi-Fi</item>
       <item quantity="many">K dispozícii sú siete Wi-Fi</item>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 76f1e66..5bc756b 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Glasnost predstavnosti"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Glasnost obvestila"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Privzeta melodija zvonjenja"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Privzeta melodija zvonjenja (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Brez"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvonjenja"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Neznana melodija zvonjenja"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Na voljo so omrežja Wi-Fi</item>
       <item quantity="two">Na voljo so omrežja Wi-Fi</item>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 0fb3ebe..1095088 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"volumi i klipit \"media\""</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumi i njoftimeve"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Zile e paracaktuar."</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zilja e paracaktuar (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Asnjë"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Zilet"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Zile e panjohur"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Rrjete Wi-Fi ofrohen për përdorim</item>
       <item quantity="one">Një rrjet Wi-Fi ofrohet për përdorim</item>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index fdf8a6d..27d7cad 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1082,10 +1082,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина звука медија"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина звука обавештења"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Подразумевани звук звона"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Подразумевани звук звона (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Звукови звона"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Непознати звук звона"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Wi-Fi мреже су доступне</item>
       <item quantity="few">Wi-Fi мреже су доступне</item>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 340010f..b048762 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolym"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Meddelandevolym"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standardringsignal"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standardringsignal (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringsignaler"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Okänd ringsignal"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi-nätverk är tillgängliga</item>
       <item quantity="one">Wi-Fi-nätverk är tillgängligt</item>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 4832546..6cfd253 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1057,10 +1057,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Sauti ya midia"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Sauti ya arifa"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Mlio chaguo-msingi"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Mlio chaguo-msingi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Hamna"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Toni za mlio"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Mlio amabo haujulikani"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Mitandao ya Wi-Fi inapatikana</item>
       <item quantity="one">Mtandao wa Wi-Fi unapatikana</item>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index f6bb25c..b391912 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"மீடியாவின் ஒலியளவு"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"அறிவிப்பின் ஒலியளவு"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"இயல்புநிலை ரிங்டோன்"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"இயல்புநிலை ரிங்டோன் (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ஏதுமில்லை"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"ரிங்டோன்கள்"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"அறியப்படாத ரிங்டோன்"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">வைஃபை நெட்வொர்க்குகள் உள்ளன</item>
       <item quantity="one">வைஃபை நெட்வொர்க் உள்ளது</item>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 24bfebd..5ec586f 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"మీడియా వాల్యూమ్"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"నోటిఫికేషన్ వాల్యూమ్"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"డిఫాల్ట్ రింగ్‌టోన్"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"డిఫాల్ట్ రింగ్‌టోన్ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ఏదీ వద్దు"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"రింగ్‌టోన్‌లు"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"తెలియని రింగ్‌టోన్"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi నెట్‌వర్క్‌లు అందుబాటులో ఉన్నాయి</item>
       <item quantity="one">Wi-Fi నెట్‌వర్క్ అందుబాటులో ఉంది</item>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 818bb9f..15cbd94 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"ระดับเสียงของสื่อ"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"ระดับเสียงของการแจ้งเตือน"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"เสียงเรียกเข้าเริ่มต้น"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"เสียงเรียกเข้าเริ่มต้น (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"ไม่มี"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"เสียงเรียกเข้า"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"ไม่ทราบเสียงเรียกเข้า"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">มีหลายเครือข่าย Wi-Fi ที่ใช้งานได้</item>
       <item quantity="one">มี 1 เครือข่าย Wi-Fi ที่ใช้งานได้</item>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 81c5fd0..31666ee 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume ng media"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume ng notification"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Default na ringtone"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default na ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Wala"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Mga Ringtone"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Hindi kilalang ringtone"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Available ang mga Wi-Fi network</item>
       <item quantity="other">Available ang mga Wi-Fi network</item>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 12a5b7c..0126068 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Medya ses düzeyi"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildirim ses düzeyi"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Varsayılan zil sesi"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Varsayılan zil sesi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Yok"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Zil sesleri"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Bilinmeyen zil sesi"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Kablosuz ağlar var</item>
       <item quantity="one">Kablosuz ağ var</item>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index fb0fda8..104badd 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1105,10 +1105,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Гучність медіа"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучність сповіщення"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Мелодія за умовчанням"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Мелодія за умовчанням (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Немає"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодії"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Невідома мелодія"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Мережі Wi-Fi доступні</item>
       <item quantity="few">Мережі Wi-Fi доступні</item>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index d6eae64a..f8224f2 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"میڈیا والیوم"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"اطلاع کا والیوم"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"ڈیفالٹ رنگ ٹون"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ڈیفالٹ رنگ ٹون (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"کوئی نہیں"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"رنگ ٹونز"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"نامعلوم رنگ ٹون"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">‏Wi-Fi نیٹ ورکس دستیاب ہیں</item>
       <item quantity="one">‏Wi-Fi نیٹ ورک دستیاب ہے</item>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 5b7cf74..78b5400 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Multimedia ovozi"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Eslatma tovushi"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Standart rington"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standart rington (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Yo‘q"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtonlar"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Noma’lum rington"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Wi-Fi tarmoqlari aniqlandi</item>
       <item quantity="one">Wi-Fi tarmog‘i aniqlandi</item>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 42e0b0a..ca5e3bc 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Âm lượng phương tiện"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Âm lượng thông báo"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Nhạc chuông mặc định"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nhạc chuông mặc định (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Không"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Nhạc chuông"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Nhạc chuông không xác định"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">Các mạng Wi-Fi khả dụng</item>
       <item quantity="one">Mạng Wi-Fi khả dụng</item>
diff --git a/core/res/res/values-watch/colors_material.xml b/core/res/res/values-watch/colors_material.xml
index 1456976..72f589b 100644
--- a/core/res/res/values-watch/colors_material.xml
+++ b/core/res/res/values-watch/colors_material.xml
@@ -22,7 +22,7 @@
     <color name="accent_material_dark">#5E97F6</color>
     <color name="accent_material_50">#93B7F5</color>
 
-    <color name="primary_material_dark">#4D4D4D</color>
+    <color name="primary_material_dark">#33ffffff</color>
 
     <color name="button_material_dark">#ff919699</color>
 </resources>
diff --git a/core/res/res/values-watch/config_material.xml b/core/res/res/values-watch/config_material.xml
index 529f18b..03d3637 100644
--- a/core/res/res/values-watch/config_material.xml
+++ b/core/res/res/values-watch/config_material.xml
@@ -30,6 +30,9 @@
     <!-- Always overscan by default to ensure onApplyWindowInsets will always be called. -->
     <bool name="config_windowOverscanByDefault">true</bool>
 
+    <!-- Enable windowSwipeToDismiss. -->
+    <bool name="config_windowSwipeToDismiss">true</bool>
+
     <!-- Style the scrollbars accoridngly. -->
     <drawable name="config_scrollbarThumbVertical">@drawable/scrollbar_vertical_thumb</drawable>
     <drawable name="config_scrollbarTrackVertical">@drawable/scrollbar_vertical_track</drawable>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index aa1594d..fbe780d 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -314,7 +314,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
-        <item name="colorBackground">?attr/colorBackgroundFloating</item>
+        <item name="colorBackground">@color/background_device_default_dark</item>
         <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
         <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item>
         <item name="colorButtonNormal">@color/button_normal_device_default_dark</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 68e87c2..2126d12 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"媒体音量"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"默认铃声"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"默认铃声(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"无"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"铃声"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"未知铃声"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">有可用的 WLAN 网络</item>
       <item quantity="one">有可用的 WLAN 网络</item>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 62bb44a..bdd9fe3 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"媒體音量"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"預設鈴聲"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"預設鈴聲 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"無"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"鈴聲"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"不明鈴聲"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">有可用的 Wi-Fi 網絡</item>
       <item quantity="one">有可用的 Wi-Fi 網絡</item>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 0500c07..3c2146b 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"媒體音量"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"預設鈴聲"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"預設鈴聲 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"無"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"鈴聲"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"未知的鈴聲"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="other">有多個可用的 Wi-Fi 網路</item>
       <item quantity="one">有一個可用的 Wi-Fi 網路</item>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 849f292..011e4f7 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1059,10 +1059,16 @@
     <string name="volume_icon_description_media" msgid="4217311719665194215">"Ivolumu yemidiya"</string>
     <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ivolumu yesaziso"</string>
     <string name="ringtone_default" msgid="3789758980357696936">"Iringithoni emisiwe"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Iringithoni ezenzakalelayo <xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>"</string>
+    <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
+    <skip />
     <string name="ringtone_silent" msgid="7937634392408977062">"Akunalutho"</string>
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Amaringithoni"</string>
-    <string name="ringtone_unknown" msgid="5477919988701784788">"Iringithoni engaziwa"</string>
+    <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
+    <skip />
+    <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
+    <skip />
+    <!-- no translation found for ringtone_unknown (3914515995813061520) -->
+    <skip />
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
       <item quantity="one">Amanethiwekhi we-Wi-Fi ayatholakala</item>
       <item quantity="other">Amanethiwekhi we-Wi-Fi ayatholakala</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 996fd55..d4119d0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2326,12 +2326,15 @@
 
     <bool name="config_sms_force_7bit_encoding">false</bool>
 
-    <!-- Flag indicating whether strict threshold is used, or lenient threshold is used,
-          when evaluating RSRP for LTE antenna bar display
-           0. Strict threshold
-           1. Lenient threshold
-    -->
-    <integer name="config_LTE_RSRP_threshold_type">1</integer>
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-128</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-118</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-108</item>    <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-98</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
 
     <!-- Enabled built-in zen mode condition providers -->
     <string-array translatable="false" name="config_system_condition_providers">
diff --git a/core/res/res/values/config_material.xml b/core/res/res/values/config_material.xml
index 840a551..8737df8 100644
--- a/core/res/res/values/config_material.xml
+++ b/core/res/res/values/config_material.xml
@@ -32,6 +32,9 @@
     <!-- True if windowOverscan should be on by default. -->
     <bool name="config_windowOverscanByDefault">false</bool>
 
+    <!-- True if windowSwipeToDismiss should be on by default. -->
+    <bool name="config_windowSwipeToDismiss">false</bool>
+
     <!-- True if preference fragment should clip to padding. -->
     <bool name="config_preferenceFragmentClipToPadding">true</bool>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index cce02f2..d42ec90 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2906,13 +2906,17 @@
     <!-- Choice in the ringtone picker.  If chosen, the default ringtone will be used. -->
     <string name="ringtone_default">Default ringtone</string>
     <!-- Choice in the ringtone picker.  If chosen, the default ringtone will be used. This fills in the actual ringtone's title into the message. -->
-    <string name="ringtone_default_with_actual">Default ringtone (<xliff:g id="actual_ringtone">%1$s</xliff:g>)</string>
+    <string name="ringtone_default_with_actual">Default (<xliff:g id="actual_ringtone">%1$s</xliff:g>)</string>
     <!-- Choice in the ringtone picker.  If chosen, there will be silence instead of a ringtone played. -->
     <string name="ringtone_silent">None</string>
     <!-- The title of the ringtone picker dialog. -->
     <string name="ringtone_picker_title">Ringtones</string>
+    <!-- The title of the alarm sound picker dialog [CHAR LIMIT=100] -->
+    <string name="ringtone_picker_title_alarm">Alarm sounds</string>
+    <!-- The title of the notification sound picker dialog [CHAR LIMIT=100] -->
+    <string name="ringtone_picker_title_notification">Notification sounds</string>
     <!-- If there is ever a ringtone set for some setting, but that ringtone can no longer be resolved, t his is shown instead.  For example, if the ringtone was on a SD card and it had been removed, this woudl be shown for ringtones on that SD card. -->
-    <string name="ringtone_unknown">Unknown ringtone</string>
+    <string name="ringtone_unknown">Unknown</string>
 
     <!-- A notification is shown when there are open wireless networks nearby.  This is the notification's title. -->
     <plurals name="wifi_available">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6c0dc35..c719664 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -851,6 +851,8 @@
   <java-symbol type="string" name="ringtone_default" />
   <java-symbol type="string" name="ringtone_default_with_actual" />
   <java-symbol type="string" name="ringtone_picker_title" />
+  <java-symbol type="string" name="ringtone_picker_title_alarm" />
+  <java-symbol type="string" name="ringtone_picker_title_notification" />
   <java-symbol type="string" name="ringtone_silent" />
   <java-symbol type="string" name="ringtone_unknown" />
   <java-symbol type="string" name="roamingText0" />
@@ -2296,7 +2298,7 @@
   <java-symbol type="dimen" name="cascading_menus_min_smallest_width" />
 
   <!-- From SignalStrength -->
-  <java-symbol type="integer" name="config_LTE_RSRP_threshold_type" />
+  <java-symbol type="array" name="config_lteDbmThresholds" />
 
   <java-symbol type="string" name="android_system_label" />
   <java-symbol type="string" name="system_error_wipe_data" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index ff8693b..0de773b 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -175,6 +175,7 @@
         <item name="windowSharedElementExitTransition">@transition/move</item>
         <item name="windowContentTransitions">false</item>
         <item name="windowActivityTransitions">true</item>
+        <item name="windowSwipeToDismiss">@bool/config_windowSwipeToDismiss</item>
 
         <!-- Dialog attributes -->
         <item name="dialogTheme">@style/ThemeOverlay.Material.Dialog</item>
@@ -536,6 +537,7 @@
         <item name="windowSharedElementExitTransition">@transition/move</item>
         <item name="windowContentTransitions">false</item>
         <item name="windowActivityTransitions">true</item>
+        <item name="windowSwipeToDismiss">@bool/config_windowSwipeToDismiss</item>
 
         <!-- Dialog attributes -->
         <item name="dialogTheme">@style/ThemeOverlay.Material.Dialog</item>
diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk
index 9e45d09..d7b38e8 100644
--- a/core/tests/coretests/apks/install_jni_lib/Android.mk
+++ b/core/tests/coretests/apks/install_jni_lib/Android.mk
@@ -19,8 +19,7 @@
 LOCAL_SRC_FILES := \
     com_android_frameworks_coretests_JNITest.cpp
 
-LOCAL_SHARED_LIBRARIES := \
-    libnativehelper
+LOCAL_SDK_VERSION := 16
 
 LOCAL_CFLAGS += -Wall -Werror
 
diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
index 8d91192..0cf3a84 100644
--- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
+++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp
@@ -14,41 +14,23 @@
  * limitations under the License.
  */
 
-#include "nativehelper/JNIHelp.h"
+#include <jni.h>
 
-namespace android {
-
-static jint checkFunction(JNIEnv*, jclass) {
+extern "C" JNIEXPORT
+jint JNICALL Java_com_android_frameworks_coretests_JNITests_checkFunction(JNIEnv*, jclass) {
     return 1;
 }
 
-static const JNINativeMethod sMethods[] = {
-    /* name, signature, funcPtr */
-    { "checkFunction", "()I", (void*) checkFunction },
-};
-
-int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods,
-            NELEM(sMethods));
-}
-
-}
-
 /*
  * JNI Initialization
  */
 jint JNI_OnLoad(JavaVM *jvm, void */* reserved */) {
     JNIEnv *e;
-    int status;
 
     // Check JNI version
     if (jvm->GetEnv((void **) &e, JNI_VERSION_1_6)) {
         return JNI_ERR;
     }
 
-    if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) {
-        return JNI_ERR;
-    }
-
     return JNI_VERSION_1_6;
 }
diff --git a/core/tests/coretests/src/android/app/activity/BroadcastTest.java b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
index f28ba7e..e9e8bfc 100644
--- a/core/tests/coretests/src/android/app/activity/BroadcastTest.java
+++ b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
@@ -17,7 +17,7 @@
 package android.app.activity;
 
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -304,10 +304,10 @@
     public void testSetSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.getDefault().unbroadcastIntent(null, intent,
+        ActivityManager.getService().unbroadcastIntent(null, intent,
                 UserHandle.myUserId());
 
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         addIntermediate("finished-broadcast");
 
         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
@@ -319,9 +319,9 @@
     public void testClearSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
-        ActivityManagerNative.getDefault().unbroadcastIntent(
+        ActivityManager.getService().unbroadcastIntent(
                 null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null),
                 UserHandle.myUserId());
         addIntermediate("finished-unbroadcast");
@@ -334,10 +334,10 @@
     public void testReplaceSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         intent.putExtra("test", LaunchpadActivity.DATA_2);
 
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         addIntermediate("finished-broadcast");
 
         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
@@ -351,7 +351,7 @@
     public void testReceiveSticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY1);
     }
@@ -361,10 +361,10 @@
     public void testReceive2Sticky() throws Exception {
         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
         intent.putExtra("test", LaunchpadActivity.DATA_1);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
         intent = new Intent(LaunchpadActivity.BROADCAST_STICKY2, null);
         intent.putExtra("test", LaunchpadActivity.DATA_2);
-        ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.myUserId());
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.myUserId());
 
         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY2);
     }
diff --git a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
index 06c495e..5af2667 100644
--- a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java
@@ -21,7 +21,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -31,14 +31,14 @@
     private static final boolean localLOGV = true;
     public static final String TAG = "PackageHelperTests";
     protected final String PREFIX = "android.content.pm";
-    private IMountService mMs;
+    private IStorageManager mSm;
     private String fullId;
     private String fullId2;
 
-    private IMountService getMs() {
+    private IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
             Log.e(TAG, "Can't get mount service");
         }
@@ -47,12 +47,12 @@
 
     private void cleanupContainers() throws RemoteException {
         Log.d(TAG,"cleanUp");
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
         for (int i = 0; i < containers.length; i++) {
             if (containers[i].startsWith(PREFIX)) {
                 Log.d(TAG,"cleaing up "+containers[i]);
-                ms.destroySecureContainer(containers[i], true);
+                sm.destroySecureContainer(containers[i], true);
             }
         }
     }
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index b5f0617..a15cba0 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -46,7 +46,7 @@
 import android.os.StatFs;
 import android.os.SystemClock;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageListener;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
@@ -1149,12 +1149,12 @@
         }
     }
 
-    IMountService getMs() {
+    IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
+            Log.e(TAG, "Can't get storagemanager service");
         }
         return null;
     }
@@ -1185,7 +1185,7 @@
         try {
             // Wait on observer
             synchronized (observer) {
-                int ret = getMs().mountVolume(path);
+                int ret = getSm().mountVolume(path);
                 if (ret != StorageResultCode.OperationSucceeded) {
                     throw new Exception("Could not mount the media");
                 }
@@ -1224,7 +1224,7 @@
         try {
             // Wait on observer
             synchronized (observer) {
-                getMs().unmountVolume(path, true, false);
+                getSm().unmountVolume(path, true, false);
                 long waitTime = 0;
                 while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
                     observer.wait(WAIT_TIME_INCR);
@@ -2754,7 +2754,7 @@
         }
     }
 
-    /* This test creates a stale container via MountService and then installs
+    /* This test creates a stale container via StorageManagerService and then installs
      * a package and verifies that the stale container is cleaned up and install
      * is successful.
      * Please note that this test is very closely tied to the framework's
diff --git a/core/tests/coretests/src/android/net/RoughtimeClientTest.java b/core/tests/coretests/src/android/net/RoughtimeClientTest.java
new file mode 100644
index 0000000..cd26804
--- /dev/null
+++ b/core/tests/coretests/src/android/net/RoughtimeClientTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.RoughtimeClient;
+import android.util.Log;
+import libcore.util.HexEncoding;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+
+public class RoughtimeClientTest extends TestCase {
+    private static final String TAG = "RoughtimeClientTest";
+
+    private static final long TEST_TIME = 8675309;
+    private static final int TEST_RADIUS = 42;
+
+    private final RoughtimeTestServer mServer = new RoughtimeTestServer();
+    private final RoughtimeClient mClient = new RoughtimeClient();
+
+    public void testBasicWorkingRoughtimeClientQuery() throws Exception {
+        mServer.shouldRespond(true);
+        assertTrue(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
+        assertEquals(1, mServer.numRequestsReceived());
+        assertEquals(1, mServer.numRepliesSent());
+    }
+
+    public void testDnsResolutionFailure() throws Exception {
+        mServer.shouldRespond(true);
+        assertFalse(mClient.requestTime("roughtime.server.doesnotexist.example", 5000));
+    }
+
+    public void testTimeoutFailure() throws Exception {
+        mServer.shouldRespond(false);
+        assertFalse(mClient.requestTime(mServer.getAddress(), mServer.getPort(), 500));
+        assertEquals(1, mServer.numRequestsReceived());
+        assertEquals(0, mServer.numRepliesSent());
+    }
+
+    private static MessageDigest md = null;
+
+    private static byte[] signedResponse(byte[] nonce) {
+        RoughtimeClient.Message signed = new RoughtimeClient.Message();
+
+        try {
+            if (md == null) {
+                md = MessageDigest.getInstance("SHA-512");
+            }
+        } catch(Exception e) {
+            return null;
+        }
+
+        md.update(new byte[]{0});
+        byte[] hash = md.digest(nonce);
+        signed.put(RoughtimeClient.Tag.ROOT, hash);
+        signed.putLong(RoughtimeClient.Tag.MIDP, TEST_TIME);
+        signed.putInt(RoughtimeClient.Tag.RADI, TEST_RADIUS);
+
+        return signed.serialize();
+    }
+
+    private static byte[] response(byte[] nonce) {
+        RoughtimeClient.Message msg = new RoughtimeClient.Message();
+
+        msg.put(RoughtimeClient.Tag.SREP, signedResponse(nonce));
+        msg.putInt(RoughtimeClient.Tag.INDX, 0);
+        msg.put(RoughtimeClient.Tag.PATH, new byte[0]);
+
+        return msg.serialize();
+    }
+
+    private static class RoughtimeTestServer {
+        private final Object mLock = new Object();
+        private final DatagramSocket mSocket;
+        private final InetAddress mAddress;
+        private final int mPort;
+        private int mRcvd;
+        private int mSent;
+        private Thread mListeningThread;
+        private boolean mShouldRespond = true;
+
+        public RoughtimeTestServer() {
+            mSocket = makeSocket();
+            mAddress = mSocket.getLocalAddress();
+            mPort = mSocket.getLocalPort();
+            Log.d(TAG, "testing server listening on (" + mAddress + ", " + mPort + ")");
+
+            mListeningThread = new Thread() {
+                public void run() {
+                    while (true) {
+                        byte[] buffer = new byte[2048];
+                        DatagramPacket request = new DatagramPacket(buffer, buffer.length);
+                        try {
+                            mSocket.receive(request);
+                        } catch (IOException e) {
+                            Log.e(TAG, "datagram receive error: " + e);
+                            break;
+                        }
+                        synchronized (mLock) {
+                            mRcvd++;
+
+                            if (! mShouldRespond) {
+                                continue;
+                            }
+
+                            RoughtimeClient.Message msg =
+                                RoughtimeClient.Message.deserialize(
+                                    Arrays.copyOf(buffer, request.getLength()));
+
+                            byte[] nonce = msg.get(RoughtimeClient.Tag.NONC);
+                            if (nonce.length != 64) {
+                                Log.e(TAG, "Nonce is wrong length.");
+                            }
+
+                            try {
+                                request.setData(response(nonce));
+                                mSocket.send(request);
+                            } catch (IOException e) {
+                                Log.e(TAG, "datagram send error: " + e);
+                                break;
+                            }
+                            mSent++;
+                        }
+                    }
+                    mSocket.close();
+                }
+            };
+            mListeningThread.start();
+        }
+
+        private DatagramSocket makeSocket() {
+            DatagramSocket socket;
+            try {
+                socket = new DatagramSocket(0, InetAddress.getLoopbackAddress());
+            } catch (SocketException e) {
+                Log.e(TAG, "Failed to create test server socket: " + e);
+                return null;
+            }
+            return socket;
+        }
+
+        public void shouldRespond(boolean value) { mShouldRespond = value; }
+
+        public InetAddress getAddress() { return mAddress; }
+        public int getPort() { return mPort; }
+        public int numRequestsReceived() { synchronized (mLock) { return mRcvd; } }
+        public int numRepliesSent() { synchronized (mLock) { return mSent; } }
+    }
+}
diff --git a/core/tests/coretests/src/android/os/storage/AsecTests.java b/core/tests/coretests/src/android/os/storage/AsecTests.java
index 4f724fe..e9a810d 100644
--- a/core/tests/coretests/src/android/os/storage/AsecTests.java
+++ b/core/tests/coretests/src/android/os/storage/AsecTests.java
@@ -50,21 +50,21 @@
     }
 
     private void cleanupContainers() throws RemoteException {
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
 
         for (int i = 0; i < containers.length; i++) {
             if (containers[i].startsWith(SECURE_CONTAINER_PREFIX)) {
                 if (localLOGV)
                     Log.i(TAG, "Cleaning: " + containers[i]);
-                ms.destroySecureContainer(containers[i], true);
+                sm.destroySecureContainer(containers[i], true);
             }
         }
     }
 
     private boolean containerExists(String localId) throws RemoteException {
-        IMountService ms = getMs();
-        String[] containers = ms.getSecureContainerList();
+        IStorageManager sm = getSm();
+        String[] containers = sm.getSecureContainerList();
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
         for (int i = 0; i < containers.length; i++) {
@@ -80,8 +80,8 @@
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(),
+        IStorageManager sm = getSm();
+        return sm.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(),
                 isExternal);
     }
 
@@ -89,8 +89,8 @@
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.mountSecureContainer(fullId, key, android.os.Process.myUid(), true);
+        IStorageManager sm = getSm();
+        return sm.mountSecureContainer(fullId, key, android.os.Process.myUid(), true);
     }
 
     private int renameContainer(String localId1, String localId2) throws Exception {
@@ -98,47 +98,47 @@
         String fullId1 = SECURE_CONTAINER_PREFIX + localId1;
         String fullId2 = SECURE_CONTAINER_PREFIX + localId2;
 
-        IMountService ms = getMs();
-        return ms.renameSecureContainer(fullId1, fullId2);
+        IStorageManager sm = getSm();
+        return sm.renameSecureContainer(fullId1, fullId2);
     }
 
     private int unmountContainer(String localId, boolean force) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.unmountSecureContainer(fullId, force);
+        IStorageManager sm = getSm();
+        return sm.unmountSecureContainer(fullId, force);
     }
 
     private int destroyContainer(String localId, boolean force) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.destroySecureContainer(fullId, force);
+        IStorageManager sm = getSm();
+        return sm.destroySecureContainer(fullId, force);
     }
 
     private boolean isContainerMounted(String localId) throws Exception {
         assertTrue("Media should be mounted", isMediaMounted());
         String fullId = SECURE_CONTAINER_PREFIX + localId;
 
-        IMountService ms = getMs();
-        return ms.isSecureContainerMounted(fullId);
+        IStorageManager sm = getSm();
+        return sm.isSecureContainerMounted(fullId);
     }
 
-    private IMountService getMs() {
+    private IStorageManager getSm() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
-            return IMountService.Stub.asInterface(service);
+            return IStorageManager.Stub.asInterface(service);
         } else {
-            Log.e(TAG, "Can't get mount service");
+            Log.e(TAG, "Can't get storagemanager service");
         }
         return null;
     }
 
     private boolean isMediaMounted() throws Exception {
         String mPath = Environment.getExternalStorageDirectory().toString();
-        String state = getMs().getVolumeState(mPath);
+        String state = getSm().getVolumeState(mPath);
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 
@@ -385,11 +385,11 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testUnmountBusyContainer", 4, "none", FS_FAT, true));
 
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX
                 + "testUnmountBusyContainer");
 
         File f = new File(path, "reference");
@@ -408,12 +408,12 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
 
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testDestroyBusyContainer", 4, "none", FS_FAT, true));
 
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX
                 + "testDestroyBusyContainer");
 
         File f = new File(path, "reference");
@@ -480,10 +480,10 @@
             return;
         }
 
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertEquals(StorageResultCode.OperationSucceeded,
                 createContainer("testContainerSize", 1, "none", FS_FAT, true));
-        String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize");
+        String path = sm.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize");
 
         byte[] buf = new byte[4096];
         File f = new File(path, "reference");
@@ -495,9 +495,9 @@
     }
 
     public void testGetSecureContainerPath_NonExistPath_Failure() throws Exception {
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         assertNull("Getting the path for an invalid container should return null",
-                ms.getSecureContainerPath("jparks.broke.it"));
+                sm.getSecureContainerPath("jparks.broke.it"));
     }
 
     /*------------ Tests for unmounting volume ---*/
@@ -506,7 +506,7 @@
 
     boolean getMediaState() throws Exception {
         String mPath = Environment.getExternalStorageDirectory().toString();
-        String state = getMs().getVolumeState(mPath);
+        String state = getSm().getVolumeState(mPath);
         return Environment.MEDIA_MOUNTED.equals(state);
     }
 
@@ -520,7 +520,7 @@
         }
 
         String mPath = Environment.getExternalStorageDirectory().toString();
-        int ret = getMs().mountVolume(mPath);
+        int ret = getSm().mountVolume(mPath);
         return ret == StorageResultCode.OperationSucceeded;
     }
 
@@ -567,7 +567,7 @@
         try {
             // Wait on observer
             synchronized(observer) {
-                getMs().unmountVolume(path, false, false);
+                getSm().unmountVolume(path, false, false);
                 long waitTime = 0;
                 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                     observer.wait(WAIT_TIME_INCR);
@@ -634,7 +634,7 @@
             // Wait on observer
             synchronized(observer) {
                 for (int i = 0; i < 5; i++) {
-                    getMs().unmountVolume(path, false, false);
+                    getSm().unmountVolume(path, false, false);
                 }
                 long waitTime = 0;
                 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
@@ -661,7 +661,7 @@
         }
     }
 
-    class ShutdownObserver extends  IMountShutdownObserver.Stub{
+    class ShutdownObserver extends  IStorageShutdownObserver.Stub{
         private boolean doneFlag = false;
         int statusCode;
 
@@ -683,10 +683,10 @@
     }
 
     void invokeShutdown() throws Exception {
-        IMountService ms = getMs();
+        IStorageManager sm = getSm();
         ShutdownObserver observer = new ShutdownObserver();
         synchronized (observer) {
-            ms.shutdown(observer);
+            sm.shutdown(observer);
         }
     }
 
@@ -731,12 +731,12 @@
             if (!getMediaState()) {
                 mountMedia();
             }
-            IMountService ms = getMs();
+            IStorageManager sm = getSm();
             ShutdownObserver observer = new ShutdownObserver();
             synchronized (observer) {
-                ms.shutdown(observer);
+                sm.shutdown(observer);
                 for (int i = 0; i < 4; i++) {
-                    ms.shutdown(null);
+                    sm.shutdown(null);
                 }
             }
         } finally {
diff --git a/data/etc/Android.mk b/data/etc/Android.mk
index 134ac0c..6718259 100644
--- a/data/etc/Android.mk
+++ b/data/etc/Android.mk
@@ -18,30 +18,17 @@
 
 ########################
 include $(CLEAR_VARS)
-
 LOCAL_MODULE := platform.xml
-
 LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
 include $(BUILD_PREBUILT)
 
 ########################
-#include $(CLEAR_VARS)
+include $(CLEAR_VARS)
+LOCAL_MODULE := privapp-permissions-platform.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
 
-#LOCAL_MODULE := required_hardware.xml
-
-#LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-#LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-#LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-#include $(BUILD_PREBUILT)
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
new file mode 100644
index 0000000..3fc7914
--- /dev/null
+++ b/data/etc/privapp-permissions-platform.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<!--
+This XML file declares which signature|privileged permissions should be granted to privileged
+applications that come with the platform
+-->
+<permissions>
+    <privapp-permissions package="com.android.backupconfirm">
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.CRYPT_KEEPER"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.cellbroadcastreceiver">
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.contacts">
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.defcontainer">
+        <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.dialer">
+        <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
+        <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+        <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.emergency">
+        <permission name="android.permission.MANAGE_USERS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.externalstorage">
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.launcher">
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.location.fused">
+        <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.managedprovisioning">
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CRYPT_KEEPER"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.SET_TIME_ZONE"/>
+        <permission name="android.permission.SHUTDOWN"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.mms.service">
+        <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.mtp">
+        <permission name="android.permission.MANAGE_USB"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.musicfx">
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.packageinstaller">
+        <permission name="android.permission.CLEAR_APP_CACHE"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.phone">
+        <permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
+        <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
+        <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
+        <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+        <permission name="android.permission.SEND_RESPOND_VIA_MESSAGE"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.SET_TIME_ZONE"/>
+        <permission name="android.permission.SHUTDOWN"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+        <permission name="android.permission.UPDATE_LOCK"/>
+        <permission name="android.permission.WRITE_APN_SETTINGS"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+        <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.calendar">
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.contacts">
+        <permission name="android.permission.BIND_DIRECTORY_SEARCH"/>
+        <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.downloads">
+        <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
+        <permission name="android.permission.CLEAR_APP_CACHE"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.MODIFY_NETWORK_ACCOUNTING"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.UPDATE_DEVICE_STATS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.media">
+        <permission name="android.permission.ACCESS_MTP"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.providers.telephony">
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.provision">
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.server.telecom">
+        <permission name="android.permission.BIND_CONNECTION_SERVICE"/>
+        <permission name="android.permission.BIND_INCALL_SERVICE"/>
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.settings">
+        <permission name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
+        <permission name="android.permission.ACCESS_NOTIFICATIONS"/>
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.FORCE_STOP_PACKAGES"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MANAGE_FINGERPRINT"/>
+        <permission name="android.permission.MANAGE_USB"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.MOVE_PACKAGE"/>
+        <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
+        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+        <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
+        <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.SET_TIME"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.TETHER_PRIVILEGED"/>
+        <permission name="android.permission.USER_ACTIVITY"/>
+        <permission name="android.permission.WRITE_APN_SETTINGS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.sharedstoragebackup">
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.shell">
+        <permission name="android.permission.BACKUP"/>
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CHANGE_CONFIGURATION"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.DELETE_CACHE_FILES"/>
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.FORCE_STOP_PACKAGES"/>
+        <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
+        <permission name="android.permission.INSTALL_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_ACTIVITY_STACKS"/>
+        <permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+        <permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.MOVE_PACKAGE"/>
+        <permission name="android.permission.READ_FRAME_BUFFER"/>
+        <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
+        <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
+        <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
+        <permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/>
+        <permission name="android.permission.SET_ALWAYS_FINISH"/>
+        <permission name="android.permission.SET_ANIMATION_SCALE"/>
+        <permission name="android.permission.SET_DEBUG_APP"/>
+        <permission name="android.permission.SET_PROCESS_LIMIT"/>
+        <permission name="android.permission.SIGNAL_PERSISTENT_PROCESSES"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.statementservice">
+        <permission name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.storagemanager">
+        <permission name="android.permission.DELETE_PACKAGES"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.systemui">
+        <permission name="android.permission.BATTERY_STATS"/>
+        <permission name="android.permission.BIND_APPWIDGET"/>
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
+        <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CONTROL_VPN"/>
+        <permission name="android.permission.DUMP"/>
+        <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+        <permission name="android.permission.MANAGE_ACTIVITY_STACKS"/>
+        <permission name="android.permission.MANAGE_USB"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+        <permission name="android.permission.MASTER_CLEAR"/>
+        <permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
+        <permission name="android.permission.MODIFY_PHONE_STATE"/>
+        <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
+        <permission name="android.permission.OVERRIDE_WIFI_CONFIG"/>
+        <permission name="android.permission.READ_DREAM_STATE"/>
+        <permission name="android.permission.READ_FRAME_BUFFER"/>
+        <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
+        <permission name="android.permission.START_TASKS_FROM_RECENTS"/>
+        <permission name="android.permission.STATUS_BAR"/>
+        <permission name="android.permission.STOP_APP_SWITCHES"/>
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
+        <permission name="android.permission.TETHER_PRIVILEGED"/>
+        <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.WRITE_DREAM_STATE"/>
+        <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
+        <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+    </privapp-permissions>
+
+    <privapp-permissions package="com.android.vpndialogs">
+        <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.CONTROL_VPN"/>
+    </privapp-permissions>
+
+</permissions>
\ No newline at end of file
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 79c63ee..e628cf8 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1241,6 +1241,11 @@
      * #getAllocationByteCount()}.</p>
      */
     public final int getByteCount() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getByteCount() on a recycle()'d bitmap! "
+                    + "This is undefined behavior!");
+            return 0;
+        }
         // int result permits bitmaps up to 46,340 x 46,340
         return getRowBytes() * getHeight();
     }
@@ -1260,6 +1265,11 @@
      * @see #reconfigure(int, int, Config)
      */
     public final int getAllocationByteCount() {
+        if (mRecycled) {
+            Log.w(TAG, "Called getAllocationByteCount() on a recycle()'d bitmap! "
+                    + "This is undefined behavior!");
+            return 0;
+        }
         return nativeGetAllocationByteCount(mNativePtr);
     }
 
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 98d45dc..554e5d2 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1442,6 +1442,28 @@
     }
 
     /**
+     * Return the paint's word-spacing for text. The default value is 0.
+     *
+     * @return the paint's word-spacing for drawing text.
+     * @hide
+     */
+    public float getWordSpacing() {
+        return nGetWordSpacing(mNativePaint);
+    }
+
+    /**
+     * Set the paint's word-spacing for text. The default value is 0.
+     * The value is in pixels (note the units are not the same as for
+     * letter-spacing).
+     *
+     * @param wordSpacing set the paint's word-spacing for drawing text.
+     * @hide
+     */
+    public void setWordSpacing(float wordSpacing) {
+        nSetWordSpacing(mNativePaint, wordSpacing);
+    }
+
+    /**
      * Returns the font feature settings. The format is the same as the CSS
      * font-feature-settings attribute:
      * <a href="https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop">
@@ -2711,6 +2733,10 @@
     @CriticalNative
     private static native void nSetLetterSpacing(long paintPtr, float letterSpacing);
     @CriticalNative
+    private static native float nGetWordSpacing(long paintPtr);
+    @CriticalNative
+    private static native void nSetWordSpacing(long paintPtr, float wordSpacing);
+    @CriticalNative
     private static native int nGetHyphenEdit(long paintPtr);
     @CriticalNative
     private static native void nSetHyphenEdit(long paintPtr, int hyphen);
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 40a2833..00b5eda 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -15,14 +15,14 @@
 package android.graphics.drawable;
 
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorInflater;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
-import android.animation.ObjectAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
@@ -55,11 +55,8 @@
 import android.view.View;
 
 import com.android.internal.R;
-
 import com.android.internal.util.VirtualRefBasePtr;
 
-import dalvik.annotation.optimization.FastNative;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -67,6 +64,8 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
+import dalvik.annotation.optimization.FastNative;
+
 /**
  * This class animates properties of a {@link android.graphics.drawable.VectorDrawable} with
  * animations defined using {@link android.animation.ObjectAnimator} or
@@ -91,9 +90,77 @@
  * <a name="VDExample"></a>
  * <li><h4>XML for the VectorDrawable containing properties to be animated</h4>
  * <p>
- * Animations can be performed on both group and path attributes, which requires groups and paths to
- * have unique names in the same VectorDrawable. Groups and paths without animations do not need to
- * be named.
+ * Animations can be performed on the animatable attributes in
+ * {@link android.graphics.drawable.VectorDrawable}. These attributes will be animated by
+ * {@link android.animation.ObjectAnimator}. The ObjectAnimator's target can be the root element,
+ * a group element or a path element. The targeted elements need to be named uniquely within
+ * the same VectorDrawable. Elements without animation do not need to be named.
+ * </p>
+ * <p>
+ * Here are all the animatable attributes in {@link android.graphics.drawable.VectorDrawable}:
+ * <table border="2" align="center" cellpadding="5">
+ *     <thead>
+ *         <tr>
+ *             <th>Element Name</th>
+ *             <th>Animatable attribute name</th>
+ *         </tr>
+ *     </thead>
+ *     <tr>
+ *         <td>&lt;vector&gt;</td>
+ *         <td>alpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="7">&lt;group&gt;</td>
+ *         <td>rotation</td>
+ *     </tr>
+ *     <tr>
+ *         <td>pivotX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>pivotY</td>
+ *     </tr>
+ *     <tr>
+ *         <td>scaleX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>scaleY</td>
+ *     </tr>
+ *     <tr>
+ *         <td>translateX</td>
+ *     </tr>
+ *     <tr>
+ *         <td>translateY</td>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="8">&lt;path&gt;</td>
+ *         <td>pathData</td>
+ *     </tr>
+ *     <tr>
+ *         <td>fillColor</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeColor</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeWidth</td>
+ *     </tr>
+ *     <tr>
+ *         <td>strokeAlpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td>fillAlpha</td>
+ *     </tr>
+ *     <tr>
+ *         <td>trimPathStart</td>
+ *     </tr>
+ *     <tr>
+ *         <td>trimPathOffset</td>
+ *     </tr>
+ *     <tr>
+ *         <td>&lt;clip-path&gt;</td>
+ *         <td>pathData</td>
+ *     </tr>
+ * </table>
  * </p>
  * Below is an example of a VectorDrawable defined in vectordrawable.xml. This VectorDrawable is
  * referred to by its file name (not including file suffix) in the
@@ -121,9 +188,8 @@
  * <li><h4>XML for AnimatedVectorDrawable</h4>
  * <p>
  * An AnimatedVectorDrawable element has a VectorDrawable attribute, and one or more target
- * element(s). The target elements can be the path or group to be animated. Each target element
- * contains a name attribute that references a property (of a path or a group) to animate, and an
- * animation attribute that points to an ObjectAnimator or an AnimatorSet.
+ * element(s). The target element can specify its target by android:name attribute, and link the
+ * target with the proper ObjectAnimator or AnimatorSet by android:animation attribute.
  * </p>
  * The following code sample defines an AnimatedVectorDrawable. Note that the names refer to the
  * groups and paths in the <a href="#VDExample">VectorDrawable XML above</a>.
@@ -176,7 +242,8 @@
  * merge the XML files from the previous examples into one XML file:
  * </p>
  * <pre>
- * &lt;animated-vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; &gt;
+ * &lt;animated-vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ *                  xmlns:aapt=&quothttp://schemas.android.com/aapt&quot; &gt;
  *     &lt;aapt:attr name="android:drawable"&gt;
  *         &lt;vector
  *             android:height=&quot;64dp&quot;
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index e83104d..3a12419 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -77,36 +77,27 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of this vector drawable.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:width</code></dt>
  * <dd>Used to define the intrinsic width of the drawable.
  * This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:height</code></dt>
  * <dd>Used to define the intrinsic height the drawable.
  * This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:viewportWidth</code></dt>
  * <dd>Used to define the width of the viewport space. Viewport is basically
  * the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:viewportHeight</code></dt>
  * <dd>Used to define the height of the viewport space. Viewport is basically
  * the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:tint</code></dt>
  * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:tintMode</code></dt>
- * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>The Porter-Duff blending mode for the tint color. Default is src_in.</dd>
  * <dt><code>android:autoMirrored</code></dt>
  * <dd>Indicates if the drawable needs to be mirrored when its layout direction is
- * RTL (right-to-left).</dd>
- * <dd>Animatable : No.</dd>
+ * RTL (right-to-left). Default is false.</dd>
  * <dt><code>android:alpha</code></dt>
- * <dd>The opacity of this drawable.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of this drawable. Default is 1.0.</dd>
  * </dl></dd>
  * </dl>
  *
@@ -118,32 +109,24 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of the group.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:rotation</code></dt>
- * <dd>The degrees of rotation of the group.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The degrees of rotation of the group. Default is 0.</dd>
  * <dt><code>android:pivotX</code></dt>
  * <dd>The X coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:pivotY</code></dt>
  * <dd>The Y coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:scaleX</code></dt>
- * <dd>The amount of scale on the X Coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the X Coordinate. Default is 1.</dd>
  * <dt><code>android:scaleY</code></dt>
- * <dd>The amount of scale on the Y coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the Y coordinate. Default is 1.</dd>
  * <dt><code>android:translateX</code></dt>
  * <dd>The amount of translation on the X coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * <dt><code>android:translateY</code></dt>
  * <dd>The amount of translation on the Y coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
  * </dl></dd>
  * </dl>
  *
@@ -153,58 +136,44 @@
  * <dl>
  * <dt><code>android:name</code></dt>
  * <dd>Defines the name of the path.</dd>
- * <dd>Animatable : No.</dd>
  * <dt><code>android:pathData</code></dt>
  * <dd>Defines path data using exactly same format as "d" attribute
  * in the SVG's path data. This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:fillColor</code></dt>
  * <dd>Specifies the color used to fill the path. May be a color or, for SDK 24+, a color state list
  * or a gradient color (See {@link android.R.styleable#GradientColor}
  * and {@link android.R.styleable#GradientColorItem}).
  * If this property is animated, any value set by the animation will override the original value.
  * No path fill is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:strokeColor</code></dt>
  * <dd>Specifies the color used to draw the path outline. May be a color or, for SDK 24+, a color
  * state list or a gradient color (See {@link android.R.styleable#GradientColor}
  * and {@link android.R.styleable#GradientColorItem}).
  * If this property is animated, any value set by the animation will override the original value.
  * No path outline is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
  * <dt><code>android:strokeWidth</code></dt>
- * <dd>The width a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The width a path stroke. Default is 0.</dd>
  * <dt><code>android:strokeAlpha</code></dt>
- * <dd>The opacity of a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of a path stroke. Default is 1.</dd>
  * <dt><code>android:fillAlpha</code></dt>
- * <dd>The opacity to fill the path with.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity to fill the path with. Default is 1.</dd>
  * <dt><code>android:trimPathStart</code></dt>
- * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the start, in the range from 0 to 1. Default is 0.</dd>
  * <dt><code>android:trimPathEnd</code></dt>
- * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the end, in the range from 0 to 1. Default is 1.</dd>
  * <dt><code>android:trimPathOffset</code></dt>
  * <dd>Shift trim region (allows showed region to include the start and end), in the range
- * from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * from 0 to 1. Default is 0.</dd>
  * <dt><code>android:strokeLineCap</code></dt>
- * <dd>Sets the linecap for a stroked path: butt, round, square.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the linecap for a stroked path: butt, round, square. Default is butt.</dd>
  * <dt><code>android:strokeLineJoin</code></dt>
- * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the lineJoin for a stroked path: miter,round,bevel. Default is miter.</dd>
  * <dt><code>android:strokeMiterLimit</code></dt>
- * <dd>Sets the Miter limit for a stroked path.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the Miter limit for a stroked path. Default is 4.</dd>
  * <dt><code>android:fillType</code></dt>
- * <dd>Sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the
- * same as SVG's "fill-rule" properties. For more details, see
+ * <dd>For SDK 24+, sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the
+ * same as SVG's "fill-rule" properties. Default is nonZero. For more details, see
  * <a href="https://www.w3.org/TR/SVG/painting.html#FillRuleProperty">FillRuleProperty</a></dd>
- * <dd>Animatable : No.</dd>
  * </dl></dd>
  *
  * </dl>
diff --git a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java b/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
index 6763dd1..318bfb6 100644
--- a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
@@ -218,4 +218,13 @@
             assertEquals(width, p.measureText(bidiText), 1.0f);
         }
     }
+
+    public void testSetGetWordSpacing() {
+        Paint p = new Paint();
+        assertEquals(0.0f, p.getWordSpacing());  // The default value should be 0.
+        p.setWordSpacing(1.0f);
+        assertEquals(1.0f, p.getWordSpacing());
+        p.setWordSpacing(-2.0f);
+        assertEquals(-2.0f, p.getWordSpacing());
+    }
 }
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 5e59a64..e566b9d 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -414,6 +414,9 @@
         if (alias == null) {
             throw new NullPointerException("alias == null");
         }
+        if (context == null) {
+            throw new NullPointerException("context == null");
+        }
 
         final String keyId;
         try (KeyChainConnection keyChainConnection = bind(context.getApplicationContext())) {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 7d1e328..907d914 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -3204,7 +3204,7 @@
 {
     Package(ResTable* _owner, const Header* _header, const ResTable_package* _package)
         : owner(_owner), header(_header), package(_package), typeIdOffset(0) {
-        if (dtohs(package->header.headerSize) == sizeof(package)) {
+        if (dtohs(package->header.headerSize) == sizeof(*package)) {
             // The package structure is the same size as the definition.
             // This means it contains the typeIdOffset field.
             typeIdOffset = package->typeIdOffset;
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 4722050..fdf4d52 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -24,6 +24,7 @@
     pipeline/skia/ReorderBarrierDrawables.cpp \
     pipeline/skia/SkiaDisplayList.cpp \
     pipeline/skia/SkiaOpenGLPipeline.cpp \
+    pipeline/skia/SkiaOpenGLReadback.cpp \
     pipeline/skia/SkiaPipeline.cpp \
     pipeline/skia/SkiaProfileRenderer.cpp \
     pipeline/skia/SkiaRecordingCanvas.cpp \
@@ -84,6 +85,7 @@
     LayerUpdateQueue.cpp \
     Matrix.cpp \
     OpDumper.cpp \
+    OpenGLReadback.cpp \
     Patch.cpp \
     PatchCache.cpp \
     PathCache.cpp \
@@ -96,7 +98,6 @@
     Properties.cpp \
     PropertyValuesAnimatorSet.cpp \
     PropertyValuesHolder.cpp \
-    Readback.cpp \
     RecordingCanvas.cpp \
     RenderBufferCache.cpp \
     RenderNode.cpp \
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/OpenGLReadback.cpp
similarity index 76%
rename from libs/hwui/Readback.cpp
rename to libs/hwui/OpenGLReadback.cpp
index 1645218..408159b 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Readback.h"
+#include "OpenGLReadback.h"
 
 #include "Caches.h"
 #include "Image.h"
@@ -31,8 +31,81 @@
 namespace android {
 namespace uirenderer {
 
-static CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
-        Texture& sourceTexture, Matrix4& texTransform, const Rect& srcRect,
+CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
+        SkBitmap* bitmap) {
+    ATRACE_CALL();
+    // Setup the source
+    sp<GraphicBuffer> sourceBuffer;
+    sp<Fence> sourceFence;
+    Matrix4 texTransform;
+    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence,
+            texTransform.data);
+    texTransform.invalidateType();
+    if (err != NO_ERROR) {
+        ALOGW("Failed to get last queued buffer, error = %d", err);
+        return CopyResult::UnknownError;
+    }
+    if (!sourceBuffer.get()) {
+        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
+        return CopyResult::SourceEmpty;
+    }
+    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
+        ALOGW("Surface is protected, unable to copy from it");
+        return CopyResult::SourceInvalid;
+    }
+    err = sourceFence->wait(500 /* ms */);
+    if (err != NO_ERROR) {
+        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
+        return CopyResult::Timeout;
+    }
+
+    return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap);
+}
+
+CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
+        Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) {
+    mRenderThread.eglManager().initialize();
+    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
+    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
+    // to be able to properly sample from the buffer.
+
+    // Create the EGLImage object that maps the GraphicBuffer
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) graphicBuffer->getNativeBuffer();
+    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+            EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
+
+    if (sourceImage == EGL_NO_IMAGE_KHR) {
+        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
+        return CopyResult::UnknownError;
+    }
+
+    CopyResult copyResult = copyImageInto(sourceImage, texTransform, graphicBuffer->getWidth(),
+            graphicBuffer->getHeight(), srcRect, bitmap);
+
+    // All we're flushing & finishing is the deletion of the texture since
+    // copyImageInto already did a major flush & finish as an implicit
+    // part of glReadPixels, so this shouldn't pose any major stalls.
+    glFinish();
+    eglDestroyImageKHR(display, sourceImage);
+    return copyResult;
+}
+
+CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) {
+    Rect srcRect;
+    Matrix4 transform;
+    transform.loadScale(1, -1, 1);
+    transform.translate(0, -1);
+    return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
+        Texture& sourceTexture, const Matrix4& texTransform, const Rect& srcRect,
         SkBitmap* bitmap) {
     int destWidth = bitmap->width();
     int destHeight = bitmap->height();
@@ -134,88 +207,40 @@
     return CopyResult::Success;
 }
 
-CopyResult Readback::copySurfaceInto(renderthread::RenderThread& renderThread,
-        Surface& surface, const Rect& srcRect, SkBitmap* bitmap) {
-    ATRACE_CALL();
-    renderThread.eglManager().initialize();
+CopyResult OpenGLReadbackImpl::copyImageInto(EGLImageKHR eglImage,
+        const Matrix4& imgTransform, int imgWidth, int imgHeight, const Rect& srcRect,
+        SkBitmap* bitmap) {
 
     Caches& caches = Caches::getInstance();
-
-    // Setup the source
-    sp<GraphicBuffer> sourceBuffer;
-    sp<Fence> sourceFence;
-    Matrix4 texTransform;
-    status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence,
-            texTransform.data);
-    texTransform.invalidateType();
-    if (err != NO_ERROR) {
-        ALOGW("Failed to get last queued buffer, error = %d", err);
-        return CopyResult::UnknownError;
-    }
-    if (!sourceBuffer.get()) {
-        ALOGW("Surface doesn't have any previously queued frames, nothing to readback from");
-        return CopyResult::SourceEmpty;
-    }
-    if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) {
-        ALOGW("Surface is protected, unable to copy from it");
-        return CopyResult::SourceInvalid;
-    }
-    err = sourceFence->wait(500 /* ms */);
-    if (err != NO_ERROR) {
-        ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt");
-        return CopyResult::Timeout;
-    }
-
-    // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
-    // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
-    // to be able to properly sample from the buffer.
-
-    // Create the EGLImage object that maps the GraphicBuffer
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    EGLClientBuffer clientBuffer = (EGLClientBuffer) sourceBuffer->getNativeBuffer();
-    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-
-    EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
-            EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
-
-    if (sourceImage == EGL_NO_IMAGE_KHR) {
-        ALOGW("eglCreateImageKHR failed (%#x)", eglGetError());
-        return CopyResult::UnknownError;
-    }
     GLuint sourceTexId;
     // Create a 2D texture to sample from the EGLImage
     glGenTextures(1, &sourceTexId);
     caches.textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, sourceImage);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
 
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
         ALOGW("glEGLImageTargetTexture2DOES failed (%#x)", status);
-        eglDestroyImageKHR(display, sourceImage);
         return CopyResult::UnknownError;
     }
 
     Texture sourceTexture(caches);
-    sourceTexture.wrap(sourceTexId, sourceBuffer->getWidth(),
-            sourceBuffer->getHeight(), 0, 0 /* total lie */, GL_TEXTURE_EXTERNAL_OES);
+    sourceTexture.wrap(sourceTexId, imgWidth, imgHeight, 0, 0 /* total lie */,
+            GL_TEXTURE_EXTERNAL_OES);
 
-    CopyResult copyResult = copyTextureInto(caches, renderThread.renderState(),
-            sourceTexture, texTransform, srcRect, bitmap);
+    CopyResult copyResult = copyTextureInto(caches, mRenderThread.renderState(),
+            sourceTexture, imgTransform, srcRect, bitmap);
     sourceTexture.deleteTexture();
-    // All we're flushing & finishing is the deletion of the texture since
-    // copyTextureInto already did a major flush & finish as an implicit
-    // part of glReadPixels, so this shouldn't pose any major stalls.
-    glFinish();
-    eglDestroyImageKHR(display, sourceImage);
     return copyResult;
 }
 
-CopyResult Readback::copyTextureLayerInto(renderthread::RenderThread& renderThread,
+bool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread,
         Layer& layer, SkBitmap* bitmap) {
-    ATRACE_CALL();
-    return copyTextureInto(Caches::getInstance(), renderThread.renderState(),
-            layer.getTexture(), layer.getTexTransform(), Rect(), bitmap);
+    return CopyResult::Success == copyTextureInto(Caches::getInstance(),
+            renderThread.renderState(), layer.getTexture(), layer.getTexTransform(),
+            Rect(), bitmap);
 }
 
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
new file mode 100644
index 0000000..f4ebabc
--- /dev/null
+++ b/libs/hwui/OpenGLReadback.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Readback.h"
+
+namespace android {
+namespace uirenderer {
+
+class Matrix4;
+class Layer;
+
+class OpenGLReadback : public Readback {
+public:
+    virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
+            SkBitmap* bitmap) override;
+    virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
+            SkBitmap* bitmap) override;
+
+protected:
+    explicit OpenGLReadback(renderthread::RenderThread& thread) : Readback(thread) {}
+    virtual ~OpenGLReadback() {}
+
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) = 0;
+private:
+    CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, Matrix4& texTransform,
+            const Rect& srcRect, SkBitmap* bitmap);
+};
+
+class OpenGLReadbackImpl : public OpenGLReadback {
+public:
+    OpenGLReadbackImpl(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
+
+    /**
+     * Copies the layer's contents into the provided bitmap.
+     */
+    static bool copyLayerInto(renderthread::RenderThread& renderThread, Layer& layer,
+            SkBitmap* bitmap);
+
+protected:
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) override;
+};
+
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index e410d71..9c4cb09 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -133,7 +133,7 @@
 
     // Shaders
     bool hasBitmap;
-    bool isBitmapNpot;
+    bool useShaderBasedWrap;
 
     bool hasVertexAlpha;
     bool useShadowAlphaInterp;
@@ -180,7 +180,7 @@
         modulate = false;
 
         hasBitmap = false;
-        isBitmapNpot = false;
+        useShaderBasedWrap = false;
 
         hasGradient = false;
         gradientType = kGradientLinear;
@@ -234,7 +234,7 @@
         if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
         if (hasBitmap) {
             key |= PROGRAM_KEY_BITMAP;
-            if (isBitmapNpot) {
+            if (useShaderBasedWrap) {
                 key |= PROGRAM_KEY_BITMAP_NPOT;
                 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
                 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 1afc978..0c2309f 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -707,7 +707,7 @@
     if (blendFramebuffer) {
         generateBlend(shader, "blendFramebuffer", description.framebufferMode);
     }
-    if (description.isBitmapNpot) {
+    if (description.useShaderBasedWrap) {
         generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
     }
     if (description.hasGradient) {
@@ -736,7 +736,7 @@
             shader.append(gFS_Main_FetchGradient[gradientIndex(description)]);
         }
         if (description.hasBitmap) {
-            if (!description.isBitmapNpot) {
+            if (!description.useShaderBasedWrap) {
                 shader.append(gFS_Main_FetchBitmap);
             } else {
                 shader.append(gFS_Main_FetchBitmapNpot);
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index 55c943c..b763953 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -23,10 +23,9 @@
 #include <gui/Surface.h>
 
 namespace android {
+class GraphicBuffer;
 namespace uirenderer {
 
-class Layer;
-
 // Keep in sync with PixelCopy.java codes
 enum class CopyResult {
     Success = 0,
@@ -42,15 +41,15 @@
     /**
      * Copies the surface's most recently queued buffer into the provided bitmap.
      */
-    static CopyResult copySurfaceInto(renderthread::RenderThread& renderThread,
-            Surface& surface, const Rect& srcRect, SkBitmap* bitmap);
+    virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
+            SkBitmap* bitmap) = 0;
+    virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) = 0;
 
-    /**
-     * Copies the TextureLayer's texture content (thus, the currently rendering buffer) into the
-     * provided bitmap.
-     */
-    static CopyResult copyTextureLayerInto(renderthread::RenderThread& renderThread,
-            Layer& layer, SkBitmap* bitmap);
+protected:
+    explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {}
+    virtual ~Readback() {}
+
+    renderthread::RenderThread& mRenderThread;
 };
 
 } // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 971c2a3..34e6a06 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -58,7 +58,7 @@
 }
 
 static inline void bindTexture(Caches* caches, Texture* texture, GLenum wrapS, GLenum wrapT) {
-    caches->textureState().bindTexture(texture->id());
+    caches->textureState().bindTexture(texture->target(), texture->id());
     texture->setWrapST(wrapS, wrapT);
 }
 
@@ -218,10 +218,13 @@
     const float height = outData->bitmapTexture->height();
 
     description->hasBitmap = true;
-    if (!caches.extensions().hasNPot()
+    // gralloc doesn't support non-clamp modes
+    if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot()
             && (!isPowerOfTwo(width) || !isPowerOfTwo(height))
-            && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode)) {
-        description->isBitmapNpot = true;
+            && (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode))) {
+        // need non-clamp mode, but it's not supported for this draw,
+        // so enable custom shader logic to mimic
+        description->useShaderBasedWrap = true;
         description->bitmapWrapS = gTileModes[xy[0]];
         description->bitmapWrapT = gTileModes[xy[1]];
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index b8f7d9f..d6b6548 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -227,7 +227,7 @@
     PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
     status_t error;
     sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat,
-            GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
+            1, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
             | GraphicBuffer::USAGE_SW_READ_NEVER , &error);
 
     if (!buffer.get()) {
@@ -413,7 +413,6 @@
     case PixelStorageType::Heap:
         return mPixelStorage.heap.address;
     case PixelStorageType::Hardware:
-        LOG_ALWAYS_FATAL_IF("Can't get address for hardware bitmap");
         return nullptr;
     }
 }
@@ -460,13 +459,20 @@
 }
 
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
+    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
     if (isHardware()) {
-        //TODO: use readback to get pixels
-        LOG_ALWAYS_FATAL("Not implemented");
+        ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation");
+        outBitmap->allocPixels(info());
+        uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
         return;
     }
     outBitmap->setInfo(info(), rowBytes());
     outBitmap->setPixelRef(this);
+}
+
+void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
+    outBitmap->setInfo(info(), rowBytes());
+    outBitmap->setPixelRef(this);
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
 }
 
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 3940381..663238c 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -85,6 +85,10 @@
 
     void getSkBitmap(SkBitmap* outBitmap);
 
+    // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
+    // so it would crash if anyone tries to render this bitmap.
+    void getSkBitmapForShaders(SkBitmap* outBitmap);
+
     int getAshmemFd() const;
     size_t getAllocationByteCount() const;
 
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index a52abfc..f172473 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -65,23 +65,6 @@
     bounds->mBottom = skBounds.fBottom;
 }
 
-const void* MinikinFontSkia::GetTable(uint32_t tag, size_t* size,
-        minikin::MinikinDestroyFunc* destroy) {
-    // we don't have a buffer to the font data, copy to own buffer
-    const size_t tableSize = mTypeface->getTableSize(tag);
-    *size = tableSize;
-    if (tableSize == 0) {
-        return nullptr;
-    }
-    void* buf = malloc(tableSize);
-    if (buf == nullptr) {
-        return nullptr;
-    }
-    mTypeface->getTableData(tag, 0, tableSize, buf);
-    *destroy = free;
-    return buf;
-}
-
 SkTypeface *MinikinFontSkia::GetSkTypeface() const {
     return mTypeface.get();
 }
diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h
index 1ea99fd..3ee916c 100644
--- a/libs/hwui/hwui/MinikinSkia.h
+++ b/libs/hwui/hwui/MinikinSkia.h
@@ -37,8 +37,6 @@
     void GetBounds(minikin::MinikinRect* bounds, uint32_t glyph_id,
         const minikin::MinikinPaint &paint) const;
 
-    const void* GetTable(uint32_t tag, size_t* size, minikin::MinikinDestroyFunc* destroy);
-
     SkTypeface* GetSkTypeface() const;
     sk_sp<SkTypeface> RefSkTypeface() const;
 
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index a06cc37..8dd165c 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -45,6 +45,7 @@
     minikinPaint->scaleX = paint->getTextScaleX();
     minikinPaint->skewX = paint->getTextSkewX();
     minikinPaint->letterSpacing = paint->getLetterSpacing();
+    minikinPaint->wordSpacing = paint->getWordSpacing();
     minikinPaint->paintFlags = MinikinFontSkia::packPaintFlags(paint);
     minikinPaint->fontFeatureSettings = paint->getFontFeatureSettings();
     minikinPaint->hyphenEdit = minikin::HyphenEdit(paint->getHyphenEdit());
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 10a1db9..c9b5f00 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -48,6 +48,14 @@
         return mLetterSpacing;
     }
 
+    void setWordSpacing(float wordSpacing) {
+        mWordSpacing = wordSpacing;
+    }
+
+    float getWordSpacing() const {
+        return mWordSpacing;
+    }
+
     void setFontFeatureSettings(const std::string& fontFeatureSettings) {
         mFontFeatureSettings = fontFeatureSettings;
     }
@@ -82,6 +90,7 @@
 
 private:
     float mLetterSpacing = 0;
+    float mWordSpacing = 0;
     std::string mFontFeatureSettings;
     uint32_t mMinikinLangListId;
     minikin::FontVariant mFontVariant;
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index 84122d7..6742743 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -19,18 +19,19 @@
 namespace android {
 
 Paint::Paint() :
-        SkPaint(), mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
-        mFontVariant(minikin::VARIANT_DEFAULT) {
+        SkPaint(), mLetterSpacing(0), mWordSpacing(0), mFontFeatureSettings(),
+        mMinikinLangListId(0), mFontVariant(minikin::VARIANT_DEFAULT) {
 }
 
 Paint::Paint(const Paint& paint) : SkPaint(paint),
-        mLetterSpacing(paint.mLetterSpacing), mFontFeatureSettings(paint.mFontFeatureSettings),
+        mLetterSpacing(paint.mLetterSpacing), mWordSpacing(paint.mWordSpacing),
+        mFontFeatureSettings(paint.mFontFeatureSettings),
         mMinikinLangListId(paint.mMinikinLangListId), mFontVariant(paint.mFontVariant),
         mHyphenEdit(paint.mHyphenEdit) {
 }
 
 Paint::Paint(const SkPaint& paint) : SkPaint(paint),
-        mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+        mLetterSpacing(0), mWordSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
         mFontVariant(minikin::VARIANT_DEFAULT) {
 }
 
@@ -40,6 +41,7 @@
 Paint& Paint::operator=(const Paint& other) {
     SkPaint::operator=(other);
     mLetterSpacing = other.mLetterSpacing;
+    mWordSpacing = other.mWordSpacing;
     mFontFeatureSettings = other.mFontFeatureSettings;
     mMinikinLangListId = other.mMinikinLangListId;
     mFontVariant = other.mFontVariant;
@@ -50,6 +52,7 @@
 bool operator==(const Paint& a, const Paint& b) {
     return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
             && a.mLetterSpacing == b.mLetterSpacing
+            && a.mWordSpacing == b.mWordSpacing
             && a.mFontFeatureSettings == b.mFontFeatureSettings
             && a.mMinikinLangListId == b.mMinikinLangListId
             && a.mFontVariant == b.mFontVariant
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 59b1185..ca43156 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -23,10 +23,14 @@
 #include "Typeface.h"
 
 #include <pthread.h>
+#include <fcntl.h>  // For tests.
+#include <sys/stat.h>  // For tests.
+#include <sys/mman.h>  // For tests.
 
 #include "MinikinSkia.h"
 #include "SkTypeface.h"
 #include "SkPaint.h"
+#include "SkStream.h"  // Fot tests.
 
 #include <minikin/FontCollection.h>
 #include <minikin/FontFamily.h>
@@ -49,60 +53,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 +118,34 @@
     gDefaultTypeface = face;
 }
 
+void Typeface::setRobotoTypefaceForTest() {
+    const char* kRobotoFont = "/system/fonts/Roboto-Regular.ttf";
+
+    int fd = open(kRobotoFont, O_RDONLY);
+    LOG_ALWAYS_FATAL_IF(fd == -1, "Failed to open file %s", kRobotoFont);
+    struct stat st = {};
+    LOG_ALWAYS_FATAL_IF(fstat(fd, &st) == -1, "Failed to stat file %s", kRobotoFont);
+    void* data = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    std::unique_ptr<SkMemoryStream> fontData(new SkMemoryStream(data, st.st_size));
+    sk_sp<SkTypeface> typeface = SkTypeface::MakeFromStream(fontData.release());
+    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), data, st.st_size, 0);
+    family->addFont(font);
+    font->Unref();
+
+    std::vector<minikin::FontFamily*> typefaces = { family };
+    minikin::FontCollection *collection = new minikin::FontCollection(typefaces);
+    family->Unref();
+
+    Typeface* hwTypeface = new Typeface();
+    hwTypeface->fFontCollection = collection;
+    hwTypeface->fSkiaStyle = SkTypeface::kNormal;
+    hwTypeface->fBaseWeight = 400;
+    hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */);
+
+    Typeface::setDefault(hwTypeface);
+}
+
 }
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index ed0a7ebd..1be630c 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -48,6 +48,9 @@
     static Typeface* createFromFamilies(const std::vector<minikin::FontFamily*>& families);
 
     static void setDefault(Typeface* face);
+
+    // Sets roboto font as the default typeface for testing purpose.
+    static void setRobotoTypefaceForTest();
 };
 
 }
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 13a0ed8..f2af4a8 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -23,36 +23,41 @@
 namespace skiapipeline {
 
 void LayerDrawable::onDraw(SkCanvas* canvas) {
+    DrawLayer(canvas->getGrContext(), canvas, mLayer.get());
+}
+
+bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer) {
     // transform the matrix based on the layer
     int saveCount = -1;
-    if (!mLayer->getTransform().isIdentity()) {
+    if (!layer->getTransform().isIdentity()) {
         saveCount = canvas->save();
         SkMatrix transform;
-        mLayer->getTransform().copyTo(transform);
+        layer->getTransform().copyTo(transform);
         canvas->concat(transform);
     }
     GrGLTextureInfo externalTexture;
-    externalTexture.fTarget = mLayer->getRenderTarget();
-    externalTexture.fID = mLayer->getTextureId();
-    GrContext* context = canvas->getGrContext();
+    externalTexture.fTarget = layer->getRenderTarget();
+    externalTexture.fID = layer->getTextureId();
     GrBackendTextureDesc textureDescription;
-    textureDescription.fWidth = mLayer->getWidth();
-    textureDescription.fHeight = mLayer->getHeight();
+    textureDescription.fWidth = layer->getWidth();
+    textureDescription.fHeight = layer->getHeight();
     textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
     textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
     textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
     sk_sp<SkImage> layerImage = SkImage::MakeFromTexture(context, textureDescription);
     if (layerImage) {
         SkPaint paint;
-        paint.setAlpha(mLayer->getAlpha());
-        paint.setBlendMode(mLayer->getMode());
-        paint.setColorFilter(sk_ref_sp(mLayer->getColorFilter()));
+        paint.setAlpha(layer->getAlpha());
+        paint.setBlendMode(layer->getMode());
+        paint.setColorFilter(sk_ref_sp(layer->getColorFilter()));
         canvas->drawImage(layerImage, 0, 0, &paint);
     }
     // restore the original matrix
     if (saveCount >= 0) {
         canvas->restoreToCount(saveCount);
     }
+
+    return layerImage;
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 91e2744..4319895 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -33,6 +33,7 @@
     explicit LayerDrawable(Layer* layer)
             : mLayer(layer) {}
 
+    static bool DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer);
  protected:
      virtual SkRect onGetBounds() override {
          return SkRect::MakeWH(mLayer->getWidth(), mLayer->getHeight());
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index accbabd..7dcbbd0 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -164,6 +164,14 @@
                 paint = &tmpPaint;
             }
             renderNode->getLayerSurface()->draw(canvas, 0, 0, paint);
+
+            if (CC_UNLIKELY(Properties::debugLayersUpdates
+                    && !renderNode->getSkiaLayer()->hasRenderedSinceRepaint)) {
+                renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;
+                SkPaint layerPaint;
+                layerPaint.setColor(0x7f00ff00);
+                canvas->drawRect(bounds, layerPaint);
+            }
         // composing a software layer with alpha
         } else if (properties.effectiveLayerType() == LayerType::Software) {
             SkPaint paint;
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 4abaa90..2ad7f74 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -53,11 +53,15 @@
 
 bool SkiaDisplayList::prepareListAndChildren(TreeInfo& info, bool functorsNeedLayer,
         std::function<void(RenderNode*, TreeInfo&, bool)> childFn) {
-    // If the prepare tree is triggered by the UI thread then we must force all
-    // mutable images to be pinned in the GPU cache until the next UI thread
-    // draw
-    if (info.mode == TreeInfo::MODE_FULL) {
-        info.prepareTextures = info.canvasContext.pinImages(mMutableImages);
+    // If the prepare tree is triggered by the UI thread and no previous call to
+    // pinImages has failed then we must pin all mutable images in the GPU cache
+    // until the next UI thread draw.
+    if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) {
+        // In the event that pinning failed we prevent future pinImage calls for the
+        // remainder of this tree traversal and also unpin any currently pinned images
+        // to free up GPU resources.
+        info.prepareTextures = false;
+        info.canvasContext.unpinImages();
     }
 
     for (auto& child : mChildNodes) {
diff --git a/libs/hwui/pipeline/skia/SkiaLayer.h b/libs/hwui/pipeline/skia/SkiaLayer.h
index 0988d7e..904d57e0 100644
--- a/libs/hwui/pipeline/skia/SkiaLayer.h
+++ b/libs/hwui/pipeline/skia/SkiaLayer.h
@@ -30,6 +30,7 @@
 {
     sk_sp<SkSurface> layerSurface;
     Matrix4 inverseTransformInWindow;
+    bool hasRenderedSinceRepaint = false;
 };
 
 
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index f046e4b..7f3474a 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -17,9 +17,9 @@
 #include "SkiaOpenGLPipeline.h"
 
 #include "DeferredLayerUpdater.h"
+#include "LayerDrawable.h"
 #include "renderthread/EglManager.h"
 #include "renderstate/RenderState.h"
-#include "Readback.h"
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "utils/TraceUtils.h"
@@ -121,10 +121,16 @@
     return *requireSwap;
 }
 
-bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
-    layer->apply();
-    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
-            == CopyResult::Success;
+bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) {
+    if (!mRenderThread.getGrContext()) {
+        return false;
+    }
+
+    deferredLayer->apply();
+
+    SkCanvas canvas(*bitmap);
+    Layer* layer = deferredLayer->backingLayer();
+    return LayerDrawable::DrawLayer(mRenderThread.getGrContext(), &canvas, layer);
 }
 
 DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
new file mode 100644
index 0000000..a18d264
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SkiaOpenGLReadback.h"
+
+#include "Matrix.h"
+#include "Properties.h"
+#include <SkCanvas.h>
+#include <SkSurface.h>
+#include <gl/GrGLInterface.h>
+#include <gl/GrGLTypes.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+CopyResult SkiaOpenGLReadback::copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+        int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) {
+
+    GLuint sourceTexId;
+    glGenTextures(1, &sourceTexId);
+    glBindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);
+
+    sk_sp<GrContext> grContext = sk_ref_sp(mRenderThread.getGrContext());
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+        LOG_ALWAYS_FATAL_IF(!glInterface.get());
+        grContext.reset(GrContext::Create(GrBackend::kOpenGL_GrBackend,
+                (GrBackendContext)glInterface.get()));
+    } else {
+        grContext->resetContext();
+    }
+
+    GrGLTextureInfo externalTexture;
+    externalTexture.fTarget = GL_TEXTURE_EXTERNAL_OES;
+    externalTexture.fID = sourceTexId;
+
+    GrBackendTextureDesc textureDescription;
+    textureDescription.fWidth = imgWidth;
+    textureDescription.fHeight = imgHeight;
+    textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
+    textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
+    textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
+
+    CopyResult copyResult = CopyResult::UnknownError;
+    sk_sp<SkImage> image(SkImage::MakeFromAdoptedTexture(grContext.get(), textureDescription));
+    if (image) {
+        SkAutoLockPixels alp(*bitmap);
+
+        // convert to Skia data structures
+        const SkRect bufferRect = SkRect::MakeIWH(imgWidth, imgHeight);
+        SkRect skiaSrcRect = srcRect.toSkRect();
+        SkMatrix textureMatrix;
+        imgTransform.copyTo(textureMatrix);
+
+        // remove the y-flip applied to the matrix so that we can scale the srcRect.
+        // This flip is not needed as we specify the origin of the texture when we
+        // wrap it as an SkImage.
+        SkMatrix yFlip = SkMatrix::MakeScale(1, -1);
+        yFlip.postTranslate(0,1);
+        textureMatrix.preConcat(yFlip);
+
+        // copy the entire src if the rect is empty
+        if (skiaSrcRect.isEmpty()) {
+            skiaSrcRect = bufferRect;
+        }
+
+        // since the y-flip has been removed we can simply scale & translate
+        // the source rectangle
+        textureMatrix.mapRect(&skiaSrcRect);
+
+        if (skiaSrcRect.intersect(bufferRect)) {
+            SkPoint srcOrigin = SkPoint::Make(skiaSrcRect.fLeft, skiaSrcRect.fTop);
+
+            // if we need to scale the result we must render to an offscreen buffer
+            if (bitmap->width() != skiaSrcRect.width()
+                    || bitmap->height() != skiaSrcRect.height()) {
+                sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
+                        grContext.get(), SkBudgeted::kYes, bitmap->info());
+                SkPaint paint;
+                paint.setBlendMode(SkBlendMode::kSrc);
+                scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
+                        SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
+                image = scaledSurface->makeImageSnapshot();
+                srcOrigin.set(0,0);
+            }
+
+            if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
+                                  srcOrigin.fX, srcOrigin.fY)) {
+                copyResult = CopyResult::Success;
+            }
+        }
+    }
+
+    // make sure that we have deleted the texture (in the SkImage) before we
+    // destroy the EGLImage that it was created from
+    image.reset();
+    return copyResult;
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
new file mode 100644
index 0000000..d914409
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "OpenGLReadback.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaOpenGLReadback : public OpenGLReadback {
+public:
+    SkiaOpenGLReadback(renderthread::RenderThread& thread) : OpenGLReadback(thread) {}
+protected:
+    virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform,
+            int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) override;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index a6612c9..c5a40d4 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -48,9 +48,11 @@
 
 bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
     for (SkImage* image : mutableImages) {
-        mPinnedImages.emplace_back(sk_ref_sp(image));
-        // TODO: return false if texture creation fails (see b/32691999)
-        SkImage_pinAsTexture(image, mRenderThread.getGrContext());
+        if (SkImage_pinAsTexture(image, mRenderThread.getGrContext())) {
+            mPinnedImages.emplace_back(sk_ref_sp(image));
+        } else {
+            return false;
+        }
     }
     return true;
 }
@@ -106,6 +108,7 @@
                 return;
             }
 
+            layerNode->getSkiaLayer()->hasRenderedSinceRepaint = false;
             layerCanvas->clear(SK_ColorTRANSPARENT);
 
             RenderNodeDrawable root(layerNode, layerCanvas, false);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index c322efb..0174b86 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -84,7 +84,7 @@
      * remain in the cache until it has been unpinned. We leverage this feature
      * to avoid making a CPU copy of the pixels.
      *
-     * @return true if the images have been successfully pinned to the GPU cache
+     * @return true if all images have been successfully pinned to the GPU cache
      *         and false otherwise (e.g. cache limits have been exceeded).
      */
     bool pinImages(std::vector<SkImage*>& mutableImages) {
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index afeeef8..177a729 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -20,7 +20,7 @@
 #include "EglManager.h"
 #include "ProfileRenderer.h"
 #include "renderstate/RenderState.h"
-#include "Readback.h"
+#include "OpenGLReadback.h"
 
 #include <android/native_window.h>
 #include <cutils/properties.h>
@@ -117,9 +117,9 @@
 }
 
 bool OpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    ATRACE_CALL();
     layer->apply();
-    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
-            == CopyResult::Success;
+    return OpenGLReadbackImpl::copyLayerInto(mRenderThread, *(layer->backingLayer()), bitmap);
 }
 
 DeferredLayerUpdater* OpenGLPipeline::createTextureLayer() {
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 39e5931..022e871 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -27,6 +27,8 @@
 #include "utils/Macros.h"
 #include "utils/TimeUtils.h"
 
+#include <ui/GraphicBuffer.h>
+
 namespace android {
 namespace uirenderer {
 namespace renderthread {
@@ -602,8 +604,8 @@
 
 CREATE_BRIDGE4(copySurfaceInto, RenderThread* thread,
         Surface* surface, Rect srcRect, SkBitmap* bitmap) {
-    return (void*) Readback::copySurfaceInto(*args->thread,
-            *args->surface, args->srcRect, args->bitmap);
+    return (void*)args->thread->readback().copySurfaceInto(*args->surface,
+            args->srcRect, args->bitmap);
 }
 
 int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top,
@@ -663,6 +665,18 @@
     return hardwareBitmap;
 }
 
+CREATE_BRIDGE3(copyGraphicBufferInto, RenderThread* thread, GraphicBuffer* buffer, SkBitmap* bitmap) {
+    return (void*) args->thread->readback().copyGraphicBufferInto(args->buffer, args->bitmap);
+}
+
+int RenderProxy::copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap) {
+    SETUP_TASK(copyGraphicBufferInto);
+    args->thread = &RenderThread::getInstance();
+    args->bitmap = bitmap;
+    args->buffer = buffer;
+    return static_cast<int>(reinterpret_cast<intptr_t>(staticPostAndWait(task)));
+}
+
 void RenderProxy::post(RenderTask* task) {
     mRenderThread.queue(task);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index e559142..44a5a14 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -35,6 +35,8 @@
 #include "DrawFrameTask.h"
 
 namespace android {
+class GraphicBuffer;
+
 namespace uirenderer {
 
 class DeferredLayerUpdater;
@@ -131,6 +133,8 @@
     ANDROID_API static void prepareToDraw(Bitmap& bitmap);
 
     static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
+
+    static int copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap);
 private:
     RenderThread& mRenderThread;
     CanvasContext* mContext;
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index f3789c8..e13d0ce 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -17,10 +17,13 @@
 #include "RenderThread.h"
 
 #include "../renderstate/RenderState.h"
+#include "../pipeline/skia/SkiaOpenGLReadback.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
+#include "OpenGLReadback.h"
 #include "RenderProxy.h"
 #include "VulkanManager.h"
+#include "utils/FatVector.h"
 
 #include <gui/DisplayEventReceiver.h>
 #include <gui/ISurfaceComposer.h>
@@ -196,6 +199,30 @@
     mVkManager = new VulkanManager(*this);
 }
 
+Readback& RenderThread::readback() {
+
+    if (!mReadback) {
+        auto renderType = Properties::getRenderPipelineType();
+        switch (renderType) {
+            case RenderPipelineType::OpenGL:
+                mReadback = new OpenGLReadbackImpl(*this);
+                break;
+            case RenderPipelineType::SkiaGL:
+            case RenderPipelineType::SkiaVulkan:
+                // It works to use the OpenGL pipeline for Vulkan but this is not
+                // ideal as it causes us to create an OpenGL context in addition
+                // to the Vulkan one.
+                mReadback = new skiapipeline::SkiaOpenGLReadback(*this);
+                break;
+            default:
+                LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+                break;
+        }
+    }
+
+    return *mReadback;
+}
+
 int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
     if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
         ALOGE("Display event receiver pipe was closed or an error occurred.  "
@@ -285,10 +312,18 @@
                 "RenderThread Looper POLL_ERROR!");
 
         nsecs_t nextWakeup;
-        // Process our queue, if we have anything
-        while (RenderTask* task = nextTask(&nextWakeup)) {
-            task->run();
-            // task may have deleted itself, do not reference it again
+        {
+            FatVector<RenderTask*, 10> workQueue;
+            // Process our queue, if we have anything. By first acquiring
+            // all the pending events then processing them we avoid vsync
+            // starvation if more tasks are queued while we are processing tasks.
+            while (RenderTask* task = nextTask(&nextWakeup)) {
+                workQueue.push_back(task);
+            }
+            for (auto task : workQueue) {
+                task->run();
+                // task may have deleted itself, do not reference it again
+            }
         }
         if (nextWakeup == LLONG_MAX) {
             timeoutMillis = -1;
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 12050dd..d121bcf 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -37,6 +37,7 @@
 
 namespace uirenderer {
 
+class Readback;
 class RenderState;
 class TestUtils;
 
@@ -93,6 +94,7 @@
     RenderState& renderState() const { return *mRenderState; }
     EglManager& eglManager() const { return *mEglManager; }
     JankTracker& jankTracker() { return *mJankTracker; }
+    Readback& readback();
 
     const DisplayInfo& mainDisplayInfo() { return mDisplayInfo; }
 
@@ -151,6 +153,7 @@
     EglManager* mEglManager;
 
     JankTracker* mJankTracker = nullptr;
+    Readback* mReadback = nullptr;
 
     sk_sp<GrContext> mGrContext;
     VulkanManager* mVkManager;
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
new file mode 100644
index 0000000..9b0b950
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TestSceneBase.h"
+#include "utils/Color.h"
+#include "tests/common/BitmapAllocationTestUtils.h"
+
+class BitmapShaders;
+
+static bool _BitmapShaders(
+        BitmapAllocationTestUtils::registerBitmapAllocationScene<BitmapShaders>(
+                "bitmapShader", "Draws bitmap shaders with repeat and mirror modes."));
+
+class BitmapShaders : public TestScene {
+public:
+    BitmapShaders(BitmapAllocationTestUtils::BitmapAllocator allocator)
+        : TestScene()
+        , mAllocator(allocator) { }
+
+    sp<RenderNode> card;
+    void createContent(int width, int height, Canvas& canvas) override {
+        canvas.drawColor(Color::Grey_200, SkBlendMode::kSrcOver);
+        sk_sp<Bitmap> hwuiBitmap = mAllocator(200, 200, kRGBA_8888_SkColorType,
+                            [](SkBitmap& skBitmap) {
+            skBitmap.eraseColor(Color::White);
+            SkCanvas skCanvas(skBitmap);
+            SkPaint skPaint;
+            skPaint.setColor(Color::Red_500);
+            skCanvas.drawRect(SkRect::MakeWH(100, 100), skPaint);
+            skPaint.setColor(Color::Blue_500);
+            skCanvas.drawRect(SkRect::MakeXYWH(100, 100, 100, 100), skPaint);
+        });
+
+        SkBitmap bitmap;
+        SkPaint paint;
+        hwuiBitmap->getSkBitmapForShaders(&bitmap);
+
+        sk_sp<SkShader> repeatShader = SkMakeBitmapShader(bitmap,
+                SkShader::TileMode::kRepeat_TileMode,
+                SkShader::TileMode::kRepeat_TileMode,
+                nullptr,
+                kNever_SkCopyPixelsMode,
+                nullptr);
+        paint.setShader(std::move(repeatShader));
+        canvas.drawRoundRect(0, 0, 500, 500, 50.0f, 50.0f, paint);
+
+        sk_sp<SkShader> mirrorShader = SkMakeBitmapShader(bitmap,
+                SkShader::TileMode::kMirror_TileMode,
+                SkShader::TileMode::kMirror_TileMode,
+                nullptr,
+                kNever_SkCopyPixelsMode,
+                nullptr);
+        paint.setShader(std::move(mirrorShader));
+        canvas.drawRoundRect(0, 600, 500, 1100, 50.0f, 50.0f, paint);
+    }
+
+    void doFrame(int frameNr) override { }
+
+    BitmapAllocationTestUtils::BitmapAllocator mAllocator;
+};
\ No newline at end of file
diff --git a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
new file mode 100644
index 0000000..bc6fc64
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TestSceneBase.h"
+
+class ReadbackFromHardware;
+
+static TestScene::Registrar _SaveLayer(TestScene::Info{
+    "readbackFromHBitmap",
+    "Allocates hardware bitmap and readback data from it.",
+    TestScene::simpleCreateScene<ReadbackFromHardware>
+});
+
+class ReadbackFromHardware : public TestScene {
+public:
+    static sk_sp<Bitmap> createHardwareBitmap() {
+        SkBitmap skBitmap;
+        SkImageInfo info = SkImageInfo::Make(400, 400, kN32_SkColorType, kPremul_SkAlphaType);
+        skBitmap.allocPixels(info);
+        skBitmap.eraseColor(Color::Red_500);
+        SkCanvas canvas(skBitmap);
+        SkPaint paint;
+        paint.setColor(Color::Blue_500);
+        canvas.drawRect(SkRect::MakeXYWH(30, 30, 30, 150), paint);
+        canvas.drawRect(SkRect::MakeXYWH(30, 30, 100, 30), paint);
+        canvas.drawRect(SkRect::MakeXYWH(30, 100, 70, 30), paint);
+        return Bitmap::allocateHardwareBitmap(skBitmap);
+    }
+
+    void createContent(int width, int height, Canvas& canvas) override {
+        canvas.drawColor(Color::White, SkBlendMode::kSrcOver); // background
+
+        sk_sp<Bitmap> hardwareBitmap(createHardwareBitmap());
+
+        SkBitmap readback;
+        hardwareBitmap->getSkBitmap(&readback);
+
+        SkBitmap canvasBitmap;
+        sk_sp<Bitmap> heapBitmap(TestUtils::createBitmap(hardwareBitmap->width(),
+                hardwareBitmap->height(), &canvasBitmap));
+
+        SkCanvas skCanvas(canvasBitmap);
+        skCanvas.drawBitmap(readback, 0, 0);
+        canvas.drawBitmap(*heapBitmap, 0, 0, nullptr);
+
+        canvas.drawBitmap(*hardwareBitmap, 0, 500, nullptr);
+    }
+
+    void doFrame(int frameNr) override { }
+};
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index ebc1dd7..1f56222 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -17,6 +17,7 @@
 #include "tests/common/LeakChecker.h"
 #include "tests/common/TestScene.h"
 
+#include "hwui/Typeface.h"
 #include "protos/hwui.pb.h"
 #include "Properties.h"
 
@@ -303,6 +304,8 @@
     // set defaults
     gOpts.count = 150;
 
+    Typeface::setRobotoTypefaceForTest();
+
     parseOptions(argc, argv);
     if (!gBenchmarkReporter && gOpts.renderOffscreen) {
         gBenchmarkReporter.reset(new benchmark::ConsoleReporter());
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index da724a9..bbaf267 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -182,7 +182,7 @@
         canvas->insertReorderBarrier(true);
 
         // Draw child loop
-        for (int i = 0; i < benchState.range_x(); i++) {
+        for (int i = 0; i < benchState.range(0); i++) {
             canvas->drawRenderNode(child.get());
         }
 
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
index d68f5bd..398e7a8 100644
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
@@ -113,7 +113,7 @@
 
 void BM_FrameBuilder_defer_scene(benchmark::State& state) {
     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range_x());
+        const char* sceneName = *(SCENES.begin() + state.range(0));
         state.SetLabel(sceneName);
         auto node = getSyncedSceneNode(sceneName);
         while (state.KeepRunning()) {
@@ -129,7 +129,7 @@
 
 void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
     TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range_x());
+        const char* sceneName = *(SCENES.begin() + state.range(0));
         state.SetLabel(sceneName);
         auto node = getSyncedSceneNode(sceneName);
 
diff --git a/libs/hwui/tests/microbench/main.cpp b/libs/hwui/tests/microbench/main.cpp
index 9771c85..b5abf5b 100644
--- a/libs/hwui/tests/microbench/main.cpp
+++ b/libs/hwui/tests/microbench/main.cpp
@@ -17,6 +17,8 @@
 #include "debug/GlesDriver.h"
 #include "debug/NullGlesDriver.h"
 
+#include "hwui/Typeface.h"
+
 #include <benchmark/benchmark.h>
 
 #include <memory>
@@ -27,6 +29,7 @@
 int main(int argc, char** argv) {
     debug::GlesDriver::replace(std::make_unique<debug::NullGlesDriver>());
     benchmark::Initialize(&argc, argv);
+    Typeface::setRobotoTypefaceForTest();
     benchmark::RunSpecifiedBenchmarks();
     return 0;
 }
diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp
index d05bdbf..cea84c0 100644
--- a/libs/hwui/tests/unit/main.cpp
+++ b/libs/hwui/tests/unit/main.cpp
@@ -20,6 +20,7 @@
 #include "Caches.h"
 #include "debug/GlesDriver.h"
 #include "debug/NullGlesDriver.h"
+#include "hwui/Typeface.h"
 #include "thread/TaskManager.h"
 #include "tests/common/LeakChecker.h"
 
@@ -50,6 +51,13 @@
     raise(sig);
 }
 
+class TypefaceEnvironment : public testing::Environment {
+public:
+    virtual void SetUp() {
+        Typeface::setRobotoTypefaceForTest();
+    }
+};
+
 int main(int argc, char* argv[]) {
     // Register a crash handler
     struct sigaction sa;
@@ -69,6 +77,8 @@
     testing::InitGoogleTest(&argc, argv);
     testing::InitGoogleMock(&argc, argv);
 
+    testing::AddGlobalTestEnvironment(new TypefaceEnvironment());
+
     int ret = RUN_ALL_TESTS();
     test::LeakChecker::checkForLeaks();
     return ret;
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fe1ee02..fa3d8bd 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -553,7 +553,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IMountService")
+IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/storage/IMountServiceListener.cpp b/libs/storage/IMountServiceListener.cpp
index 6a093fd..033d70d 100644
--- a/libs/storage/IMountServiceListener.cpp
+++ b/libs/storage/IMountServiceListener.cpp
@@ -34,7 +34,7 @@
             const String16& /* oldState */, const String16& /* newState */) { }
 };
 
-IMPLEMENT_META_INTERFACE(MountServiceListener, "android.os.storage.IMountServiceListener")
+IMPLEMENT_META_INTERFACE(MountServiceListener, "android.os.storage.IStorageEventListener")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/storage/IMountShutdownObserver.cpp b/libs/storage/IMountShutdownObserver.cpp
index 6114d4a..e5de603 100644
--- a/libs/storage/IMountShutdownObserver.cpp
+++ b/libs/storage/IMountShutdownObserver.cpp
@@ -31,7 +31,7 @@
     virtual void onShutDownComplete(const int32_t /* statusCode */) {}
 };
 
-IMPLEMENT_META_INTERFACE(MountShutdownObserver, "android.os.storage.IMountShutdownObserver")
+IMPLEMENT_META_INTERFACE(MountShutdownObserver, "android.os.storage.IStorageShutdownObserver")
 
 status_t BnMountShutdownObserver::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b5e3af0..43fb4b9 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -1513,9 +1513,9 @@
     }
 
     @Override
-    void playerSetVolume(float leftVolume, float rightVolume) {
-        leftVolume = clampGainOrLevel(leftVolume);
-        rightVolume = clampGainOrLevel(rightVolume);
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        leftVolume = clampGainOrLevel(muting ? 0.0f : leftVolume);
+        rightVolume = clampGainOrLevel(muting ? 0.0f : rightVolume);
 
         native_setVolume(leftVolume, rightVolume);
     }
@@ -2393,8 +2393,8 @@
     }
 
     @Override
-    int playerSetAuxEffectSendLevel(float level) {
-        level = clampGainOrLevel(level);
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        level = clampGainOrLevel(muting ? 0.0f : level);
         int err = native_setAuxEffectSendLevel(level);
         return err == 0 ? SUCCESS : ERROR;
     }
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index d77a082..bbb7184 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2189,9 +2189,9 @@
     /**
      * Loads EXIF attributes from a JPEG input stream.
      *
-     * @param inputStream The input stream that starts with the JPEG data.
+     * @param in The input stream that starts with the JPEG data.
      * @param jpegOffset The offset value in input stream for JPEG data.
-     * @param imageTypes The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
+     * @param imageType The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
      *                   primary image, IFD_TYPE_PREVIEW for preview image, and
      *                   IFD_TYPE_THUMBNAIL for thumbnail image.
      * @throws IOException If the data contains invalid JPEG markers, offsets, or length values.
diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java
index 2348ab7..52a68bf 100644
--- a/media/java/android/media/MediaHTTPService.java
+++ b/media/java/android/media/MediaHTTPService.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.os.IBinder;
+import android.util.Log;
 
 /** @hide */
 public class MediaHTTPService extends IMediaHTTPService.Stub {
@@ -31,10 +32,10 @@
 
     /* package private */static IBinder createHttpServiceBinderIfNecessary(
             String path) {
-        if (path.startsWith("http://")
-                || path.startsWith("https://")
-                || path.startsWith("widevine://")) {
+        if (path.startsWith("http://") || path.startsWith("https://")) {
             return (new MediaHTTPService()).asBinder();
+        } else if (path.startsWith("widevine://")) {
+            Log.d(TAG, "Widevine classic is no longer supported");
         }
 
         return null;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 82cf965..36ad90b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1826,8 +1826,8 @@
     }
 
     @Override
-    void playerSetVolume(float leftVolume, float rightVolume) {
-        _setVolume(leftVolume, rightVolume);
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        _setVolume(muting ? 0.0f : leftVolume, muting ? 0.0f : rightVolume);
     }
 
     private native void _setVolume(float leftVolume, float rightVolume);
@@ -1900,8 +1900,8 @@
     }
 
     @Override
-    int playerSetAuxEffectSendLevel(float level) {
-        _setAuxEffectSendLevel(level);
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        _setAuxEffectSendLevel(muting ? 0.0f : level);
         return AudioSystem.SUCCESS;
     }
 
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index b262d97..690a553 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -39,6 +39,11 @@
  */
 public abstract class PlayerBase {
 
+    private final static String TAG = "PlayerBase";
+    private static IAudioService sService; //lazy initialization, use getService()
+    /** Debug app ops */
+    protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG);
+
     // parameters of the player that affect AppOps
     protected AudioAttributes mAttributes;
     protected float mLeftVolume = 1.0f;
@@ -51,7 +56,6 @@
     private boolean mHasAppOpsPlayAudio = true;
     private final Object mAppOpsLock = new Object();
 
-
     /**
      * Constructor. Must be given audio attributes, as they are required for AppOps.
      * @param attr non-null audio attributes
@@ -101,7 +105,7 @@
     void baseStart() {
         synchronized (mAppOpsLock) {
             if (isRestricted_sync()) {
-                playerSetVolume(0, 0);
+                playerSetVolume(true/*muting*/,0, 0);
             }
         }
     }
@@ -114,7 +118,7 @@
                 return;
             }
         }
-        playerSetVolume(leftVolume, rightVolume);
+        playerSetVolume(false/*muting*/,leftVolume, rightVolume);
     }
 
     int baseSetAuxEffectSendLevel(float level) {
@@ -124,7 +128,7 @@
                 return AudioSystem.SUCCESS;
             }
         }
-        return playerSetAuxEffectSendLevel(level);
+        return playerSetAuxEffectSendLevel(false/*muting*/, level);
     }
 
     /**
@@ -159,11 +163,18 @@
         try {
             if (oldHasAppOpsPlayAudio != mHasAppOpsPlayAudio) {
                 if (mHasAppOpsPlayAudio) {
-                    playerSetVolume(mLeftVolume, mRightVolume);
-                    playerSetAuxEffectSendLevel(mAuxEffectSendLevel);
+                    if (DEBUG_APP_OPS) {
+                        Log.v(TAG, "updateAppOpsPlayAudio: unmuting player, vol=" + mLeftVolume
+                                + "/" + mRightVolume);
+                    }
+                    playerSetVolume(false/*muting*/, mLeftVolume, mRightVolume);
+                    playerSetAuxEffectSendLevel(false/*muting*/, mAuxEffectSendLevel);
                 } else {
-                    playerSetVolume(0.0f, 0.0f);
-                    playerSetAuxEffectSendLevel(0.0f);
+                    if (DEBUG_APP_OPS) {
+                        Log.v(TAG, "updateAppOpsPlayAudio: muting player");
+                    }
+                    playerSetVolume(true/*muting*/, 0.0f, 0.0f);
+                    playerSetAuxEffectSendLevel(true/*muting*/, 0.0f);
                 }
             }
         } catch (Exception e) {
@@ -171,7 +182,6 @@
         }
     }
 
-
     /**
      * To be called by the subclass whenever an operation is potentially restricted.
      * As the media player-common behavior are incorporated into this class, the subclass's need
@@ -189,10 +199,41 @@
         if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
             return false;
         }
+        // check force audibility flag and camera restriction
+        if (((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0)
+                && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)) {
+            boolean cameraSoundForced = false;
+            try {
+                cameraSoundForced = getService().isCameraSoundForced();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Cannot access AudioService in isRestricted_sync()");
+            } catch (NullPointerException e) {
+                Log.e(TAG, "Null AudioService in isRestricted_sync()");
+            }
+            if (cameraSoundForced) {
+                return false;
+            }
+        }
         return true;
     }
 
+    private static IAudioService getService()
+    {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+
     // Abstract methods a subclass needs to implement
-    abstract void playerSetVolume(float leftVolume, float rightVolume);
-    abstract int playerSetAuxEffectSendLevel(float level);
+    /**
+     * Abstract method for the subclass behavior's for volume and muting commands
+     * @param muting if true, the player is to be muted, and the volume values can be ignored
+     * @param leftVolume the left volume to use if muting is false
+     * @param rightVolume the right volume to use if muting is false
+     */
+    abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume);
+    abstract int playerSetAuxEffectSendLevel(boolean muting, float level);
 }
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 9fafda4..b429e22 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -35,9 +35,6 @@
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 
-import com.android.internal.app.IAppOpsCallback;
-import com.android.internal.app.IAppOpsService;
-
 
 /**
  * The SoundPool class manages and plays audio resources for applications.
@@ -111,7 +108,7 @@
  * another level, a new SoundPool is created, sounds are loaded, and play
  * resumes.</p>
  */
-public class SoundPool {
+public class SoundPool extends PlayerBase {
     static { System.loadLibrary("soundpool"); }
 
     // SoundPool messages
@@ -130,10 +127,6 @@
 
     private final Object mLock;
     private final AudioAttributes mAttributes;
-    private final IAppOpsService mAppOps;
-    private final IAppOpsCallback mAppOpsCallback;
-
-    private static IAudioService sService;
 
     /**
      * Constructor. Constructs a SoundPool object with the following
@@ -156,32 +149,14 @@
     }
 
     private SoundPool(int maxStreams, AudioAttributes attributes) {
+        super(attributes);
+
         // do native setup
         if (native_setup(new WeakReference<SoundPool>(this), maxStreams, attributes) != 0) {
             throw new RuntimeException("Native setup failed");
         }
         mLock = new Object();
         mAttributes = attributes;
-        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
-        mAppOps = IAppOpsService.Stub.asInterface(b);
-        // initialize mHasAppOpsPlayAudio
-        updateAppOpsPlayAudio();
-        // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
-        mAppOpsCallback = new IAppOpsCallback.Stub() {
-            public void opChanged(int op, int uid, String packageName) {
-                synchronized (mLock) {
-                    if (op == AppOpsManager.OP_PLAY_AUDIO) {
-                        updateAppOpsPlayAudio();
-                    }
-                }
-            }
-        };
-        try {
-            mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
-                    ActivityThread.currentPackageName(), mAppOpsCallback);
-        } catch (RemoteException e) {
-            mHasAppOpsPlayAudio = false;
-        }
     }
 
     /**
@@ -192,11 +167,7 @@
      * should be set to null.
      */
     public final void release() {
-        try {
-            mAppOps.stopWatchingMode(mAppOpsCallback);
-        } catch (RemoteException e) {
-            // nothing to do here, the SoundPool is being released anyway
-        }
+        baseRelease();
         native_release();
     }
 
@@ -333,9 +304,7 @@
      */
     public final int play(int soundID, float leftVolume, float rightVolume,
             int priority, int loop, float rate) {
-        if (isRestricted()) {
-            leftVolume = rightVolume = 0;
-        }
+        baseStart();
         return _play(soundID, leftVolume, rightVolume, priority, loop, rate);
     }
 
@@ -408,12 +377,26 @@
      * @param rightVolume right volume value (range = 0.0 to 1.0)
      */
     public final void setVolume(int streamID, float leftVolume, float rightVolume) {
-        if (isRestricted()) {
-            return;
-        }
+        // unlike other subclasses of PlayerBase, we are not calling
+        // baseSetVolume(leftVolume, rightVolume) as we need to keep track of each
+        // volume separately for each player, so we still send the command, but
+        // handle mute/unmute separately through playerSetVolume()
         _setVolume(streamID, leftVolume, rightVolume);
     }
 
+
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        // not used here to control the player volume directly, but used to mute/unmute
+        _mute(muting);
+    }
+
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        // no aux send functionality so no-op
+        return AudioSystem.SUCCESS;
+    }
+
     /**
      * Similar, except set volume of all channels to same value.
      * @hide
@@ -494,55 +477,6 @@
         }
     }
 
-    private static IAudioService getService()
-    {
-        if (sService != null) {
-            return sService;
-        }
-        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
-        sService = IAudioService.Stub.asInterface(b);
-        return sService;
-    }
-
-    private boolean isRestricted() {
-        // check app ops
-        if (mHasAppOpsPlayAudio) {
-            return false;
-        }
-        // check bypass flag
-        if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
-            return false;
-        }
-        // check force audibility flag and camera restriction
-        if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0) {
-// FIXME: should also check usage when set properly by camera app
-//          && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-            boolean cameraSoundForced = false;
-            try {
-                cameraSoundForced = getService().isCameraSoundForced();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Cannot access AudioService in isRestricted()");
-            } catch (NullPointerException e) {
-                Log.e(TAG, "Null AudioService in isRestricted()");
-            }
-            if (cameraSoundForced) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private void updateAppOpsPlayAudio() {
-        try {
-            final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
-                    mAttributes.getUsage(),
-                    Process.myUid(), ActivityThread.currentPackageName());
-            mHasAppOpsPlayAudio = (mode == AppOpsManager.MODE_ALLOWED);
-        } catch (RemoteException e) {
-            mHasAppOpsPlayAudio = false;
-        }
-    }
-
     private native final int _load(FileDescriptor fd, long offset, long length, int priority); 
 
     private native final int native_setup(Object weakRef, int maxStreams,
@@ -553,6 +487,8 @@
 
     private native final void _setVolume(int streamID, float leftVolume, float rightVolume);
 
+    private native final void _mute(boolean muting);
+
     // post event from native code to message handler
     @SuppressWarnings("unchecked")
     private static void postEventFromNative(Object ref, int msg, int arg1, int arg2, Object obj) {
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index d2dc440..87092d0 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -60,6 +60,7 @@
     ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels);
 
     mQuit = false;
+    mMuted = false;
     mDecodeThread = 0;
     memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
     mAllocated = 0;
@@ -366,6 +367,19 @@
     }
 }
 
+void SoundPool::mute(bool muting)
+{
+    ALOGV("mute(%d)", muting);
+    Mutex::Autolock lock(&mLock);
+    mMuted = muting;
+    if (!mChannels.empty()) {
+            for (List<SoundChannel*>::iterator iter = mChannels.begin();
+                    iter != mChannels.end(); ++iter) {
+                (*iter)->mute(muting);
+            }
+        }
+}
+
 void SoundPool::autoResume()
 {
     ALOGV("autoResume()");
@@ -1032,7 +1046,7 @@
 {
     mLeftVolume = leftVolume;
     mRightVolume = rightVolume;
-    if (mAudioTrack != NULL)
+    if (mAudioTrack != NULL && !mMuted)
         mAudioTrack->setVolume(leftVolume, rightVolume);
 }
 
@@ -1042,6 +1056,19 @@
     setVolume_l(leftVolume, rightVolume);
 }
 
+void SoundChannel::mute(bool muting)
+{
+    Mutex::Autolock lock(&mLock);
+    mMuted = muting;
+    if (mAudioTrack != NULL) {
+        if (mMuted) {
+            mAudioTrack->setVolume(0.0f, 0.0f);
+        } else {
+            mAudioTrack->setVolume(mLeftVolume, mRightVolume);
+        }
+    }
+}
+
 void SoundChannel::setLoop(int loop)
 {
     Mutex::Autolock lock(&mLock);
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index aff101f..5c48a90 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -114,13 +114,14 @@
 public:
     enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING };
     SoundChannel() : mState(IDLE), mNumChannels(1),
-            mPos(0), mToggle(0), mAutoPaused(false) {}
+            mPos(0), mToggle(0), mAutoPaused(false), mMuted(false) {}
     ~SoundChannel();
     void init(SoundPool* soundPool);
     void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume,
             int priority, int loop, float rate);
     void setVolume_l(float leftVolume, float rightVolume);
     void setVolume(float leftVolume, float rightVolume);
+    void mute(bool muting);
     void stop_l();
     void stop();
     void pause();
@@ -154,6 +155,7 @@
     unsigned long       mToggle;
     bool                mAutoPaused;
     int                 mPrevSampleID;
+    bool                mMuted;
 };
 
 // application object for managing a pool of sounds
@@ -168,6 +170,7 @@
     int play(int sampleID, float leftVolume, float rightVolume, int priority,
             int loop, float rate);
     void pause(int channelID);
+    void mute(bool muting);
     void autoPause();
     void resume(int channelID);
     void autoResume();
@@ -222,6 +225,7 @@
     int                     mNextSampleID;
     int                     mNextChannelID;
     bool                    mQuit;
+    bool                    mMuted;
 
     // callback
     Mutex                   mCallbackLock;
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index ab3e340..9d0c1f8 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -132,6 +132,15 @@
 }
 
 static void
+android_media_SoundPool_mute(JNIEnv *env, jobject thiz, jboolean muting)
+{
+    ALOGV("android_media_SoundPool_mute(%d)", muting);
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->mute(muting == JNI_TRUE);
+}
+
+static void
 android_media_SoundPool_setPriority(JNIEnv *env, jobject thiz, jint channelID,
         jint priority)
 {
@@ -270,6 +279,10 @@
         "(IFF)V",
         (void *)android_media_SoundPool_setVolume
     },
+    {   "_mute",
+        "(Z)V",
+        (void *)android_media_SoundPool_mute
+    },
     {   "setPriority",
         "(II)V",
         (void *)android_media_SoundPool_setPriority
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index aa756ed..3060df2 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -82,7 +82,7 @@
     virtual status_t    stop() { return OK; }
     virtual status_t    pause() { return OK; }
     virtual bool        isPlaying() { return true; }
-    virtual status_t    seekTo(int /* msec */, bool /* precise */) { return OK; }
+    virtual status_t    seekTo(int /* msec */, android::MediaPlayerSeekMode /* mode */) { return OK; }
     virtual status_t    getCurrentPosition(int* /* msec */) { return OK; }
     virtual status_t    getDuration(int* /* msec */) { return OK; }
     virtual status_t    reset() {return OK;}
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-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 295248c..34d236b 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Gepasmaak (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hulp en terugvoer"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Kieslys"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bb50087..d0abbf9 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"ምናሌ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 829123c..0eebcd7 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"القائمة"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index 483770f..c0b776e 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Fərdi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Yardım və rəy"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 5498580a..cbb2271 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml
index f233db9..12f103d 100644
--- a/packages/SettingsLib/res/values-be-rBY/strings.xml
+++ b/packages/SettingsLib/res/values-be-rBY/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index cd77792..23adb5a 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index a011fcf..09988ed 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"মেনু"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index 1df5ec9..561af92 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 92e9005..19382ec 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalitzat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda i suggeriments"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8ec531c..5276b3a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastní (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Nápověda a zpětná vazba"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Nabídka"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index a65c58f..0c56b8d 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tilpasset (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hjælp og feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 923eca1..60f373b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Benutzerdefiniert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hilfe &amp; Feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 3c0247d..032d73d 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Μενού"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8ed7444..57738e8 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Help &amp; feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8ed7444..57738e8 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Help &amp; feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8ed7444..57738e8 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Help &amp; feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index cdfbc01..e0b5bb7 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ayuda y comentarios"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 2a21d22..259e7fb 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ayuda y sugerencias"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 644bf59..7d70efe 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kohandatud (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Abi ja tagasiside"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menüü"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 2217611..952fda8 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pertsonalizatua (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Laguntza eta iritziak"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menua"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 88ed7fa..e998b69 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"منو"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index d26fc05..bf96b59 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Muokattu (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ohje ja palaute"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Valikko"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 58aab1d..e2eb10d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisée (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Aide et commentaires"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 91bbaf0..282ae4a 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisé (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Aide et commentaires"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index b717382..f4bb7ad 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Axuda e suxestións"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 5605189..1cded3d 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"મેનુ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index d579ec4..a2a6e04 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 94229b1..76f04bd 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeno (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Izbornik"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 34f06e5..f5f6916 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egyéni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Súgó és visszajelzés"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index 9428e17..6dcb745 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Ընտրացանկ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index a382e37..07241b5 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"(<xliff:g id="DENSITYDPI">%d</xliff:g>) khusus"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Bantuan &amp; masukan"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 44517a8..8e8307b 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Sérsniðið (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hjálp og ábendingar"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Valmynd"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 7a32827..d894ccf 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizzato (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Guida e feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 2e85770..2ee38ef 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"תפריט"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 00e323c..8b2d784 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -343,4 +343,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"メニュー"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 2b9e8cb..609cb33 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"მენიუ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 0037c11..92d7783 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Mәзір"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 235ea6a..46cc6ce 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"ម៉ឺនុយ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index d7c8d03..cf8f382 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"ಮೆನು"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 21bbc3f..03c0edf 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"메뉴"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index ca716cae..a2eb86d 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 0108c2c..41a8eef 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ປັບແຕ່ງເອງ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"ຊ່ວຍເຫຼືອ &amp; ຄຳຕິຊົມ"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"ເມນູ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 154864f..6930c7a 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tinkintas (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pagalba ir atsiliepimai"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meniu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index df91cb1..7734881 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pielāgots (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Palīdzība un atsauksmes"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Izvēlne"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 42bc33f..711b949 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Мени"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index a6017d5..8bcbf79 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"മെനു"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index cb6327a..4fa3779 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Цэс"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index b6adb4f..20f64fe 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 9886d3e..cf77254 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tersuai (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Bantuan &amp; maklum balas"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index 935ad40..9db8348 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"မီနူး"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 18b6f60..cc4e567 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egendefinert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hjelp og tilbakemelding"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meny"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index 478e19d..a8a918b 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"मेनु"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 3b84313..8bb4579 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Help en feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index b678aac..f19ba3e 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"ਮੀਨੂ"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 77a23f2..4db3e6e 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Niestandardowe (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoc i opinie"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 588ca67..7855beb 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 763cb70..2c366c6 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e comentários"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 588ca67..7855beb 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 6a2122a..5d0b965 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ajutor și feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meniu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 1f192c1..d301ce1 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index e415544..f21793b 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"මෙනුව"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 7e636fe7..b478ecf 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastné (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomocník a spätná väzba"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Ponuka"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 78fa3fd..b9da0eb 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Po meri (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Pomoč in povratne informacije"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index ad4cf61..c17376b 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"I personalizuar (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Ndihma dhe komentet"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menyja"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 02eb615..2cf68a5 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Мени"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index a936c3e..975a4aa 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Anpassad (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Hjälp och feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Meny"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 25f79b6..f14cbdd 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kiwango maalum (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Usaidizi na maoni"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index 9e9e92c..2640122 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"தனிப்பயன் (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"உதவி &amp; கருத்து"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"மெனு"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index 27f8e09..60a4d72 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"సహాయం &amp; అభిప్రాయం"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"మెను"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 6005972..fbb67bc 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"เมนู"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index e9feded..50c43bb 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Tulong at feedback"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 0e73b7b..c5ae71c 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Özel (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Yardım ve geri bildirim"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 1015e1c..b538545 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index 61dc5ab..0b5e8a0 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"مینو"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index a6f9ab8..8d1056a 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Moslashtirilgan (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Yordam va fikr-mulohaza"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index f09e0e5..21e5b75 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tùy chỉnh (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Trợ giúp và phản hồi"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 7268dcd..ba657c6 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"菜单"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index ac9de74..60f56f1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -339,6 +339,8 @@
     <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>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index f17b523..6bb7308 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -341,4 +341,6 @@
     <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="content_description_menu_button" msgid="8182594799812351266">"選單"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 1fc551f..6714b27 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -341,4 +341,6 @@
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ngokwezifiso (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"Usizo nempendulo"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"Imenyu"</string>
+    <!-- no translation found for time_zone_gmt (2587097992671450782) -->
+    <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 972fc73..f176aac 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -863,4 +863,6 @@
     <!-- Content description for drawer menu button [CHAR_LIMIT=30]-->
     <string name="content_description_menu_button">Menu</string>
 
+    <!-- Label for Greenwich mean time, used in a string like GMT+05:00. [CHAR LIMIT=NONE] -->
+    <string name="time_zone_gmt">GMT</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 9608daa..24ede16 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -116,6 +116,10 @@
         List<BluetoothDevice> sinks = getConnectedDevices();
         if (sinks != null) {
             for (BluetoothDevice sink : sinks) {
+                if (sink.equals(device)) {
+                    Log.w(TAG, "Connecting to device " + device + " : disconnect skipped");
+                    continue;
+                }
                 mService.disconnect(sink);
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index 857ca49..4bfca9b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -19,9 +19,13 @@
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.icu.text.TimeZoneNames;
-import android.text.BidiFormatter;
-import android.text.TextDirectionHeuristics;
+import android.support.v4.text.BidiFormatter;
+import android.support.v4.text.TextDirectionHeuristicsCompat;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.text.style.TtsSpan;
 import android.util.Log;
 import android.view.View;
 
@@ -29,7 +33,6 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -65,28 +68,41 @@
     private static final String TAG = "ZoneGetter";
 
     public static final String KEY_ID = "id";  // value: String
+
+    /**
+     * @deprecated Use {@link #KEY_DISPLAY_LABEL} instead.
+     */
+    @Deprecated
     public static final String KEY_DISPLAYNAME = "name";  // value: String
+
+    public static final String KEY_DISPLAY_LABEL = "display_label"; // value: CharSequence
+
+    /**
+     * @deprecated Use {@link #KEY_OFFSET_LABEL} instead.
+     */
+    @Deprecated
     public static final String KEY_GMT = "gmt";  // value: String
     public static final String KEY_OFFSET = "offset";  // value: int (Integer)
+    public static final String KEY_OFFSET_LABEL = "offset_label";  // value: CharSequence
 
     private static final String XMLTAG_TIMEZONE = "timezone";
 
-    public static String getTimeZoneOffsetAndName(Context context, TimeZone tz, Date now) {
+    public static CharSequence getTimeZoneOffsetAndName(Context context, TimeZone tz, Date now) {
         final Locale locale = Locale.getDefault();
-        final String gmtString = getGmtOffsetString(locale, tz, now);
+        final CharSequence gmtText = getGmtOffsetText(context, locale, tz, now);
         final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
         final ZoneGetterData data = new ZoneGetterData(context);
 
         final boolean useExemplarLocationForLocalNames =
                 shouldUseExemplarLocationForLocalNames(data, timeZoneNames);
-        final String zoneNameString = getTimeZoneDisplayName(data, timeZoneNames,
+        final CharSequence zoneName = getTimeZoneDisplayName(data, timeZoneNames,
                 useExemplarLocationForLocalNames, tz, tz.getID());
-        if (zoneNameString == null) {
-            return gmtString;
+        if (zoneName == null) {
+            return gmtText;
         }
 
         // We don't use punctuation here to avoid having to worry about localizing that too!
-        return gmtString + " " + zoneNameString;
+        return TextUtils.concat(gmtText, " ", zoneName);
     }
 
     public static List<Map<String, Object>> getZonesList(Context context) {
@@ -103,28 +119,30 @@
         List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>();
         for (int i = 0; i < data.zoneCount; i++) {
             TimeZone tz = data.timeZones[i];
-            String gmtOffsetString = data.gmtOffsetStrings[i];
+            CharSequence gmtOffsetText = data.gmtOffsetTexts[i];
 
-            String displayName = getTimeZoneDisplayName(data, timeZoneNames,
+            CharSequence displayName = getTimeZoneDisplayName(data, timeZoneNames,
                     useExemplarLocationForLocalNames, tz, data.olsonIdsToDisplay[i]);
-            if (displayName == null  || displayName.isEmpty()) {
-                displayName = gmtOffsetString;
+            if (TextUtils.isEmpty(displayName)) {
+                displayName = gmtOffsetText;
             }
 
             int offsetMillis = tz.getOffset(now.getTime());
             Map<String, Object> displayEntry =
-                    createDisplayEntry(tz, gmtOffsetString, displayName, offsetMillis);
+                    createDisplayEntry(tz, gmtOffsetText, displayName, offsetMillis);
             zones.add(displayEntry);
         }
         return zones;
     }
 
     private static Map<String, Object> createDisplayEntry(
-            TimeZone tz, String gmtOffsetString, String displayName, int offsetMillis) {
-        Map<String, Object> map = new HashMap<String, Object>();
+            TimeZone tz, CharSequence gmtOffsetText, CharSequence displayName, int offsetMillis) {
+        Map<String, Object> map = new HashMap<>();
         map.put(KEY_ID, tz.getID());
-        map.put(KEY_DISPLAYNAME, displayName);
-        map.put(KEY_GMT, gmtOffsetString);
+        map.put(KEY_DISPLAYNAME, displayName.toString());
+        map.put(KEY_DISPLAY_LABEL, displayName);
+        map.put(KEY_GMT, gmtOffsetText.toString());
+        map.put(KEY_OFFSET_LABEL, gmtOffsetText);
         map.put(KEY_OFFSET, offsetMillis);
         return map;
     }
@@ -162,15 +180,15 @@
 
     private static boolean shouldUseExemplarLocationForLocalNames(ZoneGetterData data,
             TimeZoneNames timeZoneNames) {
-        final Set<String> localZoneNames = new HashSet<String>();
+        final Set<CharSequence> localZoneNames = new HashSet<>();
         final Date now = new Date();
         for (int i = 0; i < data.zoneCount; i++) {
             final String olsonId = data.olsonIdsToDisplay[i];
             if (data.localZoneIds.contains(olsonId)) {
                 final TimeZone tz = data.timeZones[i];
-                String displayName = getZoneLongName(timeZoneNames, tz, now);
+                CharSequence displayName = getZoneLongName(timeZoneNames, tz, now);
                 if (displayName == null) {
-                    displayName = data.gmtOffsetStrings[i];
+                    displayName = data.gmtOffsetTexts[i];
                 }
                 final boolean nameIsUnique = localZoneNames.add(displayName);
                 if (!nameIsUnique) {
@@ -182,8 +200,9 @@
         return false;
     }
 
-    private static String getTimeZoneDisplayName(ZoneGetterData data, TimeZoneNames timeZoneNames,
-            boolean useExemplarLocationForLocalNames, TimeZone tz, String olsonId) {
+    private static CharSequence getTimeZoneDisplayName(ZoneGetterData data,
+            TimeZoneNames timeZoneNames, boolean useExemplarLocationForLocalNames, TimeZone tz,
+            String olsonId) {
         final Date now = new Date();
         final boolean isLocalZoneId = data.localZoneIds.contains(olsonId);
         final boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames;
@@ -213,23 +232,70 @@
         return names.getDisplayName(tz.getID(), nameType, now.getTime());
     }
 
-    private static String getGmtOffsetString(Locale locale, TimeZone tz, Date now) {
-        // Use SimpleDateFormat to format the GMT+00:00 string.
-        final SimpleDateFormat gmtFormatter = new SimpleDateFormat("ZZZZ");
-        gmtFormatter.setTimeZone(tz);
-        String gmtString = gmtFormatter.format(now);
+    private static void appendWithTtsSpan(SpannableStringBuilder builder, CharSequence content,
+            TtsSpan span) {
+        int start = builder.length();
+        builder.append(content);
+        builder.setSpan(span, start, builder.length(), 0);
+    }
+
+    private static String twoDigits(int input) {
+        StringBuilder builder = new StringBuilder(3);
+        if (input < 0) builder.append('-');
+        String string = Integer.toString(Math.abs(input));
+        if (string.length() == 1) builder.append("0");
+        builder.append(string);
+        return builder.toString();
+    }
+
+    /**
+     * Get the GMT offset text label for the given time zone, in the format "GMT-08:00". This will
+     * also add TTS spans to give hints to the text-to-speech engine for the type of data it is.
+     *
+     * @param context The context which the string is displayed in.
+     * @param locale The locale which the string is displayed in. This should be the same as the
+     *               locale of the context.
+     * @param tz Time zone to get the GMT offset from.
+     * @param now The current time, used to tell whether daylight savings is active.
+     * @return A CharSequence suitable for display as the offset label of {@code tz}.
+     */
+    private static CharSequence getGmtOffsetText(Context context, Locale locale, TimeZone tz,
+            Date now) {
+        SpannableStringBuilder builder = new SpannableStringBuilder();
+
+        appendWithTtsSpan(builder, "GMT",
+                new TtsSpan.TextBuilder(context.getString(R.string.time_zone_gmt)).build());
+
+        int offsetMillis = tz.getOffset(now.getTime());
+        if (offsetMillis >= 0) {
+            appendWithTtsSpan(builder, "+", new TtsSpan.VerbatimBuilder("+").build());
+        }
+
+        final int offsetHours = (int) (offsetMillis / DateUtils.HOUR_IN_MILLIS);
+        appendWithTtsSpan(builder, twoDigits(offsetHours),
+                new TtsSpan.MeasureBuilder().setNumber(offsetHours).setUnit("hour").build());
+
+        builder.append(":");
+
+        final int offsetMinutes = (int) (offsetMillis / DateUtils.MINUTE_IN_MILLIS);
+        final int offsetMinutesRemaining = Math.abs(offsetMinutes) % 60;
+        appendWithTtsSpan(builder, twoDigits(offsetMinutesRemaining),
+                new TtsSpan.MeasureBuilder().setNumber(offsetMinutesRemaining)
+                        .setUnit("minute").build());
+
+        CharSequence gmtText = new SpannableString(builder);
 
         // Ensure that the "GMT+" stays with the "00:00" even if the digits are RTL.
         final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
         boolean isRtl = TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL;
-        gmtString = bidiFormatter.unicodeWrap(gmtString,
-                isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR);
-        return gmtString;
+        gmtText = bidiFormatter.unicodeWrap(gmtText,
+                isRtl ? TextDirectionHeuristicsCompat.RTL : TextDirectionHeuristicsCompat.LTR);
+        return gmtText;
     }
 
     private static final class ZoneGetterData {
         public final String[] olsonIdsToDisplay;
-        public final String[] gmtOffsetStrings;
+        public final CharSequence[] gmtOffsetTexts;
         public final TimeZone[] timeZones;
         public final Set<String> localZoneIds;
         public final int zoneCount;
@@ -243,13 +309,13 @@
             zoneCount = olsonIdsToDisplayList.size();
             olsonIdsToDisplay = new String[zoneCount];
             timeZones = new TimeZone[zoneCount];
-            gmtOffsetStrings = new String[zoneCount];
+            gmtOffsetTexts = new CharSequence[zoneCount];
             for (int i = 0; i < zoneCount; i++) {
                 final String olsonId = olsonIdsToDisplayList.get(i);
                 olsonIdsToDisplay[i] = olsonId;
                 final TimeZone tz = TimeZone.getTimeZone(olsonId);
                 timeZones[i] = tz;
-                gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now);
+                gmtOffsetTexts[i] = getGmtOffsetText(context, locale, tz, now);
             }
 
             // Create a lookup of local zone IDs.
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index e07856e..7e3f67b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -39,6 +39,8 @@
     public static final String CATEGORY_SYSTEM_INPUT = "com.android.settings.category.ia.input";
     public static final String CATEGORY_SYSTEM_LANGUAGE =
             "com.android.settings.category.ia.language";
+    public static final String CATEGORY_SYSTEM_DEVELOPMENT =
+            "com.android.settings.category.ia.development";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index ed411be..f3658c3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -18,19 +18,24 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.settingslib.applications.InterestingConfigChanges;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import static java.lang.String.CASE_INSENSITIVE_ORDER;
+
 public class CategoryManager {
 
     private static final String TAG = "CategoryManager";
@@ -111,6 +116,8 @@
                 mCategoryByKeyMap.put(category.key, category);
             }
             backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+            normalizePriority(context, mCategoryByKeyMap);
+            filterDuplicateTiles(mCategoryByKeyMap);
         }
     }
 
@@ -163,4 +170,81 @@
             }
         }
     }
+
+    /**
+     * Normalize priority values on tiles across injected from all apps to make sure they don't set
+     * the same priority value. However internal tiles' priority remains unchanged.
+     * <p/>
+     * A list of tiles are considered normalized when their priority value increases in a linear
+     * scan.
+     */
+    @VisibleForTesting
+    synchronized void normalizePriority(Context context,
+            Map<String, DashboardCategory> categoryByKeyMap) {
+        for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+            normalizePriorityForExternalTiles(context, categoryEntry.getValue());
+        }
+    }
+
+    /**
+     * Filter out duplicate tiles from category. Duplicate tiles are the ones pointing to the
+     * same intent.
+     */
+    @VisibleForTesting
+    synchronized void filterDuplicateTiles(Map<String, DashboardCategory> categoryByKeyMap) {
+        for (Entry<String, DashboardCategory> categoryEntry : categoryByKeyMap.entrySet()) {
+            final DashboardCategory category = categoryEntry.getValue();
+            final int count = category.tiles.size();
+            final Set<ComponentName> components = new ArraySet<>();
+            for (int i = count - 1; i >= 0; i--) {
+                final Tile tile = category.tiles.get(i);
+                if (tile.intent == null) {
+                    continue;
+                }
+                final ComponentName tileComponent = tile.intent.getComponent();
+                if (components.contains(tileComponent)) {
+                    category.tiles.remove(i);
+                } else {
+                    components.add(tileComponent);
+                }
+            }
+        }
+    }
+
+    /**
+     * Normalize priority value for tiles within a single {@code DashboardCategory}.
+     *
+     * @see #normalizePriority(Context, Map)
+     */
+    private synchronized void normalizePriorityForExternalTiles(Context context,
+            DashboardCategory dashboardCategory) {
+        final String skipPackageName = context.getPackageName();
+
+        // Sort tiles based on [package, priority within package]
+        Collections.sort(dashboardCategory.tiles, (tile1, tile2) -> {
+            final String package1 = tile1.intent.getComponent().getPackageName();
+            final String package2 = tile2.intent.getComponent().getPackageName();
+            final int packageCompare = CASE_INSENSITIVE_ORDER.compare(package1, package2);
+            // First sort by package name
+            if (packageCompare != 0) {
+                return packageCompare;
+            } else if (TextUtils.equals(package1, skipPackageName)) {
+                return 0;
+            }
+            // Then sort by priority
+            return tile1.priority - tile2.priority;
+        });
+        // Update priority for all items so no package define the same priority value.
+        final int count = dashboardCategory.tiles.size();
+        for (int i = 0; i < count; i++) {
+            final String packageName =
+                    dashboardCategory.tiles.get(i).intent.getComponent().getPackageName();
+            if (TextUtils.equals(packageName, skipPackageName)) {
+                // We skip this tile because it's a intent pointing to our own app. We trust the
+                // priority is set correctly, so don't normalize.
+                continue;
+            }
+            dashboardCategory.tiles.get(i).priority = i;
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
index 57e06dd..703e9d2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
@@ -19,6 +19,9 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.filters.SmallTest;
+import android.text.Spanned;
+import android.text.style.TtsSpan;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -55,14 +58,41 @@
         testTimeZoneOffsetAndNameInner(TIME_ZONE_LA_ID, "Pacific Daylight Time");
     }
 
+    @Test
+    public void getZonesList_checkTypes() {
+        final List<Map<String, Object>> zones =
+                ZoneGetter.getZonesList(InstrumentationRegistry.getContext());
+        for (Map<String, Object> zone : zones) {
+            assertTrue(zone.get(ZoneGetter.KEY_DISPLAYNAME) instanceof String);
+            assertTrue(zone.get(ZoneGetter.KEY_DISPLAY_LABEL) instanceof CharSequence);
+            assertTrue(zone.get(ZoneGetter.KEY_OFFSET) instanceof Integer);
+            assertTrue(zone.get(ZoneGetter.KEY_OFFSET_LABEL) instanceof CharSequence);
+            assertTrue(zone.get(ZoneGetter.KEY_ID) instanceof String);
+            assertTrue(zone.get(ZoneGetter.KEY_GMT) instanceof String);
+        }
+    }
+
+    @Test
+    public void getTimeZoneOffsetAndName_withTtsSpan() {
+        final Context context = InstrumentationRegistry.getContext();
+        final TimeZone timeZone = TimeZone.getTimeZone(TIME_ZONE_LA_ID);
+
+        CharSequence timeZoneString = ZoneGetter.getTimeZoneOffsetAndName(context, timeZone,
+                mCalendar.getTime());
+        assertTrue("Time zone string should be spanned", timeZoneString instanceof Spanned);
+        assertTrue("Time zone display name should have TTS spans",
+                ((Spanned) timeZoneString).getSpans(
+                    0, timeZoneString.length(), TtsSpan.class).length > 0);
+    }
+
     private void testTimeZoneOffsetAndNameInner(String timeZoneId, String expectedName) {
         final Context context = InstrumentationRegistry.getContext();
         final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
 
-        String timeZoneString = ZoneGetter.getTimeZoneOffsetAndName(context, timeZone,
+        CharSequence timeZoneString = ZoneGetter.getTimeZoneOffsetAndName(context, timeZone,
                 mCalendar.getTime());
 
-        assertTrue(timeZoneString.endsWith(expectedName));
+        assertTrue(timeZoneString.toString().endsWith(expectedName));
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index a0254cd..b209f4e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -58,9 +58,10 @@
         allKeys.add(CategoryKey.CATEGORY_SYSTEM);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_INPUT);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
+        allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
         // DO NOT REMOVE ANYTHING ABOVE
 
-        assertThat(allKeys.size()).isEqualTo(13);
+        assertThat(allKeys.size()).isEqualTo(14);
     }
 
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
index 380f622..573ec1f0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
@@ -16,7 +16,9 @@
 
 package com.android.settingslib.drawer;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.util.Pair;
 
 import com.android.settingslib.TestConfig;
@@ -116,4 +118,170 @@
         // Old category still exists.
         assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1);
     }
+
+    @Test
+    public void normalizePriority_singlePackage_shouldReorderBasedOnPriority() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage = "com.android.test";
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 50;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 200;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify they are now sorted.
+        assertThat(category.tiles.get(0)).isSameAs(tile2);
+        assertThat(category.tiles.get(1)).isSameAs(tile1);
+        assertThat(category.tiles.get(2)).isSameAs(tile3);
+        // Verify their priority is normalized
+        assertThat(category.tiles.get(0).priority).isEqualTo(0);
+        assertThat(category.tiles.get(1).priority).isEqualTo(1);
+        assertThat(category.tiles.get(2).priority).isEqualTo(2);
+    }
+
+    @Test
+    public void normalizePriority_multiPackage_shouldReorderBasedOnPackageAndPriority() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage1 = "com.android.test1";
+        final String testPackage2 = "com.android.test2";
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage2, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage1, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage1, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify they are now sorted.
+        assertThat(category.tiles.get(0)).isSameAs(tile3);
+        assertThat(category.tiles.get(1)).isSameAs(tile2);
+        assertThat(category.tiles.get(2)).isSameAs(tile1);
+        // Verify their priority is normalized
+        assertThat(category.tiles.get(0).priority).isEqualTo(0);
+        assertThat(category.tiles.get(1).priority).isEqualTo(1);
+        assertThat(category.tiles.get(2).priority).isEqualTo(2);
+    }
+
+    @Test
+    public void normalizePriority_internalPackageTiles_shouldSkipTileForInternalPackage() {
+        // Create some fake tiles that are not sorted.
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        // Normalize their priorities
+        mCategoryManager.normalizePriority(ShadowApplication.getInstance().getApplicationContext(),
+                mCategoryByKeyMap);
+
+        // Verify the sorting order is not changed
+        assertThat(category.tiles.get(0)).isSameAs(tile1);
+        assertThat(category.tiles.get(1)).isSameAs(tile2);
+        assertThat(category.tiles.get(2)).isSameAs(tile3);
+        // Verify their priorities are not changed.
+        assertThat(category.tiles.get(0).priority).isEqualTo(100);
+        assertThat(category.tiles.get(1).priority).isEqualTo(100);
+        assertThat(category.tiles.get(2).priority).isEqualTo(50);
+    }
+
+    @Test
+    public void filterTiles_noDuplicate_noChange() {
+        // Create some unique tiles
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class2"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class3"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+        assertThat(category.tiles.size()).isEqualTo(3);
+    }
+
+    @Test
+    public void filterTiles_hasDuplicate_shouldOnlyKeepUniqueTiles() {
+        // Create tiles pointing to same intent.
+        final String testPackage =
+                ShadowApplication.getInstance().getApplicationContext().getPackageName();
+        final DashboardCategory category = new DashboardCategory();
+        final Tile tile1 = new Tile();
+        tile1.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile1.priority = 100;
+        final Tile tile2 = new Tile();
+        tile2.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile2.priority = 100;
+        final Tile tile3 = new Tile();
+        tile3.intent =
+                new Intent().setComponent(new ComponentName(testPackage, "class1"));
+        tile3.priority = 50;
+        category.tiles.add(tile1);
+        category.tiles.add(tile2);
+        category.tiles.add(tile3);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_HOMEPAGE, category);
+
+        mCategoryManager.filterDuplicateTiles(mCategoryByKeyMap);
+
+        assertThat(category.tiles.size()).isEqualTo(1);
+    }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index dd543a3..d784a3a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -645,7 +645,7 @@
 
         if (upgradeVersion == 45) {
              /*
-              * New settings for MountService
+              * New settings for StorageManagerService
               */
             db.beginTransaction();
             try {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index bf48e5d..1c51773 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.providers.settings;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.backup.IBackupManager;
 import android.content.ContentResolver;
@@ -343,7 +343,7 @@
         if (loc == null) return; // Couldn't find the saved locale in this version of the software
 
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             Configuration config = am.getConfiguration();
             config.locale = loc;
             // indicate this isn't some passing default - the user wants this remembered
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
index 169b01f..461573f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -16,7 +16,7 @@
 
 package com.android.providers.settings;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.IContentProvider;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
@@ -190,7 +190,7 @@
 
             if (mUser == UserHandle.USER_CURRENT) {
                 try {
-                    mUser = ActivityManagerNative.getDefault().getCurrentUser().id;
+                    mUser = ActivityManager.getService().getCurrentUser().id;
                 } catch (RemoteException e) {
                     throw new RuntimeException("Failed in IPC", e);
                 }
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index f6e558f..15ce90f 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -40,8 +40,7 @@
     private static final String TAG = "BugreportReceiver";
 
     /**
-     * Always keep the newest 8 bugreport files; 4 reports and 4 screenshots are
-     * roughly 17MB of disk space.
+     * Always keep the newest 8 bugreport files.
      */
     private static final int MIN_KEEP_COUNT = 8;
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java
new file mode 100644
index 0000000..688df46
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java
@@ -0,0 +1,100 @@
+/*
+ * 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.systemui.plugins.doze;
+
+import android.app.PendingIntent;
+import android.content.Context;
+
+import com.android.systemui.plugins.Plugin;
+
+/**
+ * Provides a {@link DozeUi}.
+ */
+public interface DozeProvider extends Plugin {
+
+    String ACTION = "com.android.systemui.action.PLUGIN_DOZE";
+    int VERSION = 1;
+
+    /**
+     * Caution: Even if this is called, the DozeUi provided may still be in use until it transitions
+     * to DozeState.FINISH
+     */
+    @Override
+    default void onDestroy() {
+    }
+
+    /**
+     * @return the plugin's implementation of DozeUi.
+     */
+    DozeUi provideDozeUi(Context context, DozeMachine machine, WakeLock wakeLock);
+
+    /**
+     * If true, the plugin allows the default pulse triggers to fire, otherwise they are disabled.
+     */
+    default boolean allowDefaultPulseTriggers() {
+        return false;
+    }
+
+    /**
+     * Ui for use in DozeMachine.
+     */
+    interface DozeUi {
+        /** Called whenever the DozeMachine state transitions */
+        void transitionTo(DozeState oldState, DozeState newState);
+    }
+
+    /** WakeLock wrapper for testability */
+    interface WakeLock {
+        /** @see android.os.PowerManager.WakeLock#acquire() */
+        void acquire();
+        /** @see android.os.PowerManager.WakeLock#release() */
+        void release();
+        /** @see android.os.PowerManager.WakeLock#wrap(Runnable) */
+        Runnable wrap(Runnable r);
+    }
+
+    /** Plugin version of the DozeMachine's state */
+    enum DozeState {
+        /** Default state. Transition to INITIALIZED to get Doze going. */
+        UNINITIALIZED,
+        /** Doze components are set up. Followed by transition to DOZE or DOZE_AOD. */
+        INITIALIZED,
+        /** Regular doze. Device is asleep and listening for pulse triggers. */
+        DOZE,
+        /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */
+        DOZE_AOD,
+        /** Pulse has been requested. Device is awake and preparing UI */
+        DOZE_REQUEST_PULSE,
+        /** Pulse is showing. Device is awake and showing UI. */
+        DOZE_PULSING,
+        /** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */
+        DOZE_PULSE_DONE,
+        /** Doze is done. DozeService is finished. */
+        FINISH,
+        /** WakeUp. */
+        WAKE_UP,
+    }
+
+    /** Plugin interface for the doze machine. */
+    interface DozeMachine {
+        /** Request that the DozeMachine transitions to {@code state} */
+        void requestState(DozeState state);
+
+        /** Request that the PendingIntent is sent. */
+        void requestSendIntent(PendingIntent intent);
+    }
+}
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-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 502a94e..a1a8f8d 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -198,13 +198,13 @@
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"تشغيل وضع الطائرة."</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"تم إيقاف وضع الطائرة."</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"تم تشغيل وضع الطائرة."</string>
-    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"تم تشغيل الرجاء عدم الإزعاج، الأولوية فقط."</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"تم تشغيل الرجاء عدم الإزعاج، كتم الصوت تمامًا."</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"تم تشغيل الرجاء عدم الإزعاج، التنبيهات فقط."</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"تم تشغيل \"عدم الإزعاج، الأولوية فقط\"."</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"تم تشغيل \"عدم الإزعاج، كتم الصوت تمامًا\"."</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"تم تشغيل \"عدم الإزعاج، التنبيهات فقط\"."</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"الرجاء عدم الإزعاج."</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"تم تعطيل \"الرجاء عدم الإزعاج\"."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"تم تعطيل \"الرجاء عدم الإزعاج\"."</string>
-    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"تم تشغيل \"الرجاء عدم الإزعاج\"."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"تم تشغيل \"عدم الإزعاج\"."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"البلوتوث."</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"إيقاف البلوتوث."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"تشغيل البلوتوث."</string>
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-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f482caaa..97f3926 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -342,7 +342,7 @@
     <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, ईवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, इवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string>
     <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्‍वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 8217ee5..29f8875 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -164,8 +164,8 @@
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Melding wissen"</string>
-    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ingeschakeld."</string>
-    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met GPS."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"gps ingeschakeld."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met gps."</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ingeschakeld."</string>
     <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Belsoftware trilt."</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Belsoftware stil."</string>
@@ -241,8 +241,8 @@
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Hervatten"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Verbonden via wifi"</string>
-    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar GPS"</string>
-    <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar gps"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met gps"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Locatieverzoeken actief"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
     <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
@@ -376,7 +376,7 @@
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Verwijderen"</string>
     <string name="guest_wipe_session_title" msgid="6419439912885956132">"Welkom terug, gast!"</string>
-    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wilt u doorgaan met je sessie?"</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wil je doorgaan met je sessie?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Opnieuw starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, doorgaan"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"Gastgebruiker"</string>
diff --git a/packages/SystemUI/res/values-pl/strings_car.xml b/packages/SystemUI/res/values-pl/strings_car.xml
index d6e02d6..dbb0373 100644
--- a/packages/SystemUI/res/values-pl/strings_car.xml
+++ b/packages/SystemUI/res/values-pl/strings_car.xml
@@ -20,5 +20,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jedź bezpiecznie"</string>
-    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Android Auto."</string>
+    <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Androida Auto."</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/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 6802fd7..b207984 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import com.android.systemui.doze.DozeFactory;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyboard.KeyboardUI;
 import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -76,7 +77,8 @@
             PipUI.class,
             ShortcutKeyDispatcher.class,
             VendorServices.class,
-            LatencyTester.class
+            LatencyTester.class,
+            DozeFactory.Initializer.class,
     };
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 4cfc811..5b10756 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -17,19 +17,52 @@
 package com.android.systemui.doze;
 
 import android.app.Application;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.hardware.SensorManager;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.os.SystemClock;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+import com.android.systemui.plugins.doze.DozeProvider;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
 public class DozeFactory {
 
+    private static DozeFactory sInstance;
+
+    private DozeProvider mDozePlugin;
+
+    /** Returns the singleton instance. */
+    public static DozeFactory getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new DozeFactory();
+            PluginManager.getInstance(context).addPluginListener(DozeProvider.ACTION,
+                    new PluginListener<DozeProvider>() {
+                        @Override
+                        public void onPluginConnected(DozeProvider plugin) {
+                            sInstance.mDozePlugin = plugin;
+                        }
+
+                        @Override
+                        public void onPluginDisconnected(DozeProvider plugin) {
+                            if (sInstance.mDozePlugin == plugin) {
+                                sInstance.mDozePlugin = null;
+                            }
+                        }
+                    },
+                    DozeProvider.VERSION, false /* Only one */);
+        }
+        return sInstance;
+    }
+
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
-    public static DozeMachine assembleMachine(DozeService dozeService) {
+    public DozeMachine assembleMachine(DozeService dozeService) {
         Context context = dozeService;
         SensorManager sensorManager = context.getSystemService(SensorManager.class);
         PowerManager powerManager = context.getSystemService(PowerManager.class);
@@ -43,14 +76,103 @@
 
         DozeMachine machine = new DozeMachine(dozeService, params, wakeLock);
         machine.setParts(new DozeMachine.Part[]{
-                new DozeTriggers(context, machine, host, config, params,
-                        sensorManager, handler, wakeLock),
-                new DozeUi(context, machine, wakeLock, host),
+                createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
+                        machine),
+                createDozeUi(context, host, wakeLock, machine),
         });
 
         return machine;
     }
 
+    private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
+            DozeHost host, AmbientDisplayConfiguration config, DozeParameters params,
+            Handler handler, WakeLock wakeLock, DozeMachine machine) {
+        boolean allowPulseTriggers = mDozePlugin == null || mDozePlugin.allowDefaultPulseTriggers();
+        return new DozeTriggers(context, machine, host, config, params,
+                sensorManager, handler, wakeLock, allowPulseTriggers);
+    }
+
+    private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
+            DozeMachine machine) {
+        if (mDozePlugin != null) {
+            DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context,
+                    pluginMachine(context, machine, host),
+                    wakeLock);
+            return (oldState, newState) -> {
+                dozeUi.transitionTo(pluginState(oldState),
+                        pluginState(newState));
+            };
+        } else {
+            return new DozeUi(context, machine, wakeLock, host);
+        }
+    }
+
+    private DozeProvider.DozeMachine pluginMachine(Context context, DozeMachine machine,
+            DozeHost host) {
+        return new DozeProvider.DozeMachine() {
+            @Override
+            public void requestState(DozeProvider.DozeState state) {
+                if (state == DozeProvider.DozeState.WAKE_UP) {
+                    PowerManager pm = context.getSystemService(PowerManager.class);
+                    pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+                    return;
+                }
+                machine.requestState(implState(state));
+            }
+
+            @Override
+            public void requestSendIntent(PendingIntent intent) {
+                host.startPendingIntentDismissingKeyguard(intent);
+            }
+        };
+    }
+
+    private DozeMachine.State implState(DozeProvider.DozeState s) {
+        switch (s) {
+            case UNINITIALIZED:
+                return DozeMachine.State.UNINITIALIZED;
+            case INITIALIZED:
+                return DozeMachine.State.INITIALIZED;
+            case DOZE:
+                return DozeMachine.State.DOZE;
+            case DOZE_AOD:
+                return DozeMachine.State.DOZE_AOD;
+            case DOZE_REQUEST_PULSE:
+                return DozeMachine.State.DOZE_REQUEST_PULSE;
+            case DOZE_PULSING:
+                return DozeMachine.State.DOZE_PULSING;
+            case DOZE_PULSE_DONE:
+                return DozeMachine.State.DOZE_PULSE_DONE;
+            case FINISH:
+                return DozeMachine.State.FINISH;
+            default:
+                throw new IllegalArgumentException("Unknown state: " + s);
+        }
+    }
+
+    private DozeProvider.DozeState pluginState(DozeMachine.State s) {
+        switch (s) {
+            case UNINITIALIZED:
+                return DozeProvider.DozeState.UNINITIALIZED;
+            case INITIALIZED:
+                return DozeProvider.DozeState.INITIALIZED;
+            case DOZE:
+                return DozeProvider.DozeState.DOZE;
+            case DOZE_AOD:
+                return DozeProvider.DozeState.DOZE_AOD;
+            case DOZE_REQUEST_PULSE:
+                return DozeProvider.DozeState.DOZE_REQUEST_PULSE;
+            case DOZE_PULSING:
+                return DozeProvider.DozeState.DOZE_PULSING;
+            case DOZE_PULSE_DONE:
+                return DozeProvider.DozeState.DOZE_PULSE_DONE;
+            case FINISH:
+                return DozeProvider.DozeState.FINISH;
+            default:
+                throw new IllegalArgumentException("Unknown state: " + s);
+        }
+    }
+
     private static DozeHost getHost(DozeService service) {
         Application appCandidate = service.getApplication();
         final SystemUIApplication app = (SystemUIApplication) appCandidate;
@@ -58,7 +180,7 @@
     }
 
     /** A wrapper around {@link PowerManager.WakeLock} for testability. */
-    public static class WakeLock {
+    public static class WakeLock implements DozeProvider.WakeLock {
         private final PowerManager.WakeLock mInner;
 
         public WakeLock(PowerManager.WakeLock inner) {
@@ -80,4 +202,13 @@
             return mInner.wrap(runnable);
         }
     }
+
+    /** Hack: We need to initialize the plugin listener before doze actually starts.
+     * This will be unnecessary once we have proper one-shot support */
+    public static class Initializer extends SystemUI {
+        @Override
+        public void start() {
+            getInstance(mContext);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index fb940b5..e081b53 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -17,6 +17,7 @@
 package com.android.systemui.doze;
 
 import android.annotation.NonNull;
+import android.app.PendingIntent;
 
 /**
  * Interface the doze service uses to communicate with the rest of system UI.
@@ -32,14 +33,16 @@
     boolean isNotificationLightOn();
     boolean isPulsingBlocked();
 
-    public interface Callback {
-        void onNewNotifications();
-        void onBuzzBeepBlinked();
-        void onNotificationLight(boolean on);
-        void onPowerSaveChanged(boolean active);
+    void startPendingIntentDismissingKeyguard(PendingIntent intent);
+
+    interface Callback {
+        default void onNewNotifications() {}
+        default void onBuzzBeepBlinked() {}
+        default void onNotificationLight(boolean on) {}
+        default void onPowerSaveChanged(boolean active) {}
     }
 
-    public interface PulseCallback {
+    interface PulseCallback {
         void onPulseStarted();
         void onPulseFinished();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index c633aa1..951b27f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -225,8 +225,10 @@
         boolean newPolicy = wakeLockPolicy(newState);
         if (mWakeLockHeldForCurrentState && !newPolicy) {
             mWakeLock.release();
+            mWakeLockHeldForCurrentState = false;
         } else if (!mWakeLockHeldForCurrentState && newPolicy) {
             mWakeLock.acquire();
+            mWakeLockHeldForCurrentState = true;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 94cbdd4..78b96b3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -38,7 +38,7 @@
 
         setWindowless(true);
 
-        mDozeMachine = DozeFactory.assembleMachine(this);
+        mDozeMachine = DozeFactory.getInstance(getApplication()).assembleMachine(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 9f26b0c..84b22ea 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -58,6 +58,7 @@
     private final SensorManager mSensorManager;
     private final Handler mHandler;
     private final DozeFactory.WakeLock mWakeLock;
+    private final boolean mAllowPulseTriggers;
     private final UiModeManager mUiModeManager;
     private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
 
@@ -68,7 +69,7 @@
     public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
             AmbientDisplayConfiguration config,
             DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
-            DozeFactory.WakeLock wakeLock) {
+            DozeFactory.WakeLock wakeLock, boolean allowPulseTriggers) {
         mContext = context;
         mMachine = machine;
         mDozeHost = dozeHost;
@@ -77,6 +78,7 @@
         mSensorManager = sensorManager;
         mHandler = handler;
         mWakeLock = wakeLock;
+        mAllowPulseTriggers = allowPulseTriggers;
         mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, config,
                 wakeLock, this::onSensor);
         mUiModeManager = mContext.getSystemService(UiModeManager.class);
@@ -149,7 +151,7 @@
 
     private void requestPulse(final int reason, boolean performedProxCheck) {
         Assert.isMainThread();
-        if (mPulsePending || !canPulse()) {
+        if (mPulsePending || !mAllowPulseTriggers || !canPulse()) {
             return;
         }
 
@@ -307,20 +309,11 @@
 
     private DozeHost.Callback mHostCallback = new DozeHost.Callback() {
         @Override
-        public void onNewNotifications() {
-        }
-
-        @Override
         public void onBuzzBeepBlinked() {
             onNotification();
         }
 
         @Override
-        public void onNotificationLight(boolean on) {
-
-        }
-
-        @Override
         public void onPowerSaveChanged(boolean active) {
             if (active) {
                 onPowerSave();
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 5f27b74..6d0e77c 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -62,8 +62,7 @@
     private void createFragmentHost(Parcelable savedState) {
         mFragments = FragmentController.createController(new HostCallbacks());
         mFragments.attachHost(null);
-        // TODO: Remove non-staticness from FragmentLifecycleCallbacks (hopefully).
-        mLifecycleCallbacks = mFragments.getFragmentManager().new FragmentLifecycleCallbacks() {
+        mLifecycleCallbacks = new FragmentLifecycleCallbacks() {
             @Override
             public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v,
                     Bundle savedInstanceState) {
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/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index dd80750..005206f 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -22,39 +22,93 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 
-public abstract class CurrentUserTracker extends BroadcastReceiver {
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
 
-    private Context mContext;
-    private int mCurrentUserId;
+public abstract class CurrentUserTracker {
+    private final UserReceiver mUserReceiver;
+
+    private Consumer<Integer> mCallback = this::onUserSwitched;
 
     public CurrentUserTracker(Context context) {
-        mContext = context;
+        mUserReceiver = UserReceiver.getInstance(context);
     }
 
     public int getCurrentUserId() {
-        return mCurrentUserId;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
-            int oldUserId = mCurrentUserId;
-            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-            if (oldUserId != mCurrentUserId) {
-                onUserSwitched(mCurrentUserId);
-            }
-        }
+        return mUserReceiver.getCurrentUserId();
     }
 
     public void startTracking() {
-        mCurrentUserId = ActivityManager.getCurrentUser();
-        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        mContext.registerReceiver(this, filter);
+        mUserReceiver.addTracker(mCallback);
     }
 
     public void stopTracking() {
-        mContext.unregisterReceiver(this);
+        mUserReceiver.removeTracker(mCallback);
     }
 
     public abstract void onUserSwitched(int newUserId);
+
+    private static class UserReceiver extends BroadcastReceiver {
+        private static UserReceiver sInstance;
+
+        private Context mAppContext;
+        private boolean mReceiverRegistered;
+        private int mCurrentUserId;
+
+        private List<Consumer<Integer>> mCallbacks = new ArrayList<>();
+
+        private UserReceiver(Context context) {
+            mAppContext = context.getApplicationContext();
+        }
+
+        static UserReceiver getInstance(Context context) {
+            if (sInstance == null) {
+                sInstance = new UserReceiver(context);
+            }
+            return sInstance;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                notifyUserSwitched(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+            }
+        }
+
+        public int getCurrentUserId() {
+            return mCurrentUserId;
+        }
+
+        private void addTracker(Consumer<Integer> callback) {
+            if (!mCallbacks.contains(callback)) {
+                mCallbacks.add(callback);
+            }
+            if (!mReceiverRegistered) {
+                mCurrentUserId = ActivityManager.getCurrentUser();
+                IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
+                mAppContext.registerReceiver(this, filter);
+                mReceiverRegistered = true;
+            }
+        }
+
+        private void removeTracker(Consumer<Integer> callback) {
+            if (mCallbacks.contains(callback)) {
+                mCallbacks.remove(callback);
+                if (mCallbacks.size() == 0 && mReceiverRegistered) {
+                    mAppContext.unregisterReceiver(this);
+                    mReceiverRegistered = false;
+                }
+            }
+        }
+
+        private void notifyUserSwitched(int newUserId) {
+            if (mCurrentUserId != newUserId) {
+                mCurrentUserId = newUserId;
+                for (Consumer<Integer> consumer : mCallbacks) {
+                    consumer.accept(newUserId);
+                }
+            }
+        }
+    }
 }
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..6f13ba5 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();
 
@@ -5168,5 +5167,10 @@
             return mNotificationLightOn;
         }
 
+        @Override
+        public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
+            PhoneStatusBar.this.startPendingIntentDismissingKeyguard(intent);
+        }
+
     }
 }
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/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 5696123..6217433 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -165,6 +165,14 @@
         mBrightnessMirror = findViewById(R.id.brightness_mirror);
     }
 
+    @Override
+    public void onViewAdded(View child) {
+        super.onViewAdded(child);
+        if (child.getId() == R.id.brightness_mirror) {
+            mBrightnessMirror = child;
+        }
+    }
+
     public void setService(PhoneStatusBar service) {
         mService = service;
         mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
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/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index ba7c923..863f0e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -189,6 +189,19 @@
 
     @Test
     @UiThreadTest
+    public void testWakeLock_releasedAfterPulse() {
+        mMachine.requestState(INITIALIZED);
+
+        mMachine.requestState(DOZE);
+        mMachine.requestState(DOZE_REQUEST_PULSE);
+        mMachine.requestState(DOZE_PULSING);
+        mMachine.requestState(DOZE_PULSE_DONE);
+
+        assertFalse(mWakeLockFake.isHeld());
+    }
+
+    @Test
+    @UiThreadTest
     public void testScreen_offInDoze() {
         mMachine.requestState(INITIALIZED);
 
diff --git a/preloaded-classes b/preloaded-classes
index 45734b6..a79ae50 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -327,9 +327,6 @@
 android.app.ActivityManager$StackId
 android.app.ActivityManager$TaskDescription
 android.app.ActivityManager$TaskDescription$1
-android.app.ActivityManagerNative
-android.app.ActivityManagerNative$1
-android.app.ActivityManagerProxy
 android.app.ActivityOptions
 android.app.ActivityThread
 android.app.ActivityThread$1
@@ -1729,9 +1726,9 @@
 android.os.Vibrator
 android.os.ZygoteStartFailedEx
 android.os.health.SystemHealthManager
-android.os.storage.IMountService
-android.os.storage.IMountService$Stub
-android.os.storage.IMountService$Stub$Proxy
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
 android.os.storage.StorageManager
 android.os.storage.StorageVolume
 android.os.storage.StorageVolume$1
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 5cf74c7..45f2ec7 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -22,6 +22,27 @@
 // Wrapper for System UI log events
 message MetricsEvent {
 
+  // Types of events
+  enum Type {
+    // Unknown
+    TYPE_UNKNOWN = 0;
+
+    // The view became visible to the user.
+    TYPE_OPEN = 1;
+
+    // The view became hidden.
+    TYPE_CLOSE = 2;
+
+    // The view switched to detail mode (most relevant for quick settings tiles)
+    TYPE_DETAIL = 3;
+
+    // The view or control was activated.
+    TYPE_ACTION = 4;
+
+    // The view or control was dismissed.
+    TYPE_DISMISS = 5;
+  }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -2632,6 +2653,12 @@
     // OS: O
     ENTERPRISE_PRIVACY_SETTINGS = 628;
 
+    // ACTION: Longpress on a TextView.
+    //  SUBTYPE: 1 is for START_SELECTION, 2 is for START_DRAG_AND_DROP, 0 is for OTHER.
+    // CATEGORY: TEXT_CONTROLS
+    // OS: O
+    TEXT_LONGPRESS = 629;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index bf60e47..6404604 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1593,14 +1593,6 @@
 
         // Make sure the package runs under the caller uid.
         mSecurityPolicy.enforceCallFromPackage(callingPackage);
-
-        final int bitmapMemoryUsage = (views != null) ? views.estimateMemoryUsage() : 0;
-        if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
-            throw new IllegalArgumentException("RemoteViews for widget update exceeds"
-                    + " maximum bitmap memory usage (used: " + bitmapMemoryUsage
-                    + ", max: " + mMaxWidgetBitmapMemory + ")");
-        }
-
         synchronized (mLock) {
             ensureGroupStateLoadedLocked(userId);
 
@@ -1812,6 +1804,15 @@
                 // For a full update we replace the RemoteViews completely.
                 widget.views = views;
             }
+            int memoryUsage;
+            if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) &&
+                    (widget.views != null) &&
+                    ((memoryUsage = widget.views.estimateMemoryUsage()) > mMaxWidgetBitmapMemory)) {
+                widget.views = null;
+                throw new IllegalArgumentException("RemoteViews for widget update exceeds"
+                        + " maximum bitmap memory usage (used: " + memoryUsage
+                        + ", max: " + mMaxWidgetBitmapMemory + ")");
+            }
             scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked());
         }
     }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 8b37756..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,124 +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 boolean requestAutoFill(int userId, IBinder activityToken) {
+        public void requestAutoFill(int userId, IBinder activityToken) {
             mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
 
             synchronized (mLock) {
-                return getImplOrThrowLocked(userId).requestAutoFill(activityToken);
+                final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+                if (service != null) {
+                    service.requestAutoFill(activityToken);
+                }
             }
         }
 
@@ -236,17 +269,15 @@
                 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);
                     }
                 }
@@ -267,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 ae687da4..e409cb0 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -16,6 +16,8 @@
 
 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;
@@ -27,10 +29,11 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.icu.text.DateFormat;
-import android.os.Bundle;
+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;
@@ -38,14 +41,15 @@
 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.ArrayList;
 import java.util.Date;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -56,21 +60,23 @@
 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;
 
     // TODO: improve its usage
     // - set maximum number of entries
     // - disable on low-memory devices.
-    private final List<String> mRequestHistory = new ArrayList<>();
+    private final List<String> mRequestHistory = new LinkedList<>();
+
+    @GuardedBy("mLock")
+    private final List<IBinder> mQueuedRequests = new LinkedList<>();
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -90,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);
                 }
             }
         }
@@ -100,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);
+            }
         }
     };
 
@@ -109,18 +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);
 
         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;
@@ -140,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;
@@ -154,11 +180,12 @@
         if (DEBUG) Slog.d(TAG, "Bound to " + mComponent);
     }
 
-    boolean requestAutoFill(IBinder activityToken) {
-        if (!mBound) {
-            // TODO: should it bind on demand? Or perhaps always run when on on low-memory?
-            Slog.w(TAG, "requestAutoFill() failed because it's not bound to service");
-            return false;
+    void requestAutoFill(IBinder activityToken) {
+        synchronized (mLock) {
+            if (!mBound) {
+                Slog.w(TAG, "requestAutoFill() failed because it's not bound to service");
+                return;
+            }
         }
 
         // TODO: activityToken should probably not be null, but we need to wait until the UI is
@@ -175,25 +202,28 @@
                 Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
             if (topActivities.isEmpty()) {
                 Slog.w(TAG, "Could not get top activity");
-                return false;
+                return;
             }
             activityToken = topActivities.get(0);
         }
 
+        final String historyItem =
+                DateFormat.getDateTimeInstance().format(new Date()) + " - " + activityToken;
         synchronized (mLock) {
-            return requestAutoFillLocked(activityToken);
+            mRequestHistory.add(historyItem);
+            requestAutoFillLocked(activityToken, true);
         }
     }
 
-    private boolean requestAutoFillLocked(IBinder activityToken) {
-        mRequestHistory.add(
-                DateFormat.getDateTimeInstance().format(new Date()) + " - " + activityToken);
-        if (DEBUG) Slog.d(TAG, "Requesting for user " + mUser + " and activity " + activityToken);
-
-        // Sanity check
+    private void requestAutoFillLocked(IBinder activityToken, boolean queueIfNecessary) {
         if (mService == null) {
-            Slog.w(TAG, "requestAutoFillLocked(: service is null");
-            return false;
+            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;
         }
 
         /*
@@ -206,23 +236,30 @@
         try {
             // TODO: add MetricsLogger call
             if (!mAm.requestAutoFillData(mService.getAssistReceiver(), null, activityToken)) {
-                return false;
+                // 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) {
             // Should happen, it's a local call.
         }
-        return true;
     }
 
-    void shutdownLocked() {
-        if (DEBUG) Slog.d(TAG, "shutdownLocked()");
+    void stopLocked() {
+        if (DEBUG) Slog.d(TAG, "stopLocked()");
 
+        // Sanity check.
+        if (mService == null) {
+            Log.w(TAG, "service already null on shutdown");
+            return;
+        }
         try {
-            if (mService != null) {
-                mService.shutdown();
-            }
+            mService.onDisconnected();
         } catch (RemoteException e) {
-            Slog.w(TAG, "RemoteException in shutdown", e);
+            if (! (e instanceof DeadObjectException)) {
+                Slog.w(TAG, "Exception calling service.onDisconnected(): " + e);
+            }
+        } finally {
+            mService = null;
         }
 
         if (mBound) {
@@ -245,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)
@@ -265,11 +306,20 @@
                 pw.print(prefix2); pw.print(i); pw.print(": "); pw.println(mRequestHistory.get(i));
             }
         }
+        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));
+            }
+        }
     }
 
     @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 c9037fc..6406b8a 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java
@@ -66,8 +66,8 @@
 
     private int requestAutoFill() throws RemoteException {
         final int userId = getUserIdFromArgs();
-        final boolean ok = mService.requestAutoFill(userId, null);
-        return ok ? 0 : 1;
+        mService.requestAutoFill(userId, null);
+        return 0;
     }
 
     private int getUserIdFromArgs() {
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..f4ddc06 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;
@@ -249,13 +249,16 @@
         try {
             randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
             String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
+            tieProfileLockToParent(managedUserId, newPassword);
             setLockPasswordInternal(newPassword, managedUserPassword, managedUserId);
             // We store a private credential for the managed user that's unlocked by the primary
             // account holder's credential. As such, the user will never be prompted to enter this
             // password directly, so we always store a password.
             setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
                     DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
-            tieProfileLockToParent(managedUserId, newPassword);
+        } catch (KeyStoreException e) {
+            // Bug: 32490092
+            Slog.e(TAG, "Not able to set keys to keystore", e);
         } catch (NoSuchAlgorithmException | RemoteException e) {
             Slog.e(TAG, "Fail to tie managed profile", e);
             // Nothing client can do to fix this issue, so we do not throw exception out
@@ -776,6 +779,7 @@
     }
 
     private void unlockChildProfile(int profileHandle) throws RemoteException {
+        if (DEBUG) Slog.v(TAG, "Unlock child profile");
         try {
             doVerifyPassword(getDecryptedPasswordForTiedProfile(profileHandle), false,
                     0 /* no challenge */, profileHandle, null /* progressCallback */);
@@ -813,7 +817,7 @@
         };
 
         try {
-            ActivityManagerNative.getDefault().unlockUser(userId, token, secret, listener);
+            ActivityManager.getService().unlockUser(userId, token, secret, listener);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -1035,7 +1039,7 @@
         }
     }
 
-    private void tieProfileLockToParent(int userId, String password) {
+    private void tieProfileLockToParent(int userId, String password) throws KeyStoreException {
         if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
         byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
         byte[] encryptionResult;
@@ -1077,7 +1081,7 @@
                 keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
             }
         } catch (CertificateException | UnrecoverableKeyException
-                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+                | IOException | BadPaddingException | IllegalBlockSizeException
                 | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
             throw new RuntimeException("Failed to encrypt key", e);
         }
@@ -1160,10 +1164,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 +1175,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);
         }
@@ -1219,7 +1223,11 @@
         } finally {
             if (managedUserId != -1 && managedUserDecryptedPassword != null) {
                 if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
-                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+                try {
+                    tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+                } catch (KeyStoreException e) {
+                    throw new RuntimeException("Failed to tie profile lock", e);
+                }
             }
         }
     }
@@ -1488,7 +1496,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 +1659,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..8fd1d2f 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;
@@ -1882,7 +1881,13 @@
                 final long accountId = accounts.accountsDb.findDeAccountId(accountToRename);
                 if (accountId >= 0) {
                     accounts.accountsDb.renameCeAccount(accountId, newName);
-                    accounts.accountsDb.renameDeAccount(accountId, newName, accountToRename.name);
+                    if (accounts.accountsDb.renameDeAccount(
+                            accountId, newName, accountToRename.name)) {
+                        accounts.accountsDb.setTransactionSuccessful();
+                    } else {
+                        Log.e(TAG, "renameAccount failed");
+                        return null;
+                    }
                 }
             } finally {
                 accounts.accountsDb.endTransaction();
@@ -3999,7 +4004,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 +4945,7 @@
 
     private int handleIncomingUser(int userId) {
         try {
-            return ActivityManagerNative.getDefault().handleIncomingUser(
+            return ActivityManager.getService().handleIncomingUser(
                     Binder.getCallingPid(), Binder.getCallingUid(), userId, true, true, "", null);
         } catch (RemoteException re) {
             // Shouldn't happen, local.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e080fd9..c8ed872 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;
@@ -1520,7 +1520,7 @@
     static final int PERSIST_URI_GRANTS_MSG = 38;
     static final int REQUEST_ALL_PSS_MSG = 39;
     static final int START_PROFILES_MSG = 40;
-    static final int UPDATE_TIME = 41;
+    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
     static final int SYSTEM_USER_START_MSG = 42;
     static final int SYSTEM_USER_CURRENT_MSG = 43;
     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
@@ -2026,15 +2026,18 @@
                 }
                 break;
             }
-            case UPDATE_TIME: {
+            case UPDATE_TIME_PREFERENCE_MSG: {
+                // The user's time format preference might have changed.
+                // For convenience we re-use the Intent extra values.
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
                         ProcessRecord r = mLruProcesses.get(i);
                         if (r.thread != null) {
                             try {
-                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
+                                r.thread.updateTimePrefs(msg.arg1);
                             } catch (RemoteException ex) {
-                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
+                                Slog.w(TAG, "Failed to update preferences for: "
+                                        + r.info.processName);
                             }
                         }
                     }
@@ -2097,9 +2100,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 +3602,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();
@@ -6324,13 +6327,18 @@
             removeLruProcessLocked(app);
             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
                 Slog.w(TAG, "Unattached app died before backup, skipping");
-                try {
-                    IBackupManager bm = IBackupManager.Stub.asInterface(
-                            ServiceManager.getService(Context.BACKUP_SERVICE));
-                    bm.agentDisconnected(app.info.packageName);
-                } catch (RemoteException e) {
-                    // Can't happen; the backup manager is local
-                }
+                mHandler.post(new Runnable() {
+                @Override
+                    public void run(){
+                        try {
+                            IBackupManager bm = IBackupManager.Stub.asInterface(
+                                    ServiceManager.getService(Context.BACKUP_SERVICE));
+                            bm.agentDisconnected(app.info.packageName);
+                        } catch (RemoteException e) {
+                            // Can't happen; the backup manager is local
+                        }
+                    }
+                });
             }
             if (isPendingBroadcastProcessLocked(pid)) {
                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
@@ -6490,11 +6498,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,
@@ -8097,7 +8106,12 @@
 
         // Third...  does the caller itself have permission to access
         // this uri?
-        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
+        final int callingAppId = UserHandle.getAppId(callingUid);
+        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
+            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
+                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
+            return -1;
+        } else {
             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
                 // Require they hold a strong enough Uri permission
                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
@@ -10332,6 +10346,46 @@
     }
 
     /**
+     * Check if the calling UID has a possible chance at accessing the provider
+     * at the given authority and user.
+     */
+    public String checkContentProviderAccess(String authority, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+            userId = UserHandle.getCallingUserId();
+        }
+
+        ProviderInfo cpi = null;
+        try {
+            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
+                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
+                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                    userId);
+        } catch (RemoteException ignored) {
+        }
+        if (cpi == null) {
+            // TODO: make this an outright failure in a future platform release;
+            // until then anonymous content notifications are unprotected
+            //return "Failed to find provider " + authority + " for user " + userId;
+            return null;
+        }
+
+        ProcessRecord r = null;
+        synchronized (mPidsSelfLocked) {
+            r = mPidsSelfLocked.get(Binder.getCallingPid());
+        }
+        if (r == null) {
+            return "Failed to find PID " + Binder.getCallingPid();
+        }
+
+        synchronized (this) {
+            return checkContentProviderPermissionLocked(cpi, r, userId, true);
+        }
+    }
+
+    /**
      * Check if {@link ProcessRecord} has a possible chance at accessing the
      * given {@link ProviderInfo}. Final permission checking is always done
      * in {@link ContentProvider}.
@@ -13522,9 +13576,11 @@
         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
                 crashInfo);
 
-        if (r != null && r.pid != Process.myPid() &&
-                Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
+        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
+                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
+        final boolean isSystem = (r == null) || r.persistent;
+
+        if (isFatal && !isSystem) {
             mAppErrors.crashApplication(r, crashInfo);
             return true;
         } else {
@@ -16908,13 +16964,18 @@
         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
                     + mBackupTarget.appInfo + " died during backup");
-            try {
-                IBackupManager bm = IBackupManager.Stub.asInterface(
-                        ServiceManager.getService(Context.BACKUP_SERVICE));
-                bm.agentDisconnected(app.info.packageName);
-            } catch (RemoteException e) {
-                // can't happen; backup manager is local
-            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run(){
+                    try {
+                        IBackupManager bm = IBackupManager.Stub.asInterface(
+                                ServiceManager.getService(Context.BACKUP_SERVICE));
+                        bm.agentDisconnected(app.info.packageName);
+                    } catch (RemoteException e) {
+                        // can't happen; backup manager is local
+                    }
+                }
+            });
         }
 
         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
@@ -18111,11 +18172,20 @@
                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
                     break;
                 case Intent.ACTION_TIME_CHANGED:
-                    // If the user set the time, let all running processes know.
-                    final int is24Hour =
-                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
-                                    : 0;
-                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
+                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
+                    // the tri-state value it may contain and "unknown".
+                    // For convenience we re-use the Intent extra values.
+                    final int NO_EXTRA_VALUE_FOUND = -1;
+                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
+                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
+                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
+                    // Only send a message if the time preference is available.
+                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
+                        Message updateTimePreferenceMsg =
+                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
+                                        timeFormatPreferenceMsgValue, 0);
+                        mHandler.sendMessage(updateTimePreferenceMsg);
+                    }
                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
                     synchronized (stats) {
                         stats.noteCurrentTimeChangedLocked();
@@ -22057,6 +22127,11 @@
 
     private final class LocalService extends ActivityManagerInternal {
         @Override
+        public String checkContentProviderAccess(String authority, int userId) {
+            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
+        }
+
+        @Override
         public void onWakefulnessChanged(int wakefulness) {
             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
         }
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/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 1bdef43..473b1a3 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1471,7 +1471,7 @@
             return STACK_INVISIBLE;
         }
 
-        if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) {
+        if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) {
             return STACK_VISIBLE;
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 282ec50..5d8d79f 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;
@@ -609,6 +612,15 @@
 
     /** The top most stack. */
     boolean isFrontStack(ActivityStack stack) {
+        return isFrontOfStackList(stack, mHomeStack.mStacks);
+    }
+
+    /** The top most stack on its display. */
+    boolean isFrontStackOnDisplay(ActivityStack stack) {
+        return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks);
+    }
+
+    private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) {
         if (stack == null) {
             return false;
         }
@@ -617,7 +629,7 @@
         if (parent != null) {
             stack = parent.getStack();
         }
-        return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1));
+        return stack == stackList.get((stackList.size() - 1));
     }
 
     /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
@@ -1483,16 +1495,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 +1968,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 +1979,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 +2391,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 +3573,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 +4227,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..dff7cef 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -31,6 +31,7 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.isStaticStack;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -50,6 +51,8 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.view.Display.INVALID_DISPLAY;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
@@ -115,6 +118,7 @@
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
+import com.android.server.pm.EphemeralResolver;
 import com.android.server.wm.WindowManagerService;
 
 import java.util.ArrayList;
@@ -132,9 +136,6 @@
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
 
-    // TODO b/30204367 remove when the platform fully supports ephemeral applications
-    private static final boolean USE_DEFAULT_EPHEMERAL_LAUNCHER = false;
-
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
     private ActivityStartInterceptor mInterceptor;
@@ -254,11 +255,7 @@
 
         if (err == ActivityManager.START_SUCCESS) {
             Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
-                    + "} from uid " + callingUid
-                    + " on display " + (container == null ? (mSupervisor.mFocusedStack == null ?
-                    Display.DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId) :
-                    (container.mActivityDisplay == null ? Display.DEFAULT_DISPLAY :
-                            container.mActivityDisplay.mDisplayId)));
+                    + "} from uid " + callingUid);
         }
 
         ActivityRecord sourceRecord = null;
@@ -458,13 +455,21 @@
         // Instead, launch the ephemeral installer. Once the installer is finished, it
         // starts either the intent we resolved here [on install error] or the ephemeral
         // app [on install success].
-        if (rInfo != null && rInfo.ephemeralIntentInfo != null) {
+        if (rInfo != null && rInfo.ephemeralResponse != null) {
             final String packageName =
-                    rInfo.ephemeralIntentInfo.getEphemeralResolveInfo().getPackageName();
-            final String splitName = rInfo.ephemeralIntentInfo.getSplitName();
-            intent = buildEphemeralInstallerIntent(intent, ephemeralIntent,
-                    packageName, splitName, callingPackage, resolvedType,
-                    userId);
+                    rInfo.ephemeralResponse.resolveInfo.getPackageName();
+            final String splitName = rInfo.ephemeralResponse.splitName;
+            final boolean needsPhaseTwo = rInfo.ephemeralResponse.needsPhase2;
+            final String token = rInfo.ephemeralResponse.token;
+            if (needsPhaseTwo) {
+                // request phase two resolution
+                mService.getPackageManagerInternalLocked().requestEphemeralResolutionPhaseTwo(
+                        rInfo.ephemeralResponse, ephemeralIntent, resolvedType, intent,
+                        callingPackage, userId);
+            }
+            intent = EphemeralResolver.buildEphemeralInstallerIntent(intent, ephemeralIntent,
+                    callingPackage, resolvedType, userId, packageName, splitName, token,
+                    needsPhaseTwo);
             resolvedType = null;
             callingUid = realCallingUid;
             callingPid = realCallingPid;
@@ -523,60 +528,6 @@
         return err;
     }
 
-    /**
-     * Builds and returns an intent to launch the ephemeral installer.
-     */
-    private Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent,
-            String ephemeralPackageName, String ephemeralSplitName, String callingPackage,
-            String resolvedType, int userId) {
-        final Intent nonEphemeralIntent = new Intent(origIntent);
-        nonEphemeralIntent.setFlags(nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
-        // Intent that is launched if the ephemeral package couldn't be installed
-        // for any reason.
-        final IIntentSender failureIntentTarget = mService.getIntentSenderLocked(
-                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
-                Binder.getCallingUid(), userId, null /*token*/, null /*resultWho*/, 1,
-                new Intent[]{ nonEphemeralIntent }, new String[]{ resolvedType },
-                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
-                | PendingIntent.FLAG_IMMUTABLE, null /*bOptions*/);
-
-        final Intent ephemeralIntent;
-        if (USE_DEFAULT_EPHEMERAL_LAUNCHER) {
-            // Force the intent to be directed to the ephemeral package
-            ephemeralIntent = new Intent(origIntent);
-            ephemeralIntent.setPackage(ephemeralPackageName);
-        } else {
-            // Success intent goes back to the installer
-            ephemeralIntent = new Intent(launchIntent);
-        }
-
-        // Intent that is eventually launched if the ephemeral package was
-        // installed successfully. This will actually be launched by a platform
-        // broadcast receiver.
-        final IIntentSender successIntentTarget = mService.getIntentSenderLocked(
-                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
-                Binder.getCallingUid(), userId, null /*token*/, null /*resultWho*/, 0,
-                new Intent[]{ ephemeralIntent }, new String[]{ resolvedType },
-                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
-                | PendingIntent.FLAG_IMMUTABLE, null /*bOptions*/);
-
-        // Finally build the actual intent to launch the ephemeral installer
-        int flags = launchIntent.getFlags();
-        final Intent intent = new Intent();
-        intent.setFlags(flags
-                | Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_CLEAR_TASK
-                | Intent.FLAG_ACTIVITY_NO_HISTORY
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName);
-        intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName);
-        intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, new IntentSender(failureIntentTarget));
-        intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS, new IntentSender(successIntentTarget));
-        // TODO: Remove when the platform has fully implemented ephemeral apps
-        intent.setData(origIntent.getData().buildUpon().clearQuery().build());
-        return intent;
-    }
-
     void postStartActivityUncheckedProcessing(
             ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
             ActivityStack targetStack) {
@@ -1573,8 +1524,8 @@
 
     private void updateTaskReturnToType(
             TaskRecord task, int launchFlags, ActivityStack focusedStack) {
-        if (focusedStack != null && focusedStack.isHomeStack() &&
-                focusedStack.topTask().isOnTopLauncher()) {
+        if (focusedStack != null && focusedStack.isHomeStack() && focusedStack.topTask() != null
+                && focusedStack.topTask().isOnTopLauncher()) {
             // Since an on-top launcher will is moved to back when tasks are launched from it,
             // those tasks should first try to return to a non-home activity.
             // This also makes sure that non-home activities are visible under a transparent
@@ -1952,12 +1903,14 @@
 
         // The fullscreen stack can contain any task regardless of if the task is resizeable
         // or not. So, we let the task go in the fullscreen task if it is the focus stack.
+        // Same also applies to dynamic stacks, as they behave similar to fullscreen stack.
         // If the freeform or docked stack has focus, and the activity to be launched is resizeable,
         // we can also put it in the focused stack.
         final int focusedStackId = mSupervisor.mFocusedStack.mStackId;
         final boolean canUseFocusedStack = focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID
                 || (focusedStackId == DOCKED_STACK_ID && r.canGoInDockedStack())
-                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced());
+                || (focusedStackId == FREEFORM_WORKSPACE_STACK_ID && r.isResizeableOrForced())
+                || !isStaticStack(focusedStackId);
         if (canUseFocusedStack && (!newTask
                 || mSupervisor.mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
@@ -1965,7 +1918,7 @@
             return mSupervisor.mFocusedStack;
         }
 
-        // We first try to put the task in the first dynamic stack.
+        // We first try to put the task in the first dynamic stack on home display.
         final ArrayList<ActivityStack> homeDisplayStacks = mSupervisor.mHomeStack.mStacks;
         for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             stack = homeDisplayStacks.get(stackNdx);
@@ -1994,16 +1947,29 @@
             return mReuseTask.getStack();
         }
 
+        final int launchDisplayId =
+                (aOptions != null) ? aOptions.getLaunchDisplayId() : INVALID_DISPLAY;
+
         final int launchStackId =
                 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
 
+        if (launchStackId != INVALID_STACK_ID && launchDisplayId != INVALID_DISPLAY) {
+            throw new IllegalArgumentException(
+                    "Stack and display id can't be set at the same time.");
+        }
+
         if (isValidLaunchStackId(launchStackId, r)) {
             return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
-        } else if (launchStackId == DOCKED_STACK_ID) {
+        }
+        if (launchStackId == DOCKED_STACK_ID) {
             // The preferred launch stack is the docked stack, but it isn't a valid launch stack
             // for this activity, so we put the activity in the fullscreen stack.
             return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
         }
+        if (launchDisplayId != INVALID_DISPLAY) {
+            // Stack id has higher priority than display id.
+            return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
+        }
 
         if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
             return null;
@@ -2047,9 +2013,8 @@
         }
     }
 
-    private boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
-        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID
-                || !StackId.isStaticStack(stackId)) {
+    boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
+        if (stackId == INVALID_STACK_ID || stackId == HOME_STACK_ID) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 9697855..a0a04bb 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -75,7 +75,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.IntArray;
@@ -735,8 +735,8 @@
         }
     }
 
-    private IMountService getMountService() {
-        return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+    private IStorageManager getStorageManager() {
+        return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
     }
 
     /**
@@ -980,10 +980,10 @@
             // TODO Move this block outside of synchronized if it causes lock contention
             if (!StorageManager.isUserKeyUnlocked(userId)) {
                 final UserInfo userInfo = getUserInfo(userId);
-                final IMountService mountService = getMountService();
+                final IStorageManager storageManager = getStorageManager();
                 try {
                     // We always want to unlock user storage, even user is not started yet
-                    mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
+                    storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
                 } catch (RemoteException | RuntimeException e) {
                     Slog.w(TAG, "Failed to unlock: " + e.getMessage());
                 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eb5e603..da016da 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -25,7 +25,6 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
@@ -1706,7 +1705,7 @@
     private int getCurrentUserId() {
         final long ident = Binder.clearCallingIdentity();
         try {
-            UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            UserInfo currentUser = ActivityManager.getService().getCurrentUser();
             return currentUser.id;
         } catch (RemoteException e) {
             // Activity manager not running, nothing we can do assume user 0.
@@ -5124,7 +5123,7 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
+            ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -5463,7 +5462,7 @@
             }
             try {
                 final int uid = pkg.applicationInfo.uid;
-                ActivityManagerNative.getDefault().killUid(UserHandle.getAppId(uid),
+                ActivityManager.getService().killUid(UserHandle.getAppId(uid),
                         UserHandle.getUserId(uid),
                         "killBackgroundUserProcessesWithAudioRecordPermission");
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 5772a57..8d4f0a9 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -16,7 +16,7 @@
 
 package com.android.server.clipboard;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
@@ -71,7 +71,7 @@
     public ClipboardService(Context context) {
         super(context);
 
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         mPm = getContext().getPackageManager();
         mUm = (IUserManager) ServiceManager.getService(Context.USER_SERVICE);
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 0727629..886c97f 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,12 +20,11 @@
 import android.accounts.Account;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.job.JobInfo;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
@@ -66,7 +65,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.security.InvalidParameterException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -296,24 +294,15 @@
 
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();
-        final int callingUserHandle = UserHandle.getCallingUserId();
-        // Registering an observer for any user other than the calling user requires uri grant or
-        // cross user permission
-        if (callingUserHandle != userHandle) {
-            if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle)
-                    != PackageManager.PERMISSION_GRANTED) {
-                enforceCrossUserPermission(userHandle,
-                        "no permission to observe other users' provider view");
-            }
-        }
 
-        if (userHandle < 0) {
-            if (userHandle == UserHandle.USER_CURRENT) {
-                userHandle = ActivityManager.getCurrentUser();
-            } else if (userHandle != UserHandle.USER_ALL) {
-                throw new InvalidParameterException("Bad user handle for registerContentObserver: "
-                        + userHandle);
-            }
+        userHandle = handleIncomingUser(uri, pid, uid,
+                Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle);
+
+        final String msg = LocalServices.getService(ActivityManagerInternal.class)
+                .checkContentProviderAccess(uri.getAuthority(), userHandle);
+        if (msg != null) {
+            Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg);
+            return;
         }
 
         synchronized (mRootNode) {
@@ -363,22 +352,15 @@
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();
         final int callingUserHandle = UserHandle.getCallingUserId();
-        // Notify for any user other than the caller requires uri grant or cross user permission
-        if (callingUserHandle != userHandle) {
-            if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
-                    userHandle) != PackageManager.PERMISSION_GRANTED) {
-                enforceCrossUserPermission(userHandle, "no permission to notify other users");
-            }
-        }
 
-        // We passed the permission check; resolve pseudouser targets as appropriate
-        if (userHandle < 0) {
-            if (userHandle == UserHandle.USER_CURRENT) {
-                userHandle = ActivityManager.getCurrentUser();
-            } else if (userHandle != UserHandle.USER_ALL) {
-                throw new InvalidParameterException("Bad user handle for notifyChange: "
-                        + userHandle);
-            }
+        userHandle = handleIncomingUser(uri, pid, uid,
+                Intent.FLAG_GRANT_WRITE_URI_PERMISSION, userHandle);
+
+        final String msg = LocalServices.getService(ActivityManagerInternal.class)
+                .checkContentProviderAccess(uri.getAuthority(), userHandle);
+        if (msg != null) {
+            Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg);
+            return;
         }
 
         // This makes it so that future permission checks will be in the context of this
@@ -434,7 +416,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;
@@ -1143,6 +1125,27 @@
         }
     }
 
+    private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, int userId) {
+        if (userId == UserHandle.USER_CURRENT) {
+            userId = ActivityManager.getCurrentUser();
+        }
+
+        if (userId == UserHandle.USER_ALL) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+        } else if (userId < 0) {
+            throw new IllegalArgumentException("Invalid user: " + userId);
+        } else if (userId != UserHandle.getCallingUserId()) {
+            if (checkUriPermission(uri, pid, uid, modeFlags,
+                    userId) != PackageManager.PERMISSION_GRANTED) {
+                mContext.enforceCallingOrSelfPermission(
+                        Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+            }
+        }
+
+        return userId;
+    }
+
     /**
      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL
      * permission, if the userHandle is not for the caller.
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..604b3ed 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;
@@ -81,10 +80,8 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
-import android.media.AudioSystem;
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
@@ -244,7 +241,6 @@
     private int mDefaultNotificationLedOn;
 
     private int mDefaultNotificationLedOff;
-    private long[] mDefaultVibrationPattern;
 
     private long[] mFallbackVibrationPattern;
     private boolean mUseAttentionLight;
@@ -305,7 +301,6 @@
     private RankingHandler mRankingHandler;
     private long mLastOverRateLogTime;
     private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
-    private String mSystemNotificationSound;
 
     private SnoozeHelper mSnoozeHelper;
     private GroupHelper mGroupHelper;
@@ -600,7 +595,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) {
@@ -823,8 +818,6 @@
     private final class SettingsObserver extends ContentObserver {
         private final Uri NOTIFICATION_LIGHT_PULSE_URI
                 = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
-        private final Uri NOTIFICATION_SOUND_URI
-                = Settings.System.getUriFor(Settings.System.NOTIFICATION_SOUND);
         private final Uri NOTIFICATION_RATE_LIMIT_URI
                 = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
 
@@ -836,8 +829,6 @@
             ContentResolver resolver = getContext().getContentResolver();
             resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
                     false, this, UserHandle.USER_ALL);
-            resolver.registerContentObserver(NOTIFICATION_SOUND_URI,
-                    false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
                     false, this, UserHandle.USER_ALL);
             update(null);
@@ -861,10 +852,6 @@
                 mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver,
                             Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate);
             }
-            if (uri == null || NOTIFICATION_SOUND_URI.equals(uri)) {
-                mSystemNotificationSound = Settings.System.getString(resolver,
-                        Settings.System.NOTIFICATION_SOUND);
-            }
         }
     }
 
@@ -940,8 +927,8 @@
     }
 
     @VisibleForTesting
-    void setSystemNotificationSound(String systemNotificationSound) {
-        mSystemNotificationSound = systemNotificationSound;
+    void setFallbackVibrationPattern(long[] vibrationPattern) {
+        mFallbackVibrationPattern = vibrationPattern;
     }
 
     @Override
@@ -952,7 +939,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);
@@ -1069,11 +1056,6 @@
         mDefaultNotificationLedOff = resources.getInteger(
                 R.integer.config_defaultNotificationLedOff);
 
-        mDefaultVibrationPattern = getLongArray(resources,
-                R.array.config_defaultNotificationVibePattern,
-                VIBRATE_PATTERN_MAXLEN,
-                DEFAULT_VIBRATE_PATTERN);
-
         mFallbackVibrationPattern = getLongArray(resources,
                 R.array.config_notificationFallbackVibePattern,
                 VIBRATE_PATTERN_MAXLEN,
@@ -3035,43 +3017,17 @@
                 && mAudioManager != null) {
             if (DBG) Slog.v(TAG, "Interrupting!");
 
-            // should we use the default notification sound? (indicated either by
-            // DEFAULT_SOUND or because notification.sound is pointing at
-            // Settings.System.NOTIFICATION_SOUND)
-            final boolean useDefaultSound =
-                    (notification.defaults & Notification.DEFAULT_SOUND) != 0
-                    || Settings.System.DEFAULT_NOTIFICATION_URI.equals(notification.sound);
-
-            Uri soundUri = null;
-            if (useDefaultSound) {
-                soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
-
-                // check to see if the default notification sound is silent
-                hasValidSound = mSystemNotificationSound != null;
-            } else if (notification.sound != null) {
-                soundUri = notification.sound;
-                hasValidSound = (soundUri != null);
-            } else if (record.getChannel().getRingtone() != null) {
-                soundUri = record.getChannel().getRingtone();
-                hasValidSound = (soundUri != null);
+            Uri soundUri = record.getSound();
+            hasValidSound = (soundUri != null);
+            long[] vibration = record.getVibration();
+            // Demote sound to vibration if vibration missing & phone in vibration mode.
+            if (vibration == null
+                    && hasValidSound
+                    && (mAudioManager.getRingerModeInternal()
+                            == AudioManager.RINGER_MODE_VIBRATE)) {
+                vibration = mFallbackVibrationPattern;
             }
-
-            // Does the notification want to specify its own vibration?
-            final boolean hasCustomVibrate = notification.vibrate != null;
-
-            // new in 4.2: if there was supposed to be a sound and we're in vibrate
-            // mode, and no other vibration is specified, we fall back to vibration
-            final boolean convertSoundToVibration =
-                    !hasCustomVibrate
-                            && hasValidSound
-                            && (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
-
-            // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
-            final boolean useDefaultVibrate =
-                    (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
-            final boolean hasChannelVibration = record.getChannel().shouldVibrate();
-            hasValidVibrate = useDefaultVibrate || convertSoundToVibration ||
-                    hasCustomVibrate || hasChannelVibration;
+            hasValidVibrate = vibration != null;
 
             // We can alert, and we're allowed to alert, but if the developer asked us to only do
             // it once, and we already have, then don't.
@@ -3079,54 +3035,17 @@
                     && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
 
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
-
                 if (hasValidSound) {
-                    boolean looping =
-                            (notification.flags & Notification.FLAG_INSISTENT) != 0;
-                    AudioAttributes audioAttributes = audioAttributesForNotification(notification);
                     mSoundNotificationKey = key;
-                    // do not play notifications if stream volume is 0 (typically because
-                    // ringer mode is silent) or if there is a user of exclusive audio focus
-                    if ((mAudioManager.getStreamVolume(
-                            AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
-                            && !mAudioManager.isAudioFocusExclusive()) {
-                        final long identity = Binder.clearCallingIdentity();
-                        try {
-                            final IRingtonePlayer player =
-                                    mAudioManager.getRingtonePlayer();
-                            if (player != null) {
-                                if (DBG) Slog.v(TAG, "Playing sound " + soundUri
-                                        + " with attributes " + audioAttributes);
-                                player.playAsync(soundUri, record.sbn.getUser(), looping,
-                                        audioAttributes);
-                                beep = true;
-                            }
-                        } catch (RemoteException e) {
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    }
+                    beep = playSound(record, soundUri);
                 }
                 if (hasValidVibrate && !(mAudioManager.getRingerModeInternal()
                         == AudioManager.RINGER_MODE_SILENT)) {
                     mVibrateNotificationKey = key;
 
-                    if (useDefaultVibrate || convertSoundToVibration) {
-                        playNonCustomVibration(record, useDefaultVibrate);
-                    } else if (notification.vibrate != null && notification.vibrate.length > 1) {
-                        // If you want your own vibration pattern, you need the VIBRATE
-                        // permission
-                        mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
-                                notification.vibrate,
-                                ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                        ? 0: -1, audioAttributesForNotification(notification));
-                        buzz = true;
-                    } else if (hasChannelVibration) {
-                        playNonCustomVibration(record, useDefaultVibrate);
-                    }
+                    buzz = playVibration(record, vibration);
                 }
             }
-
         }
         // If a notification is updated to remove the actively playing sound or vibrate,
         // cancel that feedback now
@@ -3169,41 +3088,42 @@
                 || (record.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0;
     }
 
-    private boolean playNonCustomVibration(final NotificationRecord record,
-            boolean useDefaultVibrate) {
+    private boolean playSound(final NotificationRecord record, Uri soundUri) {
+        boolean looping = (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0;
+        // do not play notifications if there is a user of exclusive audio focus
+        if (!mAudioManager.isAudioFocusExclusive()) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+                if (player != null) {
+                    if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+                            + " with attributes " + record.getAudioAttributes());
+                    player.playAsync(soundUri, record.sbn.getUser(), looping,
+                            record.getAudioAttributes());
+                    return true;
+                }
+            } catch (RemoteException e) {
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+        return false;
+    }
+
+    private boolean playVibration(final NotificationRecord record, long[] vibration) {
         // Escalate privileges so we can use the vibrator even if the
         // notifying app does not have the VIBRATE permission.
         long identity = Binder.clearCallingIdentity();
         try {
-            mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
-                    useDefaultVibrate ? mDefaultVibrationPattern
-                            : mFallbackVibrationPattern,
+            mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), vibration,
                     ((record.getNotification().flags & Notification.FLAG_INSISTENT) != 0)
-                            ? 0: -1, audioAttributesForNotification(record.getNotification()));
+                            ? 0: -1, record.getAudioAttributes());
             return true;
         } finally{
             Binder.restoreCallingIdentity(identity);
         }
     }
 
-    private static AudioAttributes audioAttributesForNotification(Notification n) {
-        if (n.audioAttributes != null
-                && !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) {
-            // the audio attributes are set and different from the default, use them
-            return n.audioAttributes;
-        } else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
-            // the stream type is valid, use it
-            return new AudioAttributes.Builder()
-                    .setInternalLegacyStreamType(n.audioStreamType)
-                    .build();
-        } else if (n.audioStreamType == AudioSystem.STREAM_DEFAULT) {
-            return Notification.AUDIO_ATTRIBUTES_DEFAULT;
-        } else {
-            Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
-            return Notification.AUDIO_ATTRIBUTES_DEFAULT;
-        }
-    }
-
     void showNextToastLocked() {
         ToastRecord record = mToastQueue.get(0);
         while (record != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 5eacba6..984fc38 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -24,15 +24,21 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
+import android.media.AudioSystem;
+import android.net.Uri;
+import android.os.Build;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.EventLogTags;
@@ -100,6 +106,10 @@
     private int mSuppressedVisualEffects = 0;
     private String mUserExplanation;
     private String mPeopleExplanation;
+    private boolean mPreChannelsNotification = true;
+    private Uri mSound;
+    private long[] mVibration;
+    private AudioAttributes mAttributes;
 
     @VisibleForTesting
     public NotificationRecord(Context context, StatusBarNotification sbn)
@@ -111,12 +121,95 @@
         mUpdateTimeMs = mCreationTimeMs;
         mContext = context;
         stats = new NotificationUsageStats.SingleNotificationStats();
-        mImportance = defaultImportance();
+        mPreChannelsNotification = isPreChannelsNotification();
+        mSound = calculateSound();
+        mVibration = calculateVibration();
+        mAttributes = calculateAttributes();
+        mImportance = calculateImportance();
     }
 
-    private int defaultImportance() {
+    private boolean isPreChannelsNotification() {
+        try {
+            if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(getChannel().getId())) {
+                final ApplicationInfo applicationInfo =
+                        mContext.getPackageManager().getApplicationInfoAsUser(sbn.getPackageName(),
+                                0, sbn.getUserId());
+                if (applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+                    return true;
+                }
+            }
+        } catch (NameNotFoundException e) {
+            Slog.e(TAG, "Can't find package", e);
+        }
+        return false;
+    }
+
+    private Uri calculateSound() {
         final Notification n = sbn.getNotification();
-        int importance = IMPORTANCE_DEFAULT;
+
+        Uri sound = sbn.getNotificationChannel().getSound();
+        if (mPreChannelsNotification && (getChannel().getUserLockedFields()
+                & NotificationChannel.USER_LOCKED_SOUND) == 0) {
+
+            final boolean useDefaultSound = (n.defaults & Notification.DEFAULT_SOUND) != 0;
+            if (useDefaultSound) {
+                sound = Settings.System.DEFAULT_NOTIFICATION_URI;
+            } else if (n.sound != null) {
+                sound = n.sound;
+            }
+        }
+        return sound;
+    }
+
+    private long[] calculateVibration() {
+        long[] vibration;
+        final long[] defaultVibration =  NotificationManagerService.getLongArray(
+                mContext.getResources(),
+                com.android.internal.R.array.config_defaultNotificationVibePattern,
+                NotificationManagerService.VIBRATE_PATTERN_MAXLEN,
+                NotificationManagerService.DEFAULT_VIBRATE_PATTERN);
+        if (getChannel().shouldVibrate()) {
+            vibration = defaultVibration;
+        } else {
+            vibration = null;
+        }
+        if (mPreChannelsNotification
+                && (getChannel().getUserLockedFields()
+                & NotificationChannel.USER_LOCKED_VIBRATION) == 0) {
+            final Notification notification = sbn.getNotification();
+            final boolean useDefaultVibrate =
+                    (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
+            if (useDefaultVibrate) {
+                vibration = defaultVibration;
+            } else {
+                vibration = notification.vibrate;
+            }
+        }
+        return vibration;
+    }
+
+    private AudioAttributes calculateAttributes() {
+        final Notification n = sbn.getNotification();
+        AudioAttributes attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
+
+        if (n.audioAttributes != null) {
+            // prefer audio attributes to stream type
+            attributes = n.audioAttributes;
+        } else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
+            // the stream type is valid, use it
+            attributes = new AudioAttributes.Builder()
+                    .setInternalLegacyStreamType(n.audioStreamType)
+                    .build();
+        } else if (n.audioStreamType != AudioSystem.STREAM_DEFAULT) {
+            Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
+        }
+        return attributes;
+    }
+
+    private int calculateImportance() {
+        final Notification n = sbn.getNotification();
+        int importance = getChannel().getImportance();
+        int requestedImportance = IMPORTANCE_DEFAULT;
 
         // Migrate notification flags to scores
         if (0 != (n.flags & Notification.FLAG_HIGH_PRIORITY)) {
@@ -125,41 +218,39 @@
 
         switch (n.priority) {
             case Notification.PRIORITY_MIN:
-                importance = IMPORTANCE_MIN;
+                requestedImportance = IMPORTANCE_MIN;
                 break;
             case Notification.PRIORITY_LOW:
-                importance = IMPORTANCE_LOW;
+                requestedImportance = IMPORTANCE_LOW;
                 break;
             case Notification.PRIORITY_DEFAULT:
-                importance = IMPORTANCE_DEFAULT;
+                requestedImportance = IMPORTANCE_DEFAULT;
                 break;
             case Notification.PRIORITY_HIGH:
             case Notification.PRIORITY_MAX:
-                importance = IMPORTANCE_HIGH;
+                requestedImportance = IMPORTANCE_HIGH;
                 break;
         }
-        stats.requestedImportance = importance;
+        stats.requestedImportance = requestedImportance;
+        stats.isNoisy = mSound != null || mVibration != null;
 
-        boolean isNoisy = (n.defaults & Notification.DEFAULT_SOUND) != 0
-                || (n.defaults & Notification.DEFAULT_VIBRATE) != 0
-                || n.sound != null
-                || n.vibrate != null
-                || sbn.getNotificationChannel().shouldVibrate()
-                || sbn.getNotificationChannel().getRingtone() != null;
-        stats.isNoisy = isNoisy;
-
-        if (!isNoisy && importance > IMPORTANCE_LOW) {
-            importance = IMPORTANCE_LOW;
-        }
-
-        if (isNoisy) {
-            if (importance < IMPORTANCE_DEFAULT) {
-                importance = IMPORTANCE_DEFAULT;
+        if (mPreChannelsNotification
+                && (getChannel().getUserLockedFields()
+                & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0) {
+            if (!stats.isNoisy && requestedImportance > IMPORTANCE_LOW) {
+                requestedImportance = IMPORTANCE_LOW;
             }
-        }
 
-        if (n.fullScreenIntent != null) {
-            importance = IMPORTANCE_HIGH;
+            if (stats.isNoisy) {
+                if (requestedImportance < IMPORTANCE_DEFAULT) {
+                    requestedImportance = IMPORTANCE_DEFAULT;
+                }
+            }
+
+            if (n.fullScreenIntent != null) {
+                requestedImportance = IMPORTANCE_HIGH;
+            }
+            importance = requestedImportance;
         }
 
         stats.naturalImportance = importance;
@@ -284,6 +375,9 @@
         pw.println(prefix + "  mUpdateTimeMs=" + mUpdateTimeMs);
         pw.println(prefix + "  mSuppressedVisualEffects= " + mSuppressedVisualEffects);
         pw.println(prefix + "  notificationChannel= " + notification.getChannel());
+        pw.println(prefix + "  mSound= " + mSound);
+        pw.println(prefix + "  mVibration= " + mVibration);
+        pw.println(prefix + "  mAttributes= " + mAttributes);
     }
 
 
@@ -362,16 +456,16 @@
 
     private String getUserExplanation() {
         if (mUserExplanation == null) {
-            mUserExplanation =
-                    mContext.getString(com.android.internal.R.string.importance_from_user);
+            mUserExplanation = mContext.getResources().getString(
+                    com.android.internal.R.string.importance_from_user);
         }
         return mUserExplanation;
     }
 
     private String getPeopleExplanation() {
         if (mPeopleExplanation == null) {
-            mPeopleExplanation =
-                    mContext.getString(com.android.internal.R.string.importance_from_person);
+            mPeopleExplanation = mContext.getResources().getString(
+                    com.android.internal.R.string.importance_from_person);
         }
         return mPeopleExplanation;
     }
@@ -533,4 +627,16 @@
     public NotificationChannel getChannel() {
         return sbn.getNotificationChannel();
     }
+
+    public Uri getSound() {
+        return mSound;
+    }
+
+    public long[] getVibration() {
+        return mVibration;
+    }
+
+    public AudioAttributes getAudioAttributes() {
+        return mAttributes;
+    }
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index d65ea7f..90b3715 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -497,8 +497,8 @@
         if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_PRIORITY) == 0) {
             channel.setBypassDnd(updatedChannel.canBypassDnd());
         }
-        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_RINGTONE) == 0) {
-            channel.setRingtone(updatedChannel.getRingtone());
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_SOUND) == 0) {
+            channel.setSound(updatedChannel.getSound());
         }
         if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_VIBRATION) == 0) {
             channel.setVibration(updatedChannel.shouldVibrate());
diff --git a/services/core/java/com/android/server/pm/EphemeralResolver.java b/services/core/java/com/android/server/pm/EphemeralResolver.java
new file mode 100644
index 0000000..7ddd058
--- /dev/null
+++ b/services/core/java/com/android/server/pm/EphemeralResolver.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.EphemeralIntentFilter;
+import android.content.pm.EphemeralRequest;
+import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.EphemeralResponse;
+import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.pm.EphemeralResolverConnection.PhaseTwoCallback;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/** @hide */
+public abstract class EphemeralResolver {
+
+    /** TODO b/30204367 remove when the platform fully supports ephemeral applications */
+    public static final boolean USE_DEFAULT_EPHEMERAL_LAUNCHER = false;
+
+    public static EphemeralResponse doEphemeralResolutionPhaseOne(Context context,
+            EphemeralResolverConnection connection, EphemeralRequest requestObj) {
+        final Intent intent = requestObj.origIntent;
+        final EphemeralDigest digest =
+                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
+        final int[] shaPrefix = digest.getDigestPrefix();
+        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
+                connection.getEphemeralResolveInfoList(shaPrefix);
+        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
+            // No hash prefix match; there are no ephemeral apps for this domain.
+            return null;
+        }
+
+        final String token = UUID.randomUUID().toString();
+        return EphemeralResolver.filterEphemeralIntent(ephemeralResolveInfoList,
+                intent, requestObj.resolvedType, requestObj.userId,
+                intent.getPackage(), digest, token);
+    }
+
+    public static void doEphemeralResolutionPhaseTwo(Context context,
+            EphemeralResolverConnection connection, EphemeralRequest requestObj,
+            ActivityInfo ephemeralInstaller, Handler callbackHandler) {
+        final Intent intent = requestObj.origIntent;
+        final String hostName = intent.getData().getHost();
+        final EphemeralDigest digest = new EphemeralDigest(hostName, 5 /*maxDigests*/);
+
+        final PhaseTwoCallback callback = new PhaseTwoCallback() {
+            @Override
+            void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo,
+                    int sequence) {
+                final String packageName;
+                final String splitName;
+                if (ephemeralResolveInfo != null) {
+                    final ArrayList<EphemeralResolveInfo> ephemeralResolveInfoList =
+                            new ArrayList<EphemeralResolveInfo>(1);
+                    ephemeralResolveInfoList.add(ephemeralResolveInfo);
+                    final EphemeralResponse ephemeralIntentInfo =
+                            EphemeralResolver.filterEphemeralIntent(
+                                    ephemeralResolveInfoList, intent, null /*resolvedType*/,
+                                    0 /*userId*/, intent.getPackage(), digest,
+                                    requestObj.responseObj.token);
+                    if (ephemeralIntentInfo != null
+                            && ephemeralIntentInfo.resolveInfo != null) {
+                        packageName = ephemeralIntentInfo.resolveInfo.getPackageName();
+                        splitName = ephemeralIntentInfo.splitName;
+                    } else {
+                        packageName = null;
+                        splitName = null;
+                    }
+                } else {
+                    packageName = null;
+                    splitName = null;
+                }
+                final Intent installerIntent = buildEphemeralInstallerIntent(
+                        requestObj.launchIntent,
+                        requestObj.origIntent,
+                        requestObj.callingPackage,
+                        requestObj.resolvedType,
+                        requestObj.userId,
+                        packageName,
+                        splitName,
+                        requestObj.responseObj.token,
+                        false /*needsPhaseTwo*/);
+                installerIntent.setComponent(new ComponentName(
+                        ephemeralInstaller.packageName, ephemeralInstaller.name));
+                context.startActivity(installerIntent);
+            }
+        };
+        connection.getEphemeralIntentFilterList(
+                hostName, callback, callbackHandler, 0 /*sequence*/);
+    }
+
+    /**
+     * Builds and returns an intent to launch the ephemeral installer.
+     */
+    public static Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent,
+            String callingPackage, String resolvedType, int userId, String ephemeralPackageName,
+            String ephemeralSplitName, String token, boolean needsPhaseTwo) {
+        // Construct the intent that launches the ephemeral installer
+        int flags = launchIntent.getFlags();
+        final Intent intent = new Intent();
+        intent.setFlags(flags
+                | Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_CLEAR_TASK
+                | Intent.FLAG_ACTIVITY_NO_HISTORY
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        // TODO: Remove when the platform has fully implemented ephemeral apps
+        intent.setData(origIntent.getData().buildUpon().clearQuery().build());
+        intent.putExtra(Intent.EXTRA_EPHEMERAL_TOKEN, token);
+        intent.putExtra(Intent.EXTRA_EPHEMERAL_HOSTNAME, origIntent.getData().getHost());
+
+        if (!needsPhaseTwo) {
+            // We have all of the data we need; just start the installer without a second phase
+            final Intent nonEphemeralIntent = new Intent(origIntent);
+            nonEphemeralIntent.setFlags(
+                    nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+            // Intent that is launched if the ephemeral package couldn't be installed
+            // for any reason.
+            try {
+                final IIntentSender failureIntentTarget = ActivityManagerNative.getDefault()
+                        .getIntentSender(
+                                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+                                null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
+                                new Intent[] { nonEphemeralIntent },
+                                new String[] { resolvedType },
+                                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+                                        | PendingIntent.FLAG_IMMUTABLE,
+                                null /*bOptions*/, userId);
+                intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE,
+                        new IntentSender(failureIntentTarget));
+            } catch (RemoteException ignore) { /* ignore; same process */ }
+
+            final Intent ephemeralIntent;
+            if (EphemeralResolver.USE_DEFAULT_EPHEMERAL_LAUNCHER) {
+                // Force the intent to be directed to the ephemeral package
+                ephemeralIntent = new Intent(origIntent);
+                ephemeralIntent.setPackage(ephemeralPackageName);
+            } else {
+                // Success intent goes back to the installer
+                ephemeralIntent = new Intent(launchIntent);
+            }
+
+            // Intent that is eventually launched if the ephemeral package was
+            // installed successfully. This will actually be launched by a platform
+            // broadcast receiver.
+            try {
+                final IIntentSender successIntentTarget = ActivityManagerNative.getDefault()
+                        .getIntentSender(
+                                ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+                                null /*token*/, null /*resultWho*/, 0 /*requestCode*/,
+                                new Intent[] { ephemeralIntent },
+                                new String[] { resolvedType },
+                                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+                                        | PendingIntent.FLAG_IMMUTABLE,
+                                null /*bOptions*/, userId);
+                intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS,
+                        new IntentSender(successIntentTarget));
+            } catch (RemoteException ignore) { /* ignore; same process */ }
+
+            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName);
+            intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName);
+        }
+
+        return intent;
+    }
+
+    private static EphemeralResponse filterEphemeralIntent(
+            List<EphemeralResolveInfo> ephemeralResolveInfoList,
+            Intent intent, String resolvedType, int userId, String packageName,
+            EphemeralDigest digest, String token) {
+        final int[] shaPrefix = digest.getDigestPrefix();
+        final byte[][] digestBytes = digest.getDigestBytes();
+        // Go in reverse order so we match the narrowest scope first.
+        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
+            for (EphemeralResolveInfo ephemeralInfo : ephemeralResolveInfoList) {
+                if (!Arrays.equals(digestBytes[i], ephemeralInfo.getDigestBytes())) {
+                    continue;
+                }
+                if (packageName != null
+                        && !packageName.equals(ephemeralInfo.getPackageName())) {
+                    continue;
+                }
+                final List<EphemeralIntentFilter> ephemeralFilters =
+                        ephemeralInfo.getIntentFilters();
+                // No filters; we need to start phase two
+                if (ephemeralFilters == null || ephemeralFilters.isEmpty()) {
+                    return new EphemeralResponse(ephemeralInfo,
+                            new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
+                            null /*splitName*/, token, true /*needsPhase2*/);
+                }
+                // We have a domain match; resolve the filters to see if anything matches.
+                final PackageManagerService.EphemeralIntentResolver ephemeralResolver =
+                        new PackageManagerService.EphemeralIntentResolver();
+                for (int j = ephemeralFilters.size() - 1; j >= 0; --j) {
+                    final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j);
+                    final List<IntentFilter> splitFilters = ephemeralFilter.getFilters();
+                    if (splitFilters == null || splitFilters.isEmpty()) {
+                        continue;
+                    }
+                    for (int k = splitFilters.size() - 1; k >= 0; --k) {
+                        final EphemeralResponse intentInfo =
+                                new EphemeralResponse(ephemeralInfo,
+                                        splitFilters.get(k), ephemeralFilter.getSplitName(),
+                                        token, false /*needsPhase2*/);
+                        ephemeralResolver.addFilter(intentInfo);
+                    }
+                }
+                List<EphemeralResponse> matchedResolveInfoList = ephemeralResolver
+                        .queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
+                if (!matchedResolveInfoList.isEmpty()) {
+                    return matchedResolveInfoList.get(0);
+                }
+            }
+        }
+        // Hash or filter mis-match; no ephemeral apps for this domain.
+        return null;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index ecc03d7..2b6ce10 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -23,8 +23,10 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.EphemeralResolveInfo;
+import android.content.pm.EphemeralResponse;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -54,8 +56,6 @@
     private final Object mLock = new Object();
     private final GetEphemeralResolveInfoCaller mGetEphemeralResolveInfoCaller =
             new GetEphemeralResolveInfoCaller();
-    private final GetEphemeralIntentFilterCaller mGetEphemeralIntentFilterCaller =
-            new GetEphemeralIntentFilterCaller();
     private final ServiceConnection mServiceConnection = new MyServiceConnection();
     private final Context mContext;
     /** Intent used to bind to the service */
@@ -84,19 +84,27 @@
         return null;
     }
 
-    public final List<EphemeralResolveInfo> getEphemeralIntentFilterList(int digestPrefix[]) {
-        throwIfCalledOnMainThread();
+    public final void getEphemeralIntentFilterList(String hostName, PhaseTwoCallback callback,
+            Handler callbackHandler, final int sequence) {
+        final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
+            @Override
+            public void sendResult(Bundle data) throws RemoteException {
+                final EphemeralResolveInfo ephemeralResolveInfo =
+                        data.getParcelable(EphemeralResolverService.EXTRA_RESOLVE_INFO);
+                callbackHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onPhaseTwoResolved(ephemeralResolveInfo, sequence);
+                    }
+                });
+            }
+        };
         try {
-            return mGetEphemeralIntentFilterCaller.getEphemeralIntentFilterList(
-                    getRemoteInstanceLazy(), digestPrefix);
+            getRemoteInstanceLazy()
+                    .getEphemeralIntentFilterList(remoteCallback, hostName, sequence);
         } catch (RemoteException re) {
         } catch (TimeoutException te) {
-        } finally {
-            synchronized (mLock) {
-                mLock.notifyAll();
-            }
         }
-        return null;
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
@@ -161,6 +169,13 @@
         }
     }
 
+    /**
+     * Asynchronous callback when results come back from ephemeral resolution phase two.
+     */
+    public abstract static class PhaseTwoCallback {
+        abstract void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo, int sequence);
+    }
+
     private final class MyServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -205,32 +220,4 @@
             return getResultTimed(sequence);
         }
     }
-
-    private static final class GetEphemeralIntentFilterCaller
-            extends TimedRemoteCaller<List<EphemeralResolveInfo>> {
-        private final IRemoteCallback mCallback;
-
-        public GetEphemeralIntentFilterCaller() {
-            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
-            mCallback = new IRemoteCallback.Stub() {
-                @Override
-                public void sendResult(Bundle data) throws RemoteException {
-                    final ArrayList<EphemeralResolveInfo> resolveList =
-                            data.getParcelableArrayList(
-                                    EphemeralResolverService.EXTRA_RESOLVE_INFO);
-                    int sequence =
-                            data.getInt(EphemeralResolverService.EXTRA_SEQUENCE, -1);
-                    onRemoteMethodResult(resolveList, sequence);
-                }
-            };
-        }
-
-        public List<EphemeralResolveInfo> getEphemeralIntentFilterList(
-                IEphemeralResolver target, int digestPrefix[])
-                        throws RemoteException, TimeoutException {
-            final int sequence = onBeforeRemoteCall();
-            target.getEphemeralIntentFilterList(mCallback, digestPrefix, sequence);
-            return getResultTimed(sequence);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 79ef486..ee3f42b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -101,7 +101,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.ResourcesManager;
 import android.app.admin.IDevicePolicyManager;
@@ -122,10 +121,9 @@
 import android.content.pm.AppsQueryHelper;
 import android.content.pm.ComponentInfo;
 import android.content.pm.EphemeralApplicationInfo;
-import android.content.pm.EphemeralIntentFilter;
+import android.content.pm.EphemeralRequest;
 import android.content.pm.EphemeralResolveInfo;
-import android.content.pm.EphemeralResolveInfo.EphemeralDigest;
-import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
+import android.content.pm.EphemeralResponse;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
@@ -193,8 +191,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
-import android.os.storage.IMountService;
-import android.os.storage.MountServiceInternal;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManagerInternal;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
@@ -209,6 +207,7 @@
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Base64;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.ExceptionUtils;
@@ -234,6 +233,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.IParcelFileDescriptorFactory;
 import com.android.internal.os.InstallerConnection.InstallerException;
+import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.Zygote;
 import com.android.internal.telephony.CarrierAppUtils;
@@ -286,6 +286,7 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
@@ -337,7 +338,7 @@
  *
  * <pre>
  * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
- * $ cts-tradefed run commandAndExit cts -m AppSecurityTests
+ * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
  * </pre>
  */
 public class PackageManagerService extends IPackageManager.Stub {
@@ -1067,6 +1068,7 @@
     static final int START_INTENT_FILTER_VERIFICATIONS = 17;
     static final int INTENT_FILTER_VERIFIED = 18;
     static final int WRITE_PACKAGE_LIST = 19;
+    static final int EPHEMERAL_RESOLUTION_PHASE_TWO = 20;
 
     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
 
@@ -1470,10 +1472,11 @@
                     }
                     if (reportStatus) {
                         try {
-                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
-                            PackageHelper.getMountService().finishMediaUpdate();
+                            if (DEBUG_SD_INSTALL) Log.i(TAG,
+                                    "Invoking StorageManagerService call back");
+                            PackageHelper.getStorageManager().finishMediaUpdate();
                         } catch (RemoteException e) {
-                            Log.e(TAG, "MountService not running?");
+                            Log.e(TAG, "StorageManagerService not running?");
                         }
                     }
                 } break;
@@ -1636,6 +1639,13 @@
 
                     break;
                 }
+                case EPHEMERAL_RESOLUTION_PHASE_TWO: {
+                    EphemeralResolver.doEphemeralResolutionPhaseTwo(mContext,
+                            mEphemeralResolverConnection,
+                            (EphemeralRequest) msg.obj,
+                            mEphemeralInstallerActivity,
+                            mHandler);
+                }
             }
         }
     }
@@ -1878,6 +1888,11 @@
                     Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
                     deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
                             UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
+
+                    // Try very hard to release any references to this package
+                    // so we don't risk the system server being killed due to
+                    // open FDs
+                    AttributeCache.instance().removePackage(ps.name);
                 }
 
                 mSettings.onVolumeForgotten(fsUuid);
@@ -4133,9 +4148,9 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 if (sUserManager.isInitialized(userId)) {
-                    MountServiceInternal mountServiceInternal = LocalServices.getService(
-                            MountServiceInternal.class);
-                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
+                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                            StorageManagerInternal.class);
+                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -4536,7 +4551,7 @@
     private void killUid(int appId, int userId, String reason) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 try {
                     am.killUid(appId, userId, reason);
@@ -4943,60 +4958,13 @@
         return true;
     }
 
-    private static EphemeralResolveIntentInfo getEphemeralIntentInfo(
-            Context context, EphemeralResolverConnection resolverConnection, Intent intent,
-            String resolvedType, int userId, String packageName) {
-        final EphemeralDigest digest =
-                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
-        final int[] shaPrefix = digest.getDigestPrefix();
-        final byte[][] digestBytes = digest.getDigestBytes();
-        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
-                resolverConnection.getEphemeralResolveInfoList(shaPrefix);
-        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
-            // No hash prefix match; there are no ephemeral apps for this domain.
-            return null;
-        }
-
-        // Go in reverse order so we match the narrowest scope first.
-        for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
-            for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) {
-                if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) {
-                    continue;
-                }
-                final List<EphemeralIntentFilter> ephemeralFilters =
-                        ephemeralApplication.getIntentFilters();
-                // No filters; this should never happen.
-                if (ephemeralFilters.isEmpty()) {
-                    continue;
-                }
-                if (packageName != null
-                        && !packageName.equals(ephemeralApplication.getPackageName())) {
-                    continue;
-                }
-                // We have a domain match; resolve the filters to see if anything matches.
-                final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
-                for (int j = ephemeralFilters.size() - 1; j >= 0; --j) {
-                    final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j);
-                    final List<IntentFilter> splitFilters = ephemeralFilter.getFilters();
-                    if (splitFilters == null || splitFilters.isEmpty()) {
-                        continue;
-                    }
-                    for (int k = splitFilters.size() - 1; k >= 0; --k) {
-                        final EphemeralResolveIntentInfo intentInfo =
-                                new EphemeralResolveIntentInfo(splitFilters.get(k),
-                                        ephemeralApplication, ephemeralFilter.getSplitName());
-                        ephemeralResolver.addFilter(intentInfo);
-                    }
-                }
-                List<EphemeralResolveIntentInfo> matchedResolveInfoList = ephemeralResolver
-                        .queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
-                if (!matchedResolveInfoList.isEmpty()) {
-                    return matchedResolveInfoList.get(0);
-                }
-            }
-        }
-        // Hash or filter mis-match; no ephemeral apps for this domain.
-        return null;
+    private void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+            Intent origIntent, String resolvedType, Intent launchIntent, String callingPackage,
+            int userId) {
+        final Message msg = mHandler.obtainMessage(EPHEMERAL_RESOLUTION_PHASE_TWO,
+                new EphemeralRequest(responseObj, origIntent, resolvedType, launchIntent,
+                        callingPackage, userId));
+        mHandler.sendMessage(msg);
     }
 
     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
@@ -5472,15 +5440,17 @@
         }
         if (addEphemeral) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
-            final EphemeralResolveIntentInfo intentInfo = getEphemeralIntentInfo(
-                    mContext, mEphemeralResolverConnection, intent, resolvedType, userId,
-                    matchEphemeralPackage ? pkgName : null);
+            final EphemeralRequest requestObject = new EphemeralRequest(
+                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
+                    null /*launchIntent*/, null /*callingPackage*/, userId);
+            final EphemeralResponse intentInfo = EphemeralResolver.doEphemeralResolutionPhaseOne(
+                    mContext, mEphemeralResolverConnection, requestObject);
             if (intentInfo != null) {
                 if (DEBUG_EPHEMERAL) {
                     Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                 }
                 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo);
-                ephemeralInstaller.ephemeralIntentInfo = intentInfo;
+                ephemeralInstaller.ephemeralResponse = intentInfo;
                 // make sure this resolver is the default
                 ephemeralInstaller.isDefault = true;
                 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7238,15 +7208,15 @@
 
         // Before everything else, see whether we need to fstrim.
         try {
-            IMountService ms = PackageHelper.getMountService();
-            if (ms != null) {
+            IStorageManager sm = PackageHelper.getStorageManager();
+            if (sm != null) {
                 boolean doTrim = false;
                 final long interval = android.provider.Settings.Global.getLong(
                         mContext.getContentResolver(),
                         android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
                         DEFAULT_MANDATORY_FSTRIM_INTERVAL);
                 if (interval > 0) {
-                    final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
+                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
                     if (timeSinceLast > interval) {
                         doTrim = true;
                         Slog.w(TAG, "No disk maintenance in " + timeSinceLast
@@ -7260,19 +7230,19 @@
                     }
                     if (!isFirstBoot() && dexOptDialogShown) {
                         try {
-                            ActivityManagerNative.getDefault().showBootMessage(
+                            ActivityManager.getService().showBootMessage(
                                     mContext.getResources().getString(
                                             R.string.android_upgrading_fstrim), true);
                         } catch (RemoteException e) {
                         }
                     }
-                    ms.runMaintenance();
+                    sm.runMaintenance();
                 }
             } else {
-                Slog.e(TAG, "Mount service unavailable!");
+                Slog.e(TAG, "storageManager service unavailable!");
             }
         } catch (RemoteException e) {
-            // Can't happen; MountService is local
+            // Can't happen; StorageManagerService is local
         }
     }
 
@@ -7347,7 +7317,7 @@
 
             if (showDialog) {
                 try {
-                    ActivityManagerNative.getDefault().showBootMessage(
+                    ActivityManager.getService().showBootMessage(
                             mContext.getResources().getString(R.string.android_upgrading_apk,
                                     numberOfPackagesVisited, numberOfPackagesToDexopt), true);
                 } catch (RemoteException e) {
@@ -9695,7 +9665,7 @@
         // version of the application while the new one gets installed.
         final long token = Binder.clearCallingIdentity();
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 try {
                     am.killApplication(pkgName, appId, userId, reason);
@@ -10395,14 +10365,28 @@
 
     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
             BasePermission bp, PermissionsState origPermissions) {
-        boolean allowed;
-        allowed = (compareSignatures(
+        boolean privilegedPermission = (bp.protectionLevel
+                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
+        boolean controlPrivappPermissions = RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS;
+        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
+        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
+        if (controlPrivappPermissions && privilegedPermission && pkg.isPrivilegedApp()
+                && !platformPackage && platformPermission) {
+            ArraySet<String> wlPermissions = SystemConfig.getInstance()
+                    .getPrivAppPermissions(pkg.packageName);
+            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
+            if (!whitelisted) {
+                // Log for now. TODO Enforce permissions
+                Slog.w(TAG, "Privileged permission " + perm + " for package "
+                        + pkg.packageName + " - not in privapp-permissions whitelist");
+            }
+        }
+        boolean allowed = (compareSignatures(
                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
                         == PackageManager.SIGNATURE_MATCH)
                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
                         == PackageManager.SIGNATURE_MATCH);
-        if (!allowed && (bp.protectionLevel
-                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
+        if (!allowed && privilegedPermission) {
             if (isSystemApp(pkg)) {
                 // For updated system applications, a system permission
                 // is granted only if it had been defined by the original application.
@@ -11453,8 +11437,8 @@
         private int mFlags;
     }
 
-    private static final class EphemeralIntentResolver
-            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveIntentInfo> {
+    static final class EphemeralIntentResolver
+            extends IntentResolver<EphemeralResponse, EphemeralResponse> {
         /**
          * The result that has the highest defined order. Ordering applies on a
          * per-package basis. Mapping is from package name to Pair of order and
@@ -11469,46 +11453,46 @@
         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
 
         @Override
-        protected EphemeralResolveIntentInfo[] newArray(int size) {
-            return new EphemeralResolveIntentInfo[size];
+        protected EphemeralResponse[] newArray(int size) {
+            return new EphemeralResponse[size];
         }
 
         @Override
-        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
+        protected boolean isPackageForFilter(String packageName, EphemeralResponse responseObj) {
             return true;
         }
 
         @Override
-        protected EphemeralResolveIntentInfo newResult(EphemeralResolveIntentInfo info, int match,
+        protected EphemeralResponse newResult(EphemeralResponse responseObj, int match,
                 int userId) {
             if (!sUserManager.exists(userId)) {
                 return null;
             }
-            final String packageName = info.getEphemeralResolveInfo().getPackageName();
-            final Integer order = info.getOrder();
+            final String packageName = responseObj.resolveInfo.getPackageName();
+            final Integer order = responseObj.getOrder();
             final Pair<Integer, EphemeralResolveInfo> lastOrderResult =
                     mOrderResult.get(packageName);
             // ordering is enabled and this item's order isn't high enough
             if (lastOrderResult != null && lastOrderResult.first >= order) {
                 return null;
             }
-            final EphemeralResolveInfo res = info.getEphemeralResolveInfo();
+            final EphemeralResolveInfo res = responseObj.resolveInfo;
             if (order > 0) {
                 // non-zero order, enable ordering
                 mOrderResult.put(packageName, new Pair<>(order, res));
             }
-            return info;
+            return responseObj;
         }
 
         @Override
-        protected void filterResults(List<EphemeralResolveIntentInfo> results) {
+        protected void filterResults(List<EphemeralResponse> results) {
             // only do work if ordering is enabled [most of the time it won't be]
             if (mOrderResult.size() == 0) {
                 return;
             }
             int resultSize = results.size();
             for (int i = 0; i < resultSize; i++) {
-                final EphemeralResolveInfo info = results.get(i).getEphemeralResolveInfo();
+                final EphemeralResolveInfo info = results.get(i).resolveInfo;
                 final String packageName = info.getPackageName();
                 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName);
                 if (savedInfo == null) {
@@ -11587,7 +11571,7 @@
             @Override
             public void run() {
                 try {
-                    final IActivityManager am = ActivityManagerNative.getDefault();
+                    final IActivityManager am = ActivityManager.getService();
                     if (am == null) return;
                     final int[] resolvedUserIds;
                     if (userIds == null) {
@@ -11684,7 +11668,7 @@
         }
         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
-        IActivityManager am = ActivityManagerNative.getDefault();
+        IActivityManager am = ActivityManager.getService();
         if (am != null) {
             try {
                 am.startService(null, intent, null, mContext.getOpPackageName(),
@@ -11834,7 +11818,7 @@
         if (!mUserManagerInternal.isUserRunning(userId)) {
             return;
         }
-        final IActivityManager am = ActivityManagerNative.getDefault();
+        final IActivityManager am = ActivityManager.getService();
         try {
             // Deliver LOCKED_BOOT_COMPLETED first
             Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
@@ -13796,7 +13780,7 @@
     }
 
     /**
-     * Extract the MountService "container ID" from the full code path of an
+     * Extract the StorageManagerService "container ID" from the full code path of an
      * .apk.
      */
     static String cidFromCodePath(String fullCodePath) {
@@ -14261,11 +14245,13 @@
     }
 
     private File getNextCodePath(File targetDir, String packageName) {
-        int suffix = 1;
         File result;
+        SecureRandom random = new SecureRandom();
+        byte[] bytes = new byte[16];
         do {
+            random.nextBytes(bytes);
+            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
             result = new File(targetDir, packageName + "-" + suffix);
-            suffix++;
         } while (result.exists());
         return result;
     }
@@ -17125,7 +17111,7 @@
 
     private void postPreferredActivityChangedBroadcast(int userId) {
         mHandler.post(() -> {
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             if (am == null) {
                 return;
             }
@@ -18397,10 +18383,10 @@
         mInstallerService.systemReady();
         mPackageDexOptimizer.systemReady();
 
-        MountServiceInternal mountServiceInternal = LocalServices.getService(
-                MountServiceInternal.class);
-        mountServiceInternal.addExternalStoragePolicy(
-                new MountServiceInternal.ExternalStorageMountPolicy() {
+        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
+                StorageManagerInternal.class);
+        StorageManagerInternal.addExternalStoragePolicy(
+                new StorageManagerInternal.ExternalStorageMountPolicy() {
             @Override
             public int getMountMode(int uid, String packageName) {
                 if (Process.isIsolated(uid)) {
@@ -19278,7 +19264,7 @@
     }
 
     /**
-     * Called by MountService when the initial ASECs to scan are available.
+     * Called by StorageManagerService when the initial ASECs to scan are available.
      * Should block until all the ASEC containers are finished being scanned.
      */
     public void scanAvailableAsecs() {
@@ -20790,7 +20776,7 @@
             }
             // kill any non-foreground processes so we restart them and
             // grant/revoke the GID.
-            final IActivityManager am = ActivityManagerNative.getDefault();
+            final IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 final long token = Binder.clearCallingIdentity();
                 try {
@@ -21289,6 +21275,14 @@
         public String getNameForUid(int uid) {
             return PackageManagerService.this.getNameForUid(uid);
         }
+
+        @Override
+        public void requestEphemeralResolutionPhaseTwo(EphemeralResponse responseObj,
+                Intent origIntent, String resolvedType, Intent launchIntent,
+                String callingPackage, int userId) {
+            PackageManagerService.this.requestEphemeralResolutionPhaseTwo(
+                    responseObj, origIntent, resolvedType, launchIntent, callingPackage, userId);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 42cc3a8..eef8ce2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1415,7 +1415,6 @@
         VersionInfo ver = mVersion.get(volumeUuid);
         if (ver == null) {
             ver = new VersionInfo();
-            ver.forceCurrent();
             mVersion.put(volumeUuid, ver);
         }
         return ver;
@@ -2802,8 +2801,8 @@
                             "No settings file; creating initial state");
                     // It's enough to just touch version details to create them
                     // with default values
-                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL);
-                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL);
+                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
+                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
                     return false;
                 }
                 str = new FileInputStream(mSettingsFilename);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 5a0bee1..7b877f7 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -21,7 +21,6 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IUidObserver;
 import android.app.usage.UsageStatsManagerInternal;
@@ -3669,7 +3668,7 @@
     @VisibleForTesting
     void injectRegisterUidObserver(IUidObserver observer, int which) {
         try {
-            ActivityManagerNative.getDefault().registerUidObserver(observer, which,
+            ActivityManager.getService().registerUidObserver(observer, which,
                     ActivityManager.PROCESS_STATE_UNKNOWN, null);
         } catch (RemoteException shouldntHappen) {
         }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 67488ce..5b47b6f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -26,7 +26,6 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
@@ -757,11 +756,11 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 if (enableQuietMode) {
-                    ActivityManagerNative.getDefault().stopUser(userHandle, /* force */true, null);
+                    ActivityManager.getService().stopUser(userHandle, /* force */true, null);
                     LocalServices.getService(ActivityManagerInternal.class)
                             .killForegroundAppsForUser(userHandle);
                 } else {
-                    ActivityManagerNative.getDefault().startUserInBackground(userHandle);
+                    ActivityManager.getService().startUserInBackground(userHandle);
                 }
             } catch (RemoteException e) {
                 Slog.e(LOG_TAG, "fail to start/stop user for quiet mode", e);
@@ -1414,7 +1413,7 @@
         // First, invalidate all cached values.
         mCachedEffectiveUserRestrictions.clear();
 
-        // We don't want to call into ActivityManagerNative while taking a lock, so we'll call
+        // We don't want to call into ActivityManagerService while taking a lock, so we'll call
         // it on a handler.
         final Runnable r = new Runnable() {
             @Override
@@ -1422,9 +1421,9 @@
                 // Then get the list of running users.
                 final int[] runningUsers;
                 try {
-                    runningUsers = ActivityManagerNative.getDefault().getRunningUserIds();
+                    runningUsers = ActivityManager.getService().getRunningUserIds();
                 } catch (RemoteException e) {
-                    Log.w(LOG_TAG, "Unable to access ActivityManagerNative");
+                    Log.w(LOG_TAG, "Unable to access ActivityManagerService");
                     return;
                 }
                 // Then re-calculate the effective restrictions and apply, only for running users.
@@ -2536,7 +2535,7 @@
             if (DBG) Slog.i(LOG_TAG, "Stopping user " + userHandle);
             int res;
             try {
-                res = ActivityManagerNative.getDefault().stopUser(userHandle, /* force= */ true,
+                res = ActivityManager.getService().stopUser(userHandle, /* force= */ true,
                 new IStopUserCallback.Stub() {
                             @Override
                             public void userStopped(int userId) {
@@ -3259,7 +3258,7 @@
     }
 
     private int runList(PrintWriter pw) throws RemoteException {
-        final IActivityManager am = ActivityManagerNative.getDefault();
+        final IActivityManager am = ActivityManager.getService();
         final List<UserInfo> users = getUsers(false);
         if (users == null) {
             pw.println("Error: couldn't get users");
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 3df13a9..9fe0922 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -23,7 +23,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.Binder;
@@ -411,7 +410,7 @@
                         int currentUser = ActivityManager.getCurrentUser();
                         if (currentUser != userId && userId != UserHandle.USER_SYSTEM) {
                             try {
-                                ActivityManagerNative.getDefault().stopUser(userId, false, null);
+                                ActivityManager.getService().stopUser(userId, false, null);
                             } catch (RemoteException e) {
                                 throw e.rethrowAsRuntimeException();
                             }
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index 3bea663..d4adcc4 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -27,7 +27,6 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -434,7 +433,7 @@
                         // Take an "interactive" bugreport.
                         MetricsLogger.action(mContext,
                                 MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE);
-                        ActivityManagerNative.getDefault().requestBugReport(
+                        ActivityManager.getService().requestBugReport(
                                 ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
                     } catch (RemoteException e) {
                     }
@@ -452,7 +451,7 @@
             try {
                 // Take a "full" bugreport.
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_FULL);
-                ActivityManagerNative.getDefault().requestBugReport(
+                ActivityManager.getService().requestBugReport(
                         ActivityManager.BUGREPORT_OPTION_FULL);
             } catch (RemoteException e) {
             }
@@ -592,7 +591,7 @@
 
     private UserInfo getCurrentUser() {
         try {
-            return ActivityManagerNative.getDefault().getCurrentUser();
+            return ActivityManager.getService().getCurrentUser();
         } catch (RemoteException re) {
             return null;
         }
@@ -620,7 +619,7 @@
                             + (isCurrentUser ? " \u2714" : "")) {
                         public void onPress() {
                             try {
-                                ActivityManagerNative.getDefault().switchUser(user.id);
+                                ActivityManager.getService().switchUser(user.id);
                             } catch (RemoteException re) {
                                 Log.e(TAG, "Couldn't switch user " + re);
                             }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 396c958..ccdda13 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -114,7 +114,6 @@
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
 import android.app.ProgressDialog;
@@ -2678,9 +2677,10 @@
     }
 
     @Override
-    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode) {
-        if (mHasNavigationBar) {
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        // TODO(multi-display): Support navigation bar on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) {
             // For a basic navigation bar, when we are in landscape mode we place
             // the navigation bar to the side.
             if (mNavigationBarCanMove && fullWidth > fullHeight) {
@@ -2699,9 +2699,10 @@
     }
 
     @Override
-    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode) {
-        if (mHasNavigationBar) {
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        // TODO(multi-display): Support navigation bar on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY && mHasNavigationBar) {
             // For a basic navigation bar, when we are in portrait mode we place
             // the navigation bar to the bottom.
             if (!mNavigationBarCanMove || fullWidth < fullHeight) {
@@ -2712,18 +2713,24 @@
     }
 
     @Override
-    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
-        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode);
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
+        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId);
     }
 
     @Override
-    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         // There is a separate status bar at the top of the display.  We don't count that as part
         // of the fixed decor, since it can hide; however, for purposes of configurations,
         // we do want to exclude it since applications can't generally use that part
         // of the screen.
-        return getNonDecorDisplayHeight(
-                fullWidth, fullHeight, rotation, uiMode) - mStatusBarHeight;
+        // TODO(multi-display): Support status bars on secondary displays.
+        if (displayId == Display.DEFAULT_DISPLAY) {
+            return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId)
+                    - mStatusBarHeight;
+        }
+        return fullHeight;
     }
 
     @Override
@@ -3943,7 +3950,7 @@
                     public void onKeyguardExitResult(boolean success) {
                         if (success) {
                             try {
-                                ActivityManagerNative.getDefault().stopAppSwitches();
+                                ActivityManager.getService().stopAppSwitches();
                             } catch (RemoteException e) {
                             }
                             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
@@ -3957,7 +3964,7 @@
 
         // no keyguard stuff to worry about, just launch home!
         try {
-            ActivityManagerNative.getDefault().stopAppSwitches();
+            ActivityManager.getService().stopAppSwitches();
         } catch (RemoteException e) {
         }
         if (mRecentsVisible) {
@@ -7340,7 +7347,7 @@
         if (false) {
             // This code always brings home to the front.
             try {
-                ActivityManagerNative.getDefault().stopAppSwitches();
+                ActivityManager.getService().stopAppSwitches();
             } catch (RemoteException e) {
             }
             sendCloseSystemWindows();
@@ -7353,11 +7360,11 @@
                     /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry.
                     Log.d(TAG, "UTS-TEST-MODE");
                 } else {
-                    ActivityManagerNative.getDefault().stopAppSwitches();
+                    ActivityManager.getService().stopAppSwitches();
                     sendCloseSystemWindows();
                     Intent dock = createHomeDockIntent();
                     if (dock != null) {
-                        int result = ActivityManagerNative.getDefault()
+                        int result = ActivityManager.getService()
                                 .startActivityAsUser(null, null, dock,
                                         dock.resolveTypeIfNeeded(mContext.getContentResolver()),
                                         null, null, 0,
@@ -7368,7 +7375,7 @@
                         }
                     }
                 }
-                int result = ActivityManagerNative.getDefault()
+                int result = ActivityManager.getService()
                         .startActivityAsUser(null, null, mHomeIntent,
                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                 null, null, 0,
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index ca641fb..f37f987 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,6 +1,6 @@
 package com.android.server.policy.keyguard;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -194,7 +194,7 @@
             mKeyguardState.reset();
             mHandler.post(() -> {
                 try {
-                    ActivityManagerNative.getDefault().setLockScreenShown(true);
+                    ActivityManager.getService().setLockScreenShown(true);
                 } catch (RemoteException e) {
                     // Local call.
                 }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 00700b8..b215998 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -25,7 +25,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 
-import android.app.ActivityManagerNative;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index a920d54..cd966ef 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -43,8 +43,8 @@
 import android.os.UserManager;
 import android.os.Vibrator;
 import android.os.SystemVibrator;
-import android.os.storage.IMountService;
-import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IStorageShutdownObserver;
+import android.os.storage.IStorageManager;
 import android.system.ErrnoException;
 import android.system.Os;
 
@@ -442,30 +442,30 @@
             sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);
         }
 
-        // Shutdown MountService to ensure media is in a safe state
-        IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {
+        // Shutdown StorageManagerService to ensure media is in a safe state
+        IStorageShutdownObserver observer = new IStorageShutdownObserver.Stub() {
             public void onShutDownComplete(int statusCode) throws RemoteException {
-                Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown");
+                Log.w(TAG, "Result code " + statusCode + " from StorageManagerService.shutdown");
                 actionDone();
             }
         };
 
-        Log.i(TAG, "Shutting down MountService");
+        Log.i(TAG, "Shutting down StorageManagerService");
 
         // Set initial variables and time out time.
         mActionDone = false;
         final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
         synchronized (mActionDoneSync) {
             try {
-                final IMountService mount = IMountService.Stub.asInterface(
+                final IStorageManager storageManager = IStorageManager.Stub.asInterface(
                         ServiceManager.checkService("mount"));
-                if (mount != null) {
-                    mount.shutdown(observer);
+                if (storageManager != null) {
+                    storageManager.shutdown(observer);
                 } else {
-                    Log.w(TAG, "MountService unavailable for shutdown");
+                    Log.w(TAG, "StorageManagerService unavailable for shutdown");
                 }
             } catch (Exception e) {
-                Log.e(TAG, "Exception during MountService shutdown", e);
+                Log.e(TAG, "Exception during StorageManagerService shutdown", e);
             }
             while (!mActionDone) {
                 long delay = endShutTime - SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index f3b9b18..b5aa4a9 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ISearchManager;
@@ -306,7 +305,7 @@
         try {
             Intent intent = new Intent(Intent.ACTION_ASSIST);
             intent.setComponent(comp);
-            IActivityManager am = ActivityManagerNative.getDefault();
+            IActivityManager am = ActivityManager.getService();
             return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
                     userHandle, args);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 62f5468..9d02940 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -26,7 +26,6 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.ITrustListener;
 import android.app.trust.ITrustManager;
@@ -868,7 +867,7 @@
                     }
                     if (locked) {
                         try {
-                            ActivityManagerNative.getDefault().notifyLockedProfile(userId);
+                            ActivityManager.getService().notifyLockedProfile(userId);
                         } catch (RemoteException e) {
                         }
                     }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 96662b5..3645c24 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -26,7 +26,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IWallpaperManager;
@@ -959,7 +958,7 @@
         }, shutdownFilter);
 
         try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(
+            ActivityManager.getService().registerUserSwitchObserver(
                     new UserSwitchObserver() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 302f9f6..61319cf 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -16,7 +16,7 @@
 
 package com.android.server.webkit;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -200,7 +200,7 @@
     @Override
     public void killPackageDependents(String packageName) {
         try {
-            ActivityManagerNative.getDefault().killPackageDependents(packageName,
+            ActivityManager.getService().killPackageDependents(packageName,
                     UserHandle.USER_ALL);
         } catch (RemoteException e) {
         }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 6d97796..0a7454f 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -36,6 +36,7 @@
 import com.android.server.SystemService;
 
 import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.Arrays;
 
 /**
@@ -259,5 +260,18 @@
                 Binder.restoreCallingIdentity(callingId);
             }
         }
+
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                    != PackageManager.PERMISSION_GRANTED) {
+
+                pw.println("Permission Denial: can't dump webviewupdate service from pid="
+                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+                return;
+            }
+
+            WebViewUpdateService.this.mImpl.dumpState(pw);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 453e745..1a77c68 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -30,6 +30,7 @@
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -673,6 +674,27 @@
             mMinimumVersionCode = minimumVersionCode;
             return mMinimumVersionCode;
         }
+
+        public void dumpState(PrintWriter pw) {
+            synchronized (mLock) {
+                if (mCurrentWebViewPackage == null) {
+                    pw.println("  Current WebView package is null");
+                } else {
+                    pw.println(String.format("  Current WebView package (name, version): (%s, %s)",
+                            mCurrentWebViewPackage.packageName,
+                            mCurrentWebViewPackage.versionName));
+                }
+                pw.println(String.format("  Minimum WebView version code: %d",
+                      mMinimumVersionCode));
+                pw.println(String.format("  Number of relros started: %d",
+                        mNumRelroCreationsStarted));
+                pw.println(String.format("  Number of relros finished: %d",
+                            mNumRelroCreationsFinished));
+                pw.println(String.format("  WebView package dirty: %b", mWebViewPackageDirty));
+                pw.println(String.format("  Any WebView package installed: %b",
+                        mAnyWebViewInstalled));
+            }
+        }
     }
 
     private static boolean providerHasValidSignature(WebViewProviderInfo provider,
@@ -741,4 +763,14 @@
             mSystemInterface.setMultiProcessEnabledFromContext(mContext);
         }
     }
+
+    /**
+     * Dump the state of this Service.
+     */
+    void dumpState(PrintWriter pw) {
+        pw.println("Current WebView Update Service state");
+        pw.println(String.format("  Fallback logic enabled: %b",
+                mSystemInterface.isFallbackLogicEnabled()));
+        mWebViewUpdater.dumpState(pw);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index e1b598a..c42647e 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -411,7 +411,7 @@
         }
         if (mService.mInputMethodTarget != null
                 && mService.mInputMethodTarget.mAppToken == mAppToken) {
-            mAppToken.getDisplayContent().moveInputMethodWindowsIfNeeded(true);
+            mAppToken.getDisplayContent().computeImeTarget(true /* updateImeTarget */);
         }
 
         if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 05e6f96..4569596 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> {
 }
@@ -412,6 +413,7 @@
         boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, voiceInteraction);
 
         mService.mOpeningApps.remove(this);
+        mService.mUnknownAppVisibilityController.appRemoved(this);
         waitingToShow = false;
         if (mService.mClosingApps.contains(this)) {
             delayed = true;
@@ -1004,10 +1006,7 @@
             tStartingWindow.mToken = this;
             tStartingWindow.mAppToken = this;
 
-            if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
-                    "Removing starting window: " + tStartingWindow);
-            getDisplayContent().removeFromWindowList(tStartingWindow);
-            if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+            if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                     "Removing starting " + tStartingWindow + " from " + fromToken);
             fromToken.removeChild(tStartingWindow);
             fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
@@ -1257,32 +1256,21 @@
         }
     }
 
-    int rebuildWindowListUnchecked(int addIndex) {
-        return super.rebuildWindowList(addIndex);
-    }
-
     @Override
-    int rebuildWindowList(int addIndex) {
-        if (mIsExiting && !waitingForReplacement()) {
-            return addIndex;
-        }
-        return rebuildWindowListUnchecked(addIndex);
-    }
-
-    @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
@@ -1329,6 +1317,32 @@
         mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
     }
 
+    WindowState getImeTargetBelowWindow(WindowState w) {
+        final int index = mChildren.indexOf(w);
+        if (index > 0) {
+            final WindowState target = mChildren.get(index - 1);
+            if (target.canBeImeTarget()) {
+                return target;
+            }
+        }
+        return null;
+    }
+
+    WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
+        WindowState candidate = null;
+        for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
+            final WindowState w = mChildren.get(i);
+            if (w.mRemoved) {
+                continue;
+            }
+            if (candidate == null || w.mWinAnimator.mAnimLayer >
+                    candidate.mWinAnimator.mAnimLayer) {
+                candidate = w;
+            }
+        }
+        return candidate;
+    }
+
     @Override
     void dump(PrintWriter pw, String prefix) {
         super.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ff39853..24b9d69 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -33,10 +33,6 @@
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_TOP;
-import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
-import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -44,13 +40,10 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
 import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -64,7 +57,6 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
@@ -77,10 +69,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -94,7 +84,6 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.dipToPixel;
-import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowManagerService.logSurface;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
 import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
@@ -120,27 +109,21 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.IWindow;
-import android.view.InputChannel;
 import android.view.Surface;
 import android.view.SurfaceControl;
 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;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.function.Consumer;
 
 /**
  * Utility class for keeping track of the WindowStates and other pertinent contents of a
@@ -172,8 +155,7 @@
     private final NonAppWindowContainers mImeWindowsContainers =
             new NonAppWindowContainers("mImeWindowsContainers");
 
-    // Z-ordered (bottom-most first) list of all Window objects.
-    private final WindowList mWindows = new WindowList();
+    private WindowState mTmpWindow;
 
     // Mapping from a token IBinder to a WindowToken object on this display.
     private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
@@ -230,21 +212,19 @@
 
     final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
 
-    /** Used when rebuilding window list to keep track of windows that have been removed. */
-    private WindowState[] mRebuildTmp = new WindowState[20];
-
-    /**
-     * Temporary list for comparison. Always clear this after use so we don't end up with
-     * orphaned windows references
-     */
-    private final ArrayList<WindowState> mTmpWindows = new ArrayList<>();
+    private boolean mHaveBootMsg = false;
+    private boolean mHaveApp = false;
+    private boolean mHaveWallpaper = false;
+    private boolean mHaveKeyguard = true;
 
     private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
 
     private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
             new TaskForResizePointSearchResult();
-    private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
-            new GetWindowOnDisplaySearchResult();
+    private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState =
+            new ApplySurfaceChangesTransactionState();
+    private final ScreenshotApplicationState mScreenshotApplicationState =
+            new ScreenshotApplicationState();
 
     // True if this display is in the process of being removed. Used to determine if the removal of
     // the display's direct children should be allowed.
@@ -453,17 +433,13 @@
     @Override
     void onAppTransitionDone() {
         super.onAppTransitionDone();
-        rebuildAppWindowList();
+        mService.mWindowsChanged = true;
     }
 
     @Override
     int getOrientation() {
         final WindowManagerPolicy policy = mService.mPolicy;
 
-        // TODO: All the logic before the last return statement in this method should really go in
-        // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based
-        // on non-app windows. But, we can not do that until the window list is always correct in
-        // terms of z-ordering based on layers.
         if (mService.mDisplayFrozen) {
             if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
@@ -484,31 +460,9 @@
                 return mService.mLastOrientation;
             }
         } else {
-            for (int pos = mWindows.size() - 1; pos >= 0; --pos) {
-                final WindowState win = mWindows.get(pos);
-                if (win.mAppToken != null) {
-                    // We hit an application window. so the orientation will be determined by the
-                    // app window. No point in continuing further.
-                    break;
-                }
-                if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
-                    continue;
-                }
-                int req = win.mAttrs.screenOrientation;
-                if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
-                    continue;
-                }
-
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
-                if (policy.isKeyguardHostWindow(win.mAttrs)) {
-                    mService.mLastKeyguardForcedOrientation = req;
-                }
-                return (mService.mLastWindowForcedOrientation = req);
-            }
-            mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
-            if (policy.isKeyguardShowingAndNotOccluded()) {
-                return mService.mLastKeyguardForcedOrientation;
+            final int orientation = mAboveAppWindowsContainers.getOrientation();
+            if (orientation != SCREEN_ORIENTATION_UNSET) {
+                return orientation;
             }
         }
 
@@ -725,7 +679,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);
@@ -735,22 +690,10 @@
         }
     }
 
+    @Override
     void switchUser() {
-        final int count = mWindows.size();
-        for (int i = 0; i < count; i++) {
-            final WindowState win = mWindows.get(i);
-            if (win.isHiddenFromUserLocked()) {
-                if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
-                        + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
-                win.hideLw(false);
-            }
-        }
-
-        for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
-            mTaskStackContainers.get(stackNdx).switchUser();
-        }
-
-        rebuildAppWindowList();
+        super.switchUser();
+        mService.mWindowsChanged = true;
     }
 
     private void resetAnimationBackgroundAnimator() {
@@ -912,19 +855,9 @@
     void setInputMethodAnimLayerAdjustment(int adj) {
         if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
         mInputMethodAnimLayerAdjustment = adj;
-        final WindowState imw = mService.mInputMethodWindow;
-        if (imw != null) {
-            imw.adjustAnimLayer(adj);
-        }
-        for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
-            final WindowState dialog = mService.mInputMethodDialogs.get(i);
-            // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
-            // but need to make sure we are not setting things twice for child windows that are
-            // already in the list.
-            dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
-            if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
-                    + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
-        }
+        mImeWindowsContainers.forAllWindows(w -> {
+            w.adjustAnimLayer(adj);
+        }, true /* traverseTopToBottom */);
     }
 
     /**
@@ -933,11 +866,11 @@
      * suddenly disappear.
      */
     int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
-        for (int i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState win = mWindows.get(i);
-            if (win.mIsWallpaper && win.isVisibleNow()) {
-                return win.mWinAnimator.mAnimLayer;
-            }
+        final WindowState visibleWallpaper = mBelowAppWindowsContainers.getWindow(
+                w -> w.mIsWallpaper && w.isVisibleNow());
+
+        if (visibleWallpaper != null) {
+            return visibleWallpaper.mWinAnimator.mAnimLayer;
         }
         return winAnimator.mAnimLayer;
     }
@@ -1085,48 +1018,37 @@
 
     /** Find the visible, touch-deliverable window under the given point */
     WindowState getTouchableWinAtPointLocked(float xf, float yf) {
-        WindowState touchedWin = null;
         final int x = (int) xf;
         final int y = (int) yf;
-
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            WindowState window = mWindows.get(i);
-            final int flags = window.mAttrs.flags;
-            if (!window.isVisibleLw()) {
-                continue;
+        final WindowState touchedWin = getWindow(w -> {
+            final int flags = w.mAttrs.flags;
+            if (!w.isVisibleLw()) {
+                return false;
             }
             if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
-                continue;
+                return false;
             }
 
-            window.getVisibleBounds(mTmpRect);
+            w.getVisibleBounds(mTmpRect);
             if (!mTmpRect.contains(x, y)) {
-                continue;
+                return false;
             }
 
-            window.getTouchableRegion(mTmpRegion);
+            w.getTouchableRegion(mTmpRegion);
 
             final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
-            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
-                touchedWin = window;
-                break;
-            }
-        }
+            return mTmpRegion.contains(x, y) || touchFlags == 0;
+        });
 
         return touchedWin;
     }
 
     boolean canAddToastWindowForUid(int uid) {
         // We allow one toast window per UID being shown at a time.
-        final int windowCount = mWindows.size();
-        for (int i = 0; i < windowCount; i++) {
-            final WindowState window = mWindows.get(i);
-            if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
-                    && !window.mPermanentlyHidden && !window.mWindowRemovalAllowed) {
-                return false;
-            }
-        }
-        return true;
+        final WindowState win = getWindow(w ->
+                w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == uid && !w.mPermanentlyHidden
+                && !w.mWindowRemovalAllowed);
+        return win == null;
     }
 
     void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
@@ -1134,268 +1056,76 @@
             return;
         }
         final int lostFocusUid = oldFocus.mOwnerUid;
-        final int windowCount = mWindows.size();
         final Handler handler = mService.mH;
-        for (int i = 0; i < windowCount; i++) {
-            final WindowState window = mWindows.get(i);
-            if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
-                if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
-                    handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
-                            window.mAttrs.hideTimeoutMilliseconds);
+
+        forAllWindows(w -> {
+            if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) {
+                if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) {
+                    handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w),
+                            w.mAttrs.hideTimeoutMilliseconds);
                 }
             }
-        }
+        }, false /* traverseTopToBottom */);
     }
 
     WindowState findFocusedWindow() {
         final AppWindowToken focusedApp = mService.mFocusedApp;
+        mTmpWindow = null;
 
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState win = mWindows.get(i);
+        forAllWindows(w -> {
+            if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w
+                    + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys());
 
-            if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
-                    + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
-
-            if (!win.canReceiveKeys()) {
-                continue;
+            if (!w.canReceiveKeys()) {
+                return false;
             }
 
-            final AppWindowToken wtoken = win.mAppToken;
+            final AppWindowToken wtoken = w.mAppToken;
 
             // If this window's application has been removed, just skip it.
             if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
                 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
                         + (wtoken.removed ? "removed" : "sendingToBottom"));
-                continue;
+                return false;
             }
 
             if (focusedApp == null) {
                 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
-                        + " using new focus @ " + i + " = " + win);
-                return win;
+                        + " using new focus @ " + w);
+                mTmpWindow = w;
+                return true;
             }
 
             if (!focusedApp.windowsAreFocusable()) {
                 // Current focused app windows aren't focusable...
                 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
-                        + " focusable using new focus @ " + i + " = " + win);
-                return win;
+                        + " focusable using new focus @ " + w);
+                mTmpWindow = w;
+                return true;
             }
 
             // Descend through all of the app tokens and find the first that either matches
             // win.mAppToken (return win) or mFocusedApp (return null).
-            if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
+            if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) {
                 if (focusedApp.compareTo(wtoken) > 0) {
                     // App stack below focused app stack. No focus for you!!!
                     if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
                             "findFocusedWindow: Reached focused app=" + focusedApp);
-                    return null;
+                    mTmpWindow = null;
+                    return true;
                 }
             }
 
-            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
-                    + i + " = " + win);
-            return win;
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w);
+            mTmpWindow = w;
+            return true;
+        }, true /* traverseTopToBottom */);
+
+        if (mTmpWindow == null) {
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
+            return null;
         }
-
-        if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
-        return null;
-    }
-
-    void addAppWindowToWindowList(final WindowState win) {
-        final IWindow client = win.mClient;
-
-        WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
-        if (!tokenWindowList.isEmpty()) {
-            addAppWindowExisting(win, tokenWindowList);
-            return;
-        }
-
-        // No windows from this token on this display
-        if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
-                + client.asBinder() + " (token=" + this + ")");
-
-        final WindowToken wToken = win.mToken;
-
-        // Figure out where the window should go, based on the order of applications.
-        mTmpGetWindowOnDisplaySearchResult.reset();
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
-            stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
-            if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
-                // We have reach the token we are interested in. End search.
-                break;
-            }
-        }
-
-        WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
-
-        // We now know the index into the apps. If we found an app window above, that gives us the
-        // position; else we need to look some more.
-        if (pos != null) {
-            // Move behind any windows attached to this one.
-            final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
-            if (atoken != null) {
-                tokenWindowList = getTokenWindowsOnDisplay(atoken);
-                final int NC = tokenWindowList.size();
-                if (NC > 0) {
-                    WindowState bottom = tokenWindowList.get(0);
-                    if (bottom.mSubLayer < 0) {
-                        pos = bottom;
-                    }
-                }
-            }
-            addWindowToListBefore(win, pos);
-            return;
-        }
-
-        // Continue looking down until we find the first token that has windows on this display.
-        mTmpGetWindowOnDisplaySearchResult.reset();
-        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
-            final TaskStack stack = mTaskStackContainers.get(i);
-            stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
-            if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
-                // We have found a window after the token. End search.
-                break;
-            }
-        }
-
-        pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
-
-        if (pos != null) {
-            // Move in front of any windows attached to this one.
-            final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
-            if (atoken != null) {
-                final WindowState top = atoken.getTopWindow();
-                if (top != null && top.mSubLayer >= 0) {
-                    pos = top;
-                }
-            }
-            addWindowToListAfter(win, pos);
-            return;
-        }
-
-        // Just search for the start of this layer.
-        final int myLayer = win.mBaseLayer;
-        int i;
-        for (i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState w = mWindows.get(i);
-            // Dock divider shares the base layer with application windows, but we want to always
-            // keep it above the application windows. The sharing of the base layer is intended
-            // for window animations, which need to be above the dock divider for the duration
-            // of the animation.
-            if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
-                break;
-            }
-        }
-        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
-                + mWindows.size());
-        mWindows.add(i + 1, win);
-        mService.mWindowsChanged = true;
-    }
-
-    /** Adds this non-app window to the window list. */
-    void addNonAppWindowToWindowList(WindowState win) {
-        // Figure out where window should go, based on layer.
-        int i;
-        for (i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState otherWin = mWindows.get(i);
-            if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
-                // Wallpaper wanders through the window list, for example to position itself
-                // directly behind keyguard. Because of this it will break the ordering based on
-                // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
-                // we don't want the new window to appear above them. An example of this is adding
-                // of the docked stack divider. Consider a scenario with the following ordering (top
-                // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
-                // to land below the assist preview, so the dock divider must ignore the wallpaper,
-                // with which it shares the base layer.
-                break;
-            }
-        }
-
-        i++;
-        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
-        mWindows.add(i, win);
-        mService.mWindowsChanged = true;
-    }
-
-    void addToWindowList(WindowState win, int index) {
-        mService.mWindowsChanged = true;
-        mWindows.add(index, win);
-    }
-
-    boolean removeFromWindowList(WindowState win) {
-        mService.mWindowsChanged = true;
-        return mWindows.remove(win);
-    }
-
-    private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
-        int wpos = mWindows.indexOf(win);
-        if (wpos < 0) {
-            return interestingPos;
-        }
-
-        if (wpos < interestingPos) interestingPos--;
-        if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
-        mWindows.remove(wpos);
-        mService.mWindowsChanged = true;
-        int childWinCount = win.mChildren.size();
-        while (childWinCount > 0) {
-            childWinCount--;
-            final WindowState cw = win.mChildren.get(childWinCount);
-            int cpos = mWindows.indexOf(cw);
-            if (cpos >= 0) {
-                if (cpos < interestingPos) interestingPos--;
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
-                        "Temp removing child at " + cpos + ": " + cw);
-                mWindows.remove(cpos);
-            }
-        }
-        return interestingPos;
-    }
-
-    void addChildWindowToWindowList(WindowState win) {
-        final WindowState parentWindow = win.getParentWindow();
-
-        WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
-
-        // Figure out this window's ordering relative to the parent window.
-        final int wCount = windowsOnSameDisplay.size();
-        final int sublayer = win.mSubLayer;
-        int largestSublayer = Integer.MIN_VALUE;
-        WindowState windowWithLargestSublayer = null;
-        int i;
-        for (i = 0; i < wCount; i++) {
-            WindowState w = windowsOnSameDisplay.get(i);
-            final int wSublayer = w.mSubLayer;
-            if (wSublayer >= largestSublayer) {
-                largestSublayer = wSublayer;
-                windowWithLargestSublayer = w;
-            }
-            if (sublayer < 0) {
-                // For negative sublayers, we go below all windows in the same sublayer.
-                if (wSublayer >= sublayer) {
-                    addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
-                    break;
-                }
-            } else {
-                // For positive sublayers, we go above all windows in the same sublayer.
-                if (wSublayer > sublayer) {
-                    addWindowToListBefore(win, w);
-                    break;
-                }
-            }
-        }
-        if (i >= wCount) {
-            if (sublayer < 0) {
-                addWindowToListBefore(win, parentWindow);
-            } else {
-                addWindowToListAfter(win,
-                        largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
-            }
-        }
+        return mTmpWindow;
     }
 
     /** Updates the layer assignment of windows on this display. */
@@ -1406,138 +1136,9 @@
         }
     }
 
-    void adjustWallpaperWindows() {
-        if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
-            assignWindowLayers(true /*setLayoutNeeded*/);
-        }
-    }
-
-    /**
-     * Z-orders the display window list so that:
-     * <ul>
-     * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
-     *      window.
-     * <li>Exiting application windows are at the bottom, but above the wallpaper window.
-     * <li>All other application windows are above the exiting application windows and ordered based
-     *      on the ordering of their stacks and tasks on the display.
-     * <li>Non-application windows are at the very top.
-     * </ul>
-     * <p>
-     * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
-     *       surface layering is done in {@link WindowLayersController}.
-     */
-    void rebuildAppWindowList() {
-        int count = mWindows.size();
-        int i;
-        int lastBelow = -1;
-        int numRemoved = 0;
-
-        if (mRebuildTmp.length < count) {
-            mRebuildTmp = new WindowState[count + 10];
-        }
-
-        // First remove all existing app windows.
-        i = 0;
-        while (i < count) {
-            final WindowState w = mWindows.get(i);
-            if (w.mAppToken != null) {
-                final WindowState win = mWindows.remove(i);
-                win.mRebuilding = true;
-                mRebuildTmp[numRemoved] = win;
-                mService.mWindowsChanged = true;
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
-                count--;
-                numRemoved++;
-                continue;
-            } else if (lastBelow == i-1) {
-                if (w.mAttrs.type == TYPE_WALLPAPER) {
-                    lastBelow = i;
-                }
-            }
-            i++;
-        }
-
-        // Keep whatever windows were below the app windows still below, by skipping them.
-        lastBelow++;
-        i = lastBelow;
-
-        // First add all of the exiting app tokens...  these are no longer in the main app list,
-        // but still have windows shown. We put them in the back because now that the animation is
-        // over we no longer will care about them.
-        final int numStacks = mTaskStackContainers.size();
-        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-            AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
-            int NT = exitingAppTokens.size();
-            for (int j = 0; j < NT; j++) {
-                i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
-            }
-        }
-
-        // And add in the still active app tokens in Z order.
-        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
-            i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
-        }
-
-        i -= lastBelow;
-        if (i != numRemoved) {
-            setLayoutNeeded();
-            Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
-                    + " windows but added " + i + " rebuildAppWindowListLocked() "
-                    + " callers=" + Debug.getCallers(10));
-            for (i = 0; i < numRemoved; i++) {
-                WindowState ws = mRebuildTmp[i];
-                if (ws.mRebuilding) {
-                    StringWriter sw = new StringWriter();
-                    PrintWriter pw = new FastPrintWriter(sw, false, 1024);
-                    ws.dump(pw, "", true);
-                    pw.flush();
-                    Slog.w(TAG_WM, "This window was lost: " + ws);
-                    Slog.w(TAG_WM, sw.toString());
-                    ws.mWinAnimator.destroySurfaceLocked();
-                }
-            }
-            Slog.w(TAG_WM, "Current window hierarchy:");
-            dumpChildrenNames();
-            Slog.w(TAG_WM, "Final window list:");
-            dumpWindows();
-        }
-        Arrays.fill(mRebuildTmp, null);
-    }
-
-    /** Rebuilds the display's window list and does a relayout if something changed. */
-    void rebuildAppWindowsAndLayoutIfNeeded() {
-        mTmpWindows.clear();
-        mTmpWindows.addAll(mWindows);
-
-        rebuildAppWindowList();
-
-        // Set displayContent.mLayoutNeeded if window order changed.
-        final int tmpSize = mTmpWindows.size();
-        final int winSize = mWindows.size();
-        int tmpNdx = 0, winNdx = 0;
-        while (tmpNdx < tmpSize && winNdx < winSize) {
-            // Skip over all exiting windows, they've been moved out of order.
-            WindowState tmp;
-            do {
-                tmp = mTmpWindows.get(tmpNdx++);
-            } while (tmpNdx < tmpSize && tmp.mAppToken != null && tmp.mAppToken.mIsExiting);
-
-            WindowState win;
-            do {
-                win = mWindows.get(winNdx++);
-            } while (winNdx < winSize && win.mAppToken != null && win.mAppToken.mIsExiting);
-
-            if (tmp != win) {
-                // Window order changed.
-                setLayoutNeeded();
-                break;
-            }
-        }
-        if (tmpNdx != winNdx) {
-            // One list was different from the other.
-            setLayoutNeeded();
-        }
-        mTmpWindows.clear();
+    void layoutAndAssignWindowLayersIfNeeded() {
+        mService.mWindowsChanged = true;
+        setLayoutNeeded();
 
         if (!mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                 false /*updateInputWindows*/)) {
@@ -1549,321 +1150,69 @@
         mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
     }
 
-    void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
-        final InputConsumerImpl navInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_NAVIGATION, mDisplayId);
-        final InputConsumerImpl pipInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_PIP, mDisplayId);
-        final InputConsumerImpl wallpaperInputConsumer =
-                mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_WALLPAPER, mDisplayId);
-        boolean addInputConsumerHandle = navInputConsumer != null;
-        boolean addPipInputConsumerHandle = pipInputConsumer != null;
-        boolean addWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
-        final Rect pipTouchableBounds = addPipInputConsumerHandle ? new Rect() : null;
-        boolean disableWallpaperTouchEvents = false;
-
-        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState child = mWindows.get(winNdx);
-            final InputChannel inputChannel = child.mInputChannel;
-            final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
-            if (inputChannel == null || inputWindowHandle == null || child.mRemoved
-                    || child.isAdjustedForMinimizedDock()) {
-                // Skip this window because it cannot possibly receive input.
-                continue;
-            }
-
-            if (addPipInputConsumerHandle
-                    && child.getStackId() == PINNED_STACK_ID
-                    && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) {
-                // Update the bounds of the Pip input consumer to match the Pinned stack
-                child.getStack().getBounds(pipTouchableBounds);
-                pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds);
-                inputMonitor.addInputWindowHandle(pipInputConsumer.mWindowHandle);
-                addPipInputConsumerHandle = false;
-            }
-
-            if (addInputConsumerHandle
-                    && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
-                inputMonitor.addInputWindowHandle(navInputConsumer.mWindowHandle);
-                addInputConsumerHandle = false;
-            }
-
-            if (addWallpaperInputConsumerHandle) {
-                if (child.mAttrs.type == TYPE_WALLPAPER && child.isVisibleLw()) {
-                    // Add the wallpaper input consumer above the first visible wallpaper.
-                    inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
-                    addWallpaperInputConsumerHandle = false;
-                }
-            }
-
-            final int flags = child.mAttrs.flags;
-            final int privateFlags = child.mAttrs.privateFlags;
-            final int type = child.mAttrs.type;
-
-            final boolean hasFocus = child == inputFocus;
-            final boolean isVisible = child.isVisibleLw();
-            if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
-                disableWallpaperTouchEvents = true;
-            }
-            final boolean hasWallpaper = mWallpaperController.isWallpaperTarget(child)
-                    && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
-                    && !disableWallpaperTouchEvents;
-
-            // If there's a drag in progress and 'child' is a potential drop target,
-            // make sure it's been told about the drag
-            if (inDrag && isVisible && isDefaultDisplay) {
-                mService.mDragState.sendDragStartedIfNeededLw(child);
-            }
-
-            inputMonitor.addInputWindowHandle(
-                    inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
-        }
-
-        if (addWallpaperInputConsumerHandle) {
-            // No visible wallpaper found, add the wallpaper input consumer at the end.
-            inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
-        }
-    }
-
     /** Returns true if a leaked surface was destroyed */
     boolean destroyLeakedSurfaces() {
-        boolean leakedSurface = false;
-        final int numWindows = mWindows.size();
-        for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
-            final WindowState ws = mWindows.get(winNdx);
-            final WindowStateAnimator wsa = ws.mWinAnimator;
+        // Used to indicate that a surface was leaked.
+        mTmpWindow = null;
+        forAllWindows(w -> {
+            final WindowStateAnimator wsa = w.mWinAnimator;
             if (wsa.mSurfaceController == null) {
-                continue;
+                return;
             }
             if (!mService.mSessions.contains(wsa.mSession)) {
                 Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
-                        + ws + " surface=" + wsa.mSurfaceController
-                        + " token=" + ws.mToken
-                        + " pid=" + ws.mSession.mPid
-                        + " uid=" + ws.mSession.mUid);
+                        + w + " surface=" + wsa.mSurfaceController
+                        + " token=" + w.mToken
+                        + " pid=" + w.mSession.mPid
+                        + " uid=" + w.mSession.mUid);
                 wsa.destroySurface();
-                mService.mForceRemoves.add(ws);
-                leakedSurface = true;
-            } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
+                mService.mForceRemoves.add(w);
+                mTmpWindow = w;
+            } else if (w.mAppToken != null && w.mAppToken.clientHidden) {
                 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
-                        + ws + " surface=" + wsa.mSurfaceController
-                        + " token=" + ws.mAppToken
-                        + " saved=" + ws.hasSavedSurface());
-                if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
+                        + w + " surface=" + wsa.mSurfaceController
+                        + " token=" + w.mAppToken
+                        + " saved=" + w.hasSavedSurface());
+                if (SHOW_TRANSACTIONS) logSurface(w, "LEAK DESTROY", false);
                 wsa.destroySurface();
-                leakedSurface = true;
+                mTmpWindow = w;
             }
-        }
+        }, false /* traverseTopToBottom */);
 
-        return leakedSurface;
-    }
-
-    /** Return the list of Windows on this display associated with the input token. */
-    WindowList getTokenWindowsOnDisplay(WindowToken token) {
-        final WindowList windowList = new WindowList();
-        final int count = mWindows.size();
-        for (int i = 0; i < count; i++) {
-            final WindowState win = mWindows.get(i);
-            if (win.mToken == token) {
-                windowList.add(win);
-            }
-        }
-        return windowList;
-    }
-
-    private void reAddToWindowList(WindowState win) {
-        win.mToken.addWindow(win);
-        // This is a hack to get all of the child windows added as well at the right position. Child
-        // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
-        int wpos = mWindows.indexOf(win);
-        if (wpos >= 0) {
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
-            mWindows.remove(wpos);
-            mService.mWindowsChanged = true;
-            win.reAddWindow(wpos);
-        }
-    }
-
-    void moveInputMethodDialogs(int pos) {
-        ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
-
-        final int N = dialogs.size();
-        if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
-        for (int i = 0; i < N; i++) {
-            pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
-        }
-        if (DEBUG_INPUT_METHOD) {
-            Slog.v(TAG_WM, "Window list w/pos=" + pos);
-            logWindowList(mWindows, "  ");
-        }
-
-        WindowState ime = mService.mInputMethodWindow;
-        if (pos >= 0) {
-            // Skip windows owned by the input method.
-            if (ime != null) {
-                while (pos < mWindows.size()) {
-                    WindowState wp = mWindows.get(pos);
-                    if (wp == ime || wp.getParentWindow() == ime) {
-                        pos++;
-                        continue;
-                    }
-                    break;
-                }
-            }
-            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
-            for (int i=0; i<N; i++) {
-                WindowState win = dialogs.get(i);
-                pos = win.reAddWindow(pos);
-            }
-            if (DEBUG_INPUT_METHOD) {
-                Slog.v(TAG_WM, "Final window list:");
-                logWindowList(mWindows, "  ");
-            }
-            return;
-        }
-        for (int i=0; i<N; i++) {
-            WindowState win = dialogs.get(i);
-            reAddToWindowList(win);
-            if (DEBUG_INPUT_METHOD) {
-                Slog.v(TAG_WM, "No IM target, final list:");
-                logWindowList(mWindows, "  ");
-            }
-        }
-    }
-
-    boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
-        final WindowState imWin = mService.mInputMethodWindow;
-        final int DN = mService.mInputMethodDialogs.size();
-        if (imWin == null && DN == 0) {
-            return false;
-        }
-
-        // TODO(multidisplay): IMEs are only supported on the default display.
-        int imPos = findDesiredInputMethodWindowIndex(true);
-        if (imPos >= 0) {
-            // In this case, the input method windows are to be placed
-            // immediately above the window they are targeting.
-
-            // First check to see if the input method windows are already
-            // located here, and contiguous.
-            final int N = mWindows.size();
-            final WindowState firstImWin = imPos < N ? mWindows.get(imPos) : null;
-
-            // Figure out the actual input method window that should be
-            // at the bottom of their stack.
-            WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
-            final WindowState cw = baseImWin.getBottomChild();
-            if (cw != null && cw.mSubLayer < 0) {
-                baseImWin = cw;
-            }
-
-            if (firstImWin == baseImWin) {
-                // The windows haven't moved...  but are they still contiguous?
-                // First find the top IM window.
-                int pos = imPos+1;
-                while (pos < N) {
-                    if (!(mWindows.get(pos)).mIsImWindow) {
-                        break;
-                    }
-                    pos++;
-                }
-                pos++;
-                // Now there should be no more input method windows above.
-                while (pos < N) {
-                    if ((mWindows.get(pos)).mIsImWindow) {
-                        break;
-                    }
-                    pos++;
-                }
-                if (pos >= N) {
-                    return false;
-                }
-            }
-
-            if (imWin != null) {
-                if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG_WM, "Moving IM from " + imPos);
-                    logWindowList(mWindows, "  ");
-                }
-                imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
-                if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
-                    logWindowList(mWindows, "  ");
-                }
-                imWin.reAddWindow(imPos);
-                if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
-                    logWindowList(mWindows, "  ");
-                }
-                if (DN > 0) moveInputMethodDialogs(imPos+1);
-            } else {
-                moveInputMethodDialogs(imPos);
-            }
-
-        } else {
-            // In this case, the input method windows go in a fixed layer,
-            // because they aren't currently associated with a focus window.
-
-            if (imWin != null) {
-                if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
-                removeWindowAndChildrenFromWindowList(imWin, 0);
-                reAddToWindowList(imWin);
-                if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG_WM, "List with no IM target:");
-                    logWindowList(mWindows, "  ");
-                }
-                if (DN > 0) moveInputMethodDialogs(-1);
-            } else {
-                moveInputMethodDialogs(-1);
-            }
-
-        }
-
-        if (needAssignLayers) {
-            assignWindowLayers(false /* setLayoutNeeded */);
-        }
-
-        return true;
+        return mTmpWindow != null;
     }
 
     /**
-     * Dig through the WindowStates and find the one that the Input Method will target.
-     * @param willMove
-     * @return The index+1 in mWindows of the discovered target.
+     * Determine and return the window that should be the IME target.
+     * @param updateImeTarget If true the system IME target will be updated to match what we found.
+     * @return The window that should be used as the IME target or null if there isn't any.
      */
-    int findDesiredInputMethodWindowIndex(boolean willMove) {
+    WindowState computeImeTarget(boolean updateImeTarget) {
         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
         // same display. Or even when the current IME/target are not on the same screen as the next
         // IME/target. For now only look for input windows on the main screen.
-        WindowState w = null;
-        int i;
-        for (i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState win = mWindows.get(i);
+        WindowState target = getWindow(w -> {
+            if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.i(TAG_WM, "Checking window @"
+                    + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags));
+            return w.canBeImeTarget();
+        });
 
-            if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
-                    + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
-            if (canBeImeTarget(win)) {
-                w = win;
-                //Slog.i(TAG_WM, "Putting input method here!");
 
-                // Yet more tricksyness!  If this window is a "starting" window, we do actually want
-                // to be on top of it, but it is not -really- where input will go.  So if the caller
-                // is not actually looking to move the IME, look down below for a real window to
-                // target...
-                if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
-                    final WindowState wb = mWindows.get(i-1);
-                    if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
-                        i--;
-                        w = wb;
-                    }
+        // Yet more tricksyness!  If this window is a "starting" window, we do actually want
+        // to be on top of it, but it is not -really- where input will go. So look down below
+        // for a real window to target...
+        if (target != null && target.mAttrs.type == TYPE_APPLICATION_STARTING) {
+            final AppWindowToken token = target.mAppToken;
+            if (token != null) {
+                final WindowState betterTarget = token.getImeTargetBelowWindow(target);
+                if (betterTarget != null) {
+                    target = betterTarget;
                 }
-                break;
             }
         }
 
-        // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
-
-        if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
+        if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
+                "Proposed new IME target: " + target);
 
         // Now, a special case -- if the last target's window is in the process of exiting, and is
         // above the new target, keep on the last target to avoid flicker. Consider for example a
@@ -1871,18 +1220,28 @@
         // until it is completely gone so it doesn't drop behind the dialog or its full-screen
         // scrim.
         final WindowState curTarget = mService.mInputMethodTarget;
-        if (curTarget != null
-                && curTarget.isDisplayedLw()
-                && curTarget.isClosing()
-                && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
+        if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing()
+                && (target == null
+                    || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) {
             if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
-            return mWindows.indexOf(curTarget) + 1;
+            return curTarget;
         }
 
-        if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
-                + w + " willMove=" + willMove);
+        if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target=" + target
+                + " updateImeTarget=" + updateImeTarget);
 
-        if (willMove && w != null) {
+        if (target == null) {
+            if (updateImeTarget) {
+                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
+                        + " to null." + (SHOW_STACK_CRAWLS ? " Callers="
+                        + Debug.getCallers(4) : ""));
+                setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim, 0);
+            }
+
+            return null;
+        }
+
+        if (updateImeTarget) {
             AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
             if (token != null) {
 
@@ -1890,24 +1249,8 @@
                 // to look at all windows below the current target that are in this app, finding the
                 // highest visible one in layering.
                 WindowState highestTarget = null;
-                int highestPos = 0;
                 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
-                    WindowList curWindows = token.getDisplayContent().mWindows;
-                    int pos = curWindows.indexOf(curTarget);
-                    while (pos >= 0) {
-                        WindowState win = curWindows.get(pos);
-                        if (win.mAppToken != token) {
-                            break;
-                        }
-                        if (!win.mRemoved) {
-                            if (highestTarget == null || win.mWinAnimator.mAnimLayer >
-                                    highestTarget.mWinAnimator.mAnimLayer) {
-                                highestTarget = win;
-                                highestPos = pos;
-                            }
-                        }
-                        pos--;
-                    }
+                    highestTarget = token.getHighestAnimLayerWindow(curTarget);
                 }
 
                 if (highestTarget != null) {
@@ -1915,121 +1258,76 @@
                     if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
                             + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
                             + " layer=" + highestTarget.mWinAnimator.mAnimLayer
-                            + " new layer=" + w.mWinAnimator.mAnimLayer);
+                            + " new layer=" + target.mWinAnimator.mAnimLayer);
 
                     if (appTransition.isTransitionSet()) {
                         // If we are currently setting up for an animation, hold everything until we
                         // can find out what will happen.
-                        mService.mInputMethodTargetWaitingAnim = true;
-                        mService.mInputMethodTarget = highestTarget;
-                        return highestPos + 1;
+                        setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment);
+                        return highestTarget;
                     } else if (highestTarget.mWinAnimator.isAnimationSet() &&
-                            highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
+                            highestTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer) {
                         // If the window we are currently targeting is involved with an animation,
                         // and it is on top of the next target we will be over, then hold off on
                         // moving until that is done.
-                        mService.mInputMethodTargetWaitingAnim = true;
-                        mService.mInputMethodTarget = highestTarget;
-                        return highestPos + 1;
+                        setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment);
+                        return highestTarget;
                     }
                 }
             }
+
+            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
+                    + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
+            setInputMethodTarget(target, false, target.mAppToken != null
+                    ? target.mAppToken.mAppAnimator.animLayerAdjustment : 0);
         }
 
-        //Slog.i(TAG_WM, "Placing input method @" + (i+1));
-        if (w != null) {
-            if (willMove) {
-                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
-                        + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
-                mService.mInputMethodTarget = w;
-                mService.mInputMethodTargetWaitingAnim = false;
-                if (w.mAppToken != null) {
-                    setInputMethodAnimLayerAdjustment(
-                            w.mAppToken.mAppAnimator.animLayerAdjustment);
-                } else {
-                    setInputMethodAnimLayerAdjustment(0);
-                }
-            }
-
-            // If the docked divider is visible, we still need to go through this whole excercise to
-            // find the appropriate input method target (used for animations and dialog
-            // adjustments), but for purposes of Z ordering we simply wish to place it above the
-            // docked divider. Unless it is already above the divider.
-            final WindowState dockedDivider = mDividerControllerLocked.getWindow();
-            if (dockedDivider != null && dockedDivider.isVisibleLw()) {
-                int dividerIndex = mWindows.indexOf(dockedDivider);
-                if (dividerIndex > 0 && dividerIndex > i) {
-                    return dividerIndex + 1;
-                }
-            }
-            return i+1;
-        }
-        if (willMove) {
-            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
-                    + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
-            mService.mInputMethodTarget = null;
-            setInputMethodAnimLayerAdjustment(0);
-        }
-        return -1;
+        return target;
     }
 
-    private static boolean canBeImeTarget(WindowState w) {
-        final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
-        final int type = w.mAttrs.type;
-
-        if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
-                && type != TYPE_APPLICATION_STARTING) {
-            return false;
+    private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim, int layerAdj) {
+        if (target == mService.mInputMethodTarget
+                && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim
+                && mInputMethodAnimLayerAdjustment == layerAdj) {
+            return;
         }
 
-        if (DEBUG_INPUT_METHOD) {
-            Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
-            if (!w.isVisibleOrAdding()) {
-                Slog.i(TAG_WM, "  mSurfaceController=" + w.mWinAnimator.mSurfaceController
-                        + " relayoutCalled=" + w.mRelayoutCalled
-                        + " viewVis=" + w.mViewVisibility
-                        + " policyVis=" + w.mPolicyVisibility
-                        + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
-                        + " parentHidden=" + w.isParentWindowHidden()
-                        + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
-                if (w.mAppToken != null) {
-                    Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
-                }
+        mService.mInputMethodTarget = target;
+        mService.mInputMethodTargetWaitingAnim = targetWaitingAnim;
+        setInputMethodAnimLayerAdjustment(layerAdj);
+        assignWindowLayers(false /* setLayoutNeeded */);
+    }
+
+    boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) {
+        if (top.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
+            return top.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
+        }
+
+        // Used to indicate we have reached the first window in the range we are interested in.
+        mTmpWindow = null;
+
+        // TODO: Figure-out a more efficient way to do this.
+        final WindowState candidate = getWindow(w -> {
+            if (w == top) {
+                // Reached the first window in the range we are interested in.
+                mTmpWindow = w;
             }
-        }
-        return w.isVisibleOrAdding();
-    }
+            if (mTmpWindow == null) {
+                return false;
+            }
 
-    private void logWindowList(final WindowList windows, String prefix) {
-        int N = windows.size();
-        while (N > 0) {
-            N--;
-            Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
-        }
-    }
-
-    boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
-        int index = -1;
-        while (true) {
-            if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
-                return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
+            if (w.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
+                return true;
             }
             // If we reached the bottom of the range of windows we are considering,
             // assume no menu is needed.
-            if (win == bottom) {
-                return false;
+            if (w == bottom) {
+                return true;
             }
-            // The current window hasn't specified whether menu key is needed; look behind it.
-            // First, we may need to determine the starting position.
-            if (index < 0) {
-                index = mWindows.indexOf(win);
-            }
-            index--;
-            if (index < 0) {
-                return false;
-            }
-            win = mWindows.get(index);
-        }
+            return false;
+        });
+
+        return candidate != null && candidate.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
     }
 
     void setLayoutNeeded() {
@@ -2046,85 +1344,6 @@
         return mLayoutNeeded;
     }
 
-    private void addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
-
-        // If this application has existing windows, we simply place the new window on top of
-        // them... but keep the starting window on top.
-        if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
-            // Base windows go behind everything else.
-            final WindowState lowestWindow = tokenWindowList.get(0);
-            addWindowToListBefore(win, lowestWindow);
-        } else {
-            final AppWindowToken atoken = win.mAppToken;
-            final int windowListPos = tokenWindowList.size();
-            final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
-            if (atoken != null && lastWindow == atoken.startingWindow) {
-                addWindowToListBefore(win, lastWindow);
-            } else {
-                int newIdx = findIdxBasedOnAppTokens(win);
-                // There is a window above this one associated with the same apptoken note that the
-                // window could be a floating window that was created later or a window at the top
-                // of the list of windows associated with this token.
-                if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                        "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
-                                + mWindows.size());
-                mWindows.add(newIdx + 1, win);
-                mService.mWindowsChanged = true;
-            }
-        }
-    }
-
-    /** Places the first input window after the second input window in the window list. */
-    private void addWindowToListAfter(WindowState first, WindowState second) {
-        final int i = mWindows.indexOf(second);
-        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
-                + " (after " + second + ")");
-        mWindows.add(i + 1, first);
-        mService.mWindowsChanged = true;
-    }
-
-    /** Places the first input window before the second input window in the window list. */
-    private void addWindowToListBefore(WindowState first, WindowState second) {
-        int i = mWindows.indexOf(second);
-        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                "Adding window " + this + " at " + i + " of " + mWindows.size()
-                + " (before " + second + ")");
-        if (i < 0) {
-            Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
-            i = 0;
-        }
-        mWindows.add(i, first);
-        mService.mWindowsChanged = true;
-    }
-
-    /**
-     * This method finds out the index of a window that has the same app token as win. used for z
-     * ordering the windows in mWindows
-     */
-    private int findIdxBasedOnAppTokens(WindowState win) {
-        for(int j = mWindows.size() - 1; j >= 0; j--) {
-            final WindowState wentry = mWindows.get(j);
-            if(wentry.mAppToken == win.mAppToken) {
-                return j;
-            }
-        }
-        return -1;
-    }
-
-    private void dumpChildrenNames() {
-        StringBuilder output = new StringBuilder();
-        dumpChildrenNames(output, " ");
-        Slog.v(TAG_WM, output.toString());
-    }
-
-    private void dumpWindows() {
-        Slog.v(TAG_WM, " Display #" + mDisplayId);
-        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
-            Slog.v(TAG_WM, "  #" + winNdx + ": " + mWindows.get(winNdx));
-        }
-    }
-
     void dumpTokens(PrintWriter pw, boolean dumpAll) {
         if (mTokenMap.isEmpty()) {
             return;
@@ -2145,25 +1364,24 @@
     }
 
     void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
-        final int count = mWindows.size();
-        for (int j = 0; j < count; j++) {
-            final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator;
-            pw.println(subPrefix + "Window #" + j + ": " + wAnim);
-        }
+        final int[] index = new int[1];
+        forAllWindows(w -> {
+            final WindowStateAnimator wAnim = w.mWinAnimator;
+            pw.println(subPrefix + "Window #" + index[0] + ": " + wAnim);
+            index[0] = index[0] + 1;
+        }, false /* traverseTopToBottom */);
     }
 
     void enableSurfaceTrace(FileDescriptor fd) {
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState win = mWindows.get(i);
-            win.mWinAnimator.enableSurfaceTrace(fd);
-        }
+        forAllWindows(w -> {
+            w.mWinAnimator.enableSurfaceTrace(fd);
+        }, true /* traverseTopToBottom */);
     }
 
     void disableSurfaceTrace() {
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState win = mWindows.get(i);
-            win.mWinAnimator.disableSurfaceTrace();
-        }
+        forAllWindows(w -> {
+            w.mWinAnimator.disableSurfaceTrace();
+        }, true /* traverseTopToBottom */);
     }
 
     /**
@@ -2171,63 +1389,68 @@
      */
     void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
         final WindowManagerPolicy policy = mService.mPolicy;
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState window = mWindows.get(i);
-            if (window.mAppToken == null && policy.canBeHiddenByKeyguardLw(window)) {
-                window.mWinAnimator.setAnimation(
+        forAllWindows(w -> {
+            if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)) {
+                w.mWinAnimator.setAnimation(
                         policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
             }
-        }
+        }, true /* traverseTopToBottom */);
     }
 
     boolean checkWaitingForWindows() {
 
-        boolean haveBootMsg = false;
-        boolean haveApp = false;
-        // if the wallpaper service is disabled on the device, we're never going to have
-        // wallpaper, don't bother waiting for it
-        boolean haveWallpaper = false;
-        boolean wallpaperEnabled = mService.mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_enableWallpaperService)
-                && !mService.mOnlyCore;
-        boolean haveKeyguard = true;
-        final int count = mWindows.size();
-        for (int i = 0; i < count; i++) {
-            final WindowState w = mWindows.get(i);
+        mHaveBootMsg = false;
+        mHaveApp = false;
+        mHaveWallpaper = false;
+        mHaveKeyguard = true;
+
+        final WindowState visibleWindow = getWindow(w -> {
             if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
                 return true;
             }
             if (w.isDrawnLw()) {
                 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
-                    haveBootMsg = true;
+                    mHaveBootMsg = true;
                 } else if (w.mAttrs.type == TYPE_APPLICATION
                         || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
-                    haveApp = true;
+                    mHaveApp = true;
                 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
-                    haveWallpaper = true;
+                    mHaveWallpaper = true;
                 } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
-                    haveKeyguard = mService.mPolicy.isKeyguardDrawnLw();
+                    mHaveKeyguard = mService.mPolicy.isKeyguardDrawnLw();
                 }
             }
+            return false;
+        });
+
+        if (visibleWindow != null) {
+            // We have a visible window.
+            return true;
         }
 
+        // if the wallpaper service is disabled on the device, we're never going to have
+        // wallpaper, don't bother waiting for it
+        boolean wallpaperEnabled = mService.mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_enableWallpaperService)
+                && !mService.mOnlyCore;
+
         if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM,
                 "******** booted=" + mService.mSystemBooted
                 + " msg=" + mService.mShowingBootMessages
-                + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
-                + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
-                + " haveKeyguard=" + haveKeyguard);
+                + " haveBoot=" + mHaveBootMsg + " haveApp=" + mHaveApp
+                + " haveWall=" + mHaveWallpaper + " wallEnabled=" + wallpaperEnabled
+                + " haveKeyguard=" + mHaveKeyguard);
 
         // If we are turning on the screen to show the boot message, don't do it until the boot
         // message is actually displayed.
-        if (!mService.mSystemBooted && !haveBootMsg) {
+        if (!mService.mSystemBooted && !mHaveBootMsg) {
             return true;
         }
 
         // If we are turning on the screen after the boot is completed normally, don't do so until
         // we have the application and wallpaper.
-        if (mService.mSystemBooted && ((!haveApp && !haveKeyguard) ||
-                (wallpaperEnabled && !haveWallpaper))) {
+        if (mService.mSystemBooted
+                && ((!mHaveApp && !mHaveKeyguard) || (wallpaperEnabled && !mHaveWallpaper))) {
             return true;
         }
 
@@ -2235,10 +1458,8 @@
     }
 
     void updateWindowsForAnimator(WindowAnimator animator) {
-        final WallpaperController wallpaperController = mWallpaperController;
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            WindowState win = mWindows.get(i);
-            WindowStateAnimator winAnimator = win.mWinAnimator;
+        forAllWindows(w -> {
+            WindowStateAnimator winAnimator = w.mWinAnimator;
             if (winAnimator.hasSurface()) {
                 final boolean wasAnimating = winAnimator.mWasAnimating;
                 final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
@@ -2246,10 +1467,10 @@
                 animator.orAnimating(nowAnimating);
 
                 if (DEBUG_WALLPAPER) Slog.v(TAG,
-                        win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
+                        w + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
 
                 if (wasAnimating && !winAnimator.mAnimating
-                        && wallpaperController.isWallpaperTarget(win)) {
+                        && mWallpaperController.isWallpaperTarget(w)) {
                     animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                     if (DEBUG_LAYOUT_REPEATS) {
@@ -2259,10 +1480,10 @@
                 }
             }
 
-            final AppWindowToken atoken = win.mAppToken;
+            final AppWindowToken atoken = w.mAppToken;
             if (winAnimator.mDrawState == READY_TO_SHOW) {
                 if (atoken == null || atoken.allDrawn) {
-                    if (win.performShowLocked()) {
+                    if (w.performShowLocked()) {
                         pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
                         if (DEBUG_LAYOUT_REPEATS) {
                             mService.mWindowPlacerLocked.debugLayoutRepeats(
@@ -2281,23 +1502,22 @@
                     appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
                 }
             }
-        } // end forall windows
+        }, true /* traverseTopToBottom */);
     }
 
     void updateWallpaperForAnimator(WindowAnimator animator) {
         resetAnimationBackgroundAnimator();
 
-        final WindowList windows = mWindows;
-        WindowState detachedWallpaper = null;
+        // Used to indicate a detached wallpaper.
+        mTmpWindow = null;
 
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
-            final WindowStateAnimator winAnimator = win.mWinAnimator;
+        forAllWindows(w -> {
+            final WindowStateAnimator winAnimator = w.mWinAnimator;
             if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
-                continue;
+                return;
             }
 
-            final int flags = win.mAttrs.flags;
+            final int flags = w.mAttrs.flags;
 
             // If this window is animating, make a note that we have an animating window and take
             // care of a request to run a detached wallpaper animation.
@@ -2305,11 +1525,11 @@
                 if (winAnimator.mAnimation != null) {
                     if ((flags & FLAG_SHOW_WALLPAPER) != 0
                             && winAnimator.mAnimation.getDetachWallpaper()) {
-                        detachedWallpaper = win;
+                        mTmpWindow = w;
                     }
                     final int color = winAnimator.mAnimation.getBackgroundColor();
                     if (color != 0) {
-                        final TaskStack stack = win.getStack();
+                        final TaskStack stack = w.getStack();
                         if (stack != null) {
                             stack.setAnimationBackground(winAnimator, color);
                         }
@@ -2325,62 +1545,43 @@
                     && appAnimator.animating) {
                 if ((flags & FLAG_SHOW_WALLPAPER) != 0
                         && appAnimator.animation.getDetachWallpaper()) {
-                    detachedWallpaper = win;
+                    mTmpWindow = w;
                 }
 
                 final int color = appAnimator.animation.getBackgroundColor();
                 if (color != 0) {
-                    final TaskStack stack = win.getStack();
+                    final TaskStack stack = w.getStack();
                     if (stack != null) {
                         stack.setAnimationBackground(winAnimator, color);
                     }
                 }
             }
-        } // end forall windows
+        }, true /* traverseTopToBottom */);
 
-        if (animator.mWindowDetachedWallpaper != detachedWallpaper) {
+        if (animator.mWindowDetachedWallpaper != mTmpWindow) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
-                    + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper);
-            animator.mWindowDetachedWallpaper = detachedWallpaper;
+                    + animator.mWindowDetachedWallpaper + " to " + mTmpWindow);
+            animator.mWindowDetachedWallpaper = mTmpWindow;
             animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
         }
     }
 
     void prepareWindowSurfaces() {
-        final int count = mWindows.size();
-        for (int j = 0; j < count; j++) {
-            mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true);
-        }
+        forAllWindows(w -> {
+            w.mWinAnimator.prepareSurfaceLocked(true);
+        }, false /* traverseTopToBottom */);
     }
 
     boolean inputMethodClientHasFocus(IInputMethodClient client) {
-        // The focus for the client is the window immediately below where we would place the input
-        // method window.
-        int idx = findDesiredInputMethodWindowIndex(false);
-        if (idx <= 0) {
-            return false;
-        }
-
-        WindowState imFocus = mWindows.get(idx - 1);
-        if (DEBUG_INPUT_METHOD) {
-            Slog.i(TAG_WM, "Desired input method target: " + imFocus);
-            Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
-            Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
-        }
-
+        final WindowState imFocus = computeImeTarget(false /* updateImeTarget */);
         if (imFocus == null) {
             return false;
         }
 
-        // This may be a starting window, in which case we still want to count it as okay.
-        if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING && imFocus.mAppToken != null) {
-            // The client has definitely started, so it really should have a window in this app
-            // token. Let's look for it.
-            final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
-            if (w != null) {
-                if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM, "Switching to real app window: " + w);
-                imFocus = w;
-            }
+        if (DEBUG_INPUT_METHOD) {
+            Slog.i(TAG_WM, "Desired input method target: " + imFocus);
+            Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
+            Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
         }
 
         final IInputMethodClient imeClient = imFocus.mSession.mClient;
@@ -2397,75 +1598,63 @@
     }
 
     boolean hasSecureWindowOnScreen() {
-        for (int i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState ws = mWindows.get(i);
-            if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
-                return true;
-            }
-        }
-        return false;
+        final WindowState win = getWindow(
+                w -> w.isOnScreen() && (w.mAttrs.flags & FLAG_SECURE) != 0);
+        return win != null;
     }
 
     void updateSystemUiVisibility(int visibility, int globalDiff) {
-        for (int i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState ws = mWindows.get(i);
+        forAllWindows(w -> {
             try {
-                int curValue = ws.mSystemUiVisibility;
-                int diff = (curValue ^ visibility) & globalDiff;
-                int newValue = (curValue & ~diff) | (visibility & diff);
+                final int curValue = w.mSystemUiVisibility;
+                final int diff = (curValue ^ visibility) & globalDiff;
+                final int newValue = (curValue & ~diff) | (visibility & diff);
                 if (newValue != curValue) {
-                    ws.mSeq++;
-                    ws.mSystemUiVisibility = newValue;
+                    w.mSeq++;
+                    w.mSystemUiVisibility = newValue;
                 }
-                if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
-                    ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+                if (newValue != curValue || w.mAttrs.hasSystemUiListeners) {
+                    w.mClient.dispatchSystemUiVisibilityChanged(w.mSeq,
                             visibility, newValue, diff);
                 }
             } catch (RemoteException e) {
                 // so sorry
             }
-        }
+        }, true /* traverseTopToBottom */);
     }
 
     void onWindowFreezeTimeout() {
         Slog.w(TAG_WM, "Window freeze timeout expired.");
         mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
-        for (int i = mWindows.size() - 1; i >= 0; --i) {
-            final WindowState w = mWindows.get(i);
+
+        forAllWindows(w -> {
             if (!w.mOrientationChanging) {
-                continue;
+                return;
             }
             w.mOrientationChanging = false;
             w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                     - mService.mDisplayFreezeTime);
             Slog.w(TAG_WM, "Force clearing orientation change: " + w);
-        }
+        }, true /* traverseTopToBottom */);
         mService.mWindowPlacerLocked.performSurfacePlacement();
     }
 
     void waitForAllWindowsDrawn() {
         final WindowManagerPolicy policy = mService.mPolicy;
-        for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState win = mWindows.get(winNdx);
-            final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs);
-            if (win.isVisibleLw() && (win.mAppToken != null || keyguard)) {
-                win.mWinAnimator.mDrawState = DRAW_PENDING;
+        forAllWindows(w -> {
+            final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs);
+            if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) {
+                w.mWinAnimator.mDrawState = DRAW_PENDING;
                 // Force add to mResizingWindows.
-                win.mLastContentInsets.set(-1, -1, -1, -1);
-                mService.mWaitingForDrawn.add(win);
+                w.mLastContentInsets.set(-1, -1, -1, -1);
+                mService.mWaitingForDrawn.add(w);
             }
-        }
+        }, true /* traverseTopToBottom */);
     }
 
     // TODO: Super crazy long method that should be broken down...
     boolean applySurfaceChangesTransaction(boolean recoveringMemory) {
 
-        boolean focusDisplayed = false;
-        boolean displayHasContent = false;
-        float preferredRefreshRate = 0;
-        int preferredModeId = 0;
-
-
         final int dw = mDisplayInfo.logicalWidth;
         final int dh = mDisplayInfo.logicalHeight;
         final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
@@ -2489,7 +1678,7 @@
             // Remove check for default display when there will be support for multiple wallpaper
             // targets (on different displays).
             if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
-                adjustWallpaperWindows();
+                mWallpaperController.adjustWallpaperWindows(this);
             }
 
             if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
@@ -2516,55 +1705,59 @@
 
             if (isDefaultDisplay) {
                 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
-                for (int i = mWindows.size() - 1; i >= 0; i--) {
-                    final WindowState w = mWindows.get(i);
+                forAllWindows(w -> {
                     mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
                             mService.mInputMethodTarget);
-                }
+                }, true /* traverseTopToBottom */);
                 pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw();
                 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
                         "after finishPostLayoutPolicyLw", pendingLayoutChanges);
             }
         } while (pendingLayoutChanges != 0);
 
-        RootWindowContainer root = mService.mRoot;
-        boolean obscured = false;
-        boolean syswin = false;
+        final RootWindowContainer root = mService.mRoot;
+        mTmpApplySurfaceChangesTransactionState.reset();
         resetDimming();
 
         // Only used if default window
         final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
 
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState w = mWindows.get(i);
-            final Task task = w.getTask();
-            final boolean obscuredChanged = w.mObscured != obscured;
+        forAllWindows(w -> {
+            final boolean obscuredChanged = w.mObscured !=
+                    mTmpApplySurfaceChangesTransactionState.obscured;
 
             // Update effect.
-            w.mObscured = obscured;
-            if (!obscured) {
+            w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;
+            if (!mTmpApplySurfaceChangesTransactionState.obscured) {
                 final boolean isDisplayed = w.isDisplayedLw();
 
                 if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) {
                     // This window completely covers everything behind it, so we want to leave all
                     // of them as undimmed (for performance reasons).
                     root.mObscuringWindow = w;
-                    obscured = true;
+                    mTmpApplySurfaceChangesTransactionState.obscured = true;
                 }
 
-                displayHasContent |= root.handleNotObscuredLocked(w, obscured, syswin);
+                mTmpApplySurfaceChangesTransactionState.displayHasContent |=
+                        root.handleNotObscuredLocked(w,
+                                mTmpApplySurfaceChangesTransactionState.obscured,
+                                mTmpApplySurfaceChangesTransactionState.syswin);
 
                 if (w.mHasSurface && isDisplayed) {
                     final int type = w.mAttrs.type;
                     if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
                             || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                        syswin = true;
+                        mTmpApplySurfaceChangesTransactionState.syswin = true;
                     }
-                    if (preferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
-                        preferredRefreshRate = w.mAttrs.preferredRefreshRate;
+                    if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0
+                            && w.mAttrs.preferredRefreshRate != 0) {
+                        mTmpApplySurfaceChangesTransactionState.preferredRefreshRate
+                                = w.mAttrs.preferredRefreshRate;
                     }
-                    if (preferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
-                        preferredModeId = w.mAttrs.preferredDisplayModeId;
+                    if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0
+                            && w.mAttrs.preferredDisplayModeId != 0) {
+                        mTmpApplySurfaceChangesTransactionState.preferredModeId
+                                = w.mAttrs.preferredDisplayModeId;
                     }
                 }
             }
@@ -2637,16 +1830,16 @@
 
             if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
                     && w.isDisplayedLw()) {
-                focusDisplayed = true;
+                mTmpApplySurfaceChangesTransactionState.focusDisplayed = true;
             }
 
             w.updateResizingWindowIfNeeded();
-        }
+        }, true /* traverseTopToBottom */);
 
         mService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
-                displayHasContent,
-                preferredRefreshRate,
-                preferredModeId,
+                mTmpApplySurfaceChangesTransactionState.displayHasContent,
+                mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
+                mTmpApplySurfaceChangesTransactionState.preferredModeId,
                 true /* inTraversal, must call performTraversalInTrans... below */);
 
         stopDimmingIfNeeded();
@@ -2658,7 +1851,7 @@
             atoken.updateAllDrawn(this);
         }
 
-        return focusDisplayed;
+        return mTmpApplySurfaceChangesTransactionState.focusDisplayed;
     }
 
     void performLayout(boolean initial, boolean updateInputWindows) {
@@ -2691,110 +1884,110 @@
         if (seq < 0) seq = 0;
         mService.mLayoutSeq = seq;
 
-        boolean behindDream = false;
+        // Used to indicate that we have processed the dream window and all additional windows are
+        // behind it.
+        mTmpWindow = null;
 
         // First perform layout of any root windows (not attached to another window).
-        int topAttached = -1;
-        for (i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState win = mWindows.get(i);
-
+        forAllWindows(w -> {
             // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid
             // wasting time and funky changes while a window is animating away.
-            final boolean gone = (behindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win))
-                    || win.isGoneForLayoutLw();
+            final boolean gone = (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w))
+                    || w.isGoneForLayoutLw();
 
-            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
-                Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
-                        + " mLayoutAttached=" + win.mLayoutAttached
-                        + " screen changed=" + win.isConfigChanged());
-                final AppWindowToken atoken = win.mAppToken;
-                if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + win.mViewVisibility
-                        + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden
+            if (DEBUG_LAYOUT && !w.mLayoutAttached) {
+                Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
+                        + " mLayoutAttached=" + w.mLayoutAttached
+                        + " screen changed=" + w.isConfigChanged());
+                final AppWindowToken atoken = w.mAppToken;
+                if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + w.mViewVisibility
+                        + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden
                         + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested)
-                        + " parentHidden=" + win.isParentWindowHidden());
-                else Slog.v(TAG, "  VIS: mViewVisibility=" + win.mViewVisibility
-                        + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden
+                        + " parentHidden=" + w.isParentWindowHidden());
+                else Slog.v(TAG, "  VIS: mViewVisibility=" + w.mViewVisibility
+                        + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden
                         + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested)
-                        + " parentHidden=" + win.isParentWindowHidden());
+                        + " parentHidden=" + w.isParentWindowHidden());
             }
 
             // If this view is GONE, then skip it -- keep the current frame, and let the caller know
             // so they can ignore it if they want.  (We do the normal layout for INVISIBLE windows,
             // since that means "perform layout as normal, just don't display").
-            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || ((win.isConfigChanged() || win.setReportResizeHints())
-                    && !win.isGoneForLayoutLw() &&
-                    ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                            (win.mHasSurface && win.mAppToken != null &&
-                                    win.mAppToken.layoutConfigChanges)))) {
-                if (!win.mLayoutAttached) {
+            if (!gone || !w.mHaveFrame || w.mLayoutNeeded
+                    || ((w.isConfigChanged() || w.setReportResizeHints())
+                    && !w.isGoneForLayoutLw() &&
+                    ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
+                            (w.mHasSurface && w.mAppToken != null &&
+                                    w.mAppToken.layoutConfigChanges)))) {
+                if (!w.mLayoutAttached) {
                     if (initial) {
                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
+                        w.mContentChanged = false;
                     }
-                    if (win.mAttrs.type == TYPE_DREAM) {
+                    if (w.mAttrs.type == TYPE_DREAM) {
                         // Don't layout windows behind a dream, so that if it does stuff like hide
                         // the status bar we won't get a bad transition when it goes away.
-                        behindDream = true;
+                        mTmpWindow = w;
                     }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mService.mPolicy.layoutWindowLw(win, null);
-                    win.mLayoutSeq = seq;
+                    w.mLayoutNeeded = false;
+                    w.prelayout();
+                    mService.mPolicy.layoutWindowLw(w, null);
+                    w.mLayoutSeq = mService.mLayoutSeq;
 
                     // Window frames may have changed. Update dim layer with the new bounds.
-                    final Task task = win.getTask();
+                    final Task task = w.getTask();
                     if (task != null) {
                         mDimLayerController.updateDimLayer(task);
                     }
 
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + win.mFrame
-                            + " mContainingFrame=" + win.mContainingFrame
-                            + " mDisplayFrame=" + win.mDisplayFrame);
-                } else {
-                    if (topAttached < 0) topAttached = i;
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + w.mFrame
+                            + " mContainingFrame=" + w.mContainingFrame
+                            + " mDisplayFrame=" + w.mDisplayFrame);
                 }
             }
-        }
+        }, true /* traverseTopToBottom */);
 
-        boolean attachedBehindDream = false;
+        // Used to indicate that we have processed the dream window and all additional attached
+        // windows are behind it.
+        final WindowState dreamWin = mTmpWindow;
+        mTmpWindow = null;
 
         // Now perform layout of attached windows, which usually depend on the position of the
         // window they are attached to. XXX does not deal with windows that are attached to windows
         // that are themselves attached.
-        for (i = topAttached; i >= 0; i--) {
-            final WindowState win = mWindows.get(i);
-
-            if (win.mLayoutAttached) {
-                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame
-                        + " mViewVisibility=" + win.mViewVisibility
-                        + " mRelayoutCalled=" + win.mRelayoutCalled);
-                // If this view is GONE, then skip it -- keep the current frame, and let the caller
-                // know so they can ignore it if they want.  (We do the normal layout for INVISIBLE
-                // windows, since that means "perform layout as normal, just don't display").
-                if (attachedBehindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win)) {
-                    continue;
+        forAllWindows(w -> {
+            if (w.mLayoutAttached) {
+                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
+                        + " mViewVisibility=" + w.mViewVisibility
+                        + " mRelayoutCalled=" + w.mRelayoutCalled);
+                // If this view is GONE, then skip it -- keep the current frame, and let the
+                // caller know so they can ignore it if they want.  (We do the normal layout for
+                // INVISIBLE windows, since that means "perform layout as normal, just don't
+                // display").
+                if (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) {
+                    return;
                 }
-                if ((win.mViewVisibility != GONE && win.mRelayoutCalled) || !win.mHaveFrame
-                        || win.mLayoutNeeded) {
+                if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame
+                        || w.mLayoutNeeded) {
                     if (initial) {
                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                        win.mContentChanged = false;
+                        w.mContentChanged = false;
                     }
-                    win.mLayoutNeeded = false;
-                    win.prelayout();
-                    mService.mPolicy.layoutWindowLw(win, win.getParentWindow());
-                    win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + win.mFrame
-                            + " mContainingFrame=" + win.mContainingFrame
-                            + " mDisplayFrame=" + win.mDisplayFrame);
+                    w.mLayoutNeeded = false;
+                    w.prelayout();
+                    mService.mPolicy.layoutWindowLw(w, w.getParentWindow());
+                    w.mLayoutSeq = mService.mLayoutSeq;
+                    if (DEBUG_LAYOUT)
+                        Slog.v(TAG, "  LAYOUT: mFrame=" + w.mFrame
+                                + " mContainingFrame=" + w.mContainingFrame
+                                + " mDisplayFrame=" + w.mDisplayFrame);
                 }
-            } else if (win.mAttrs.type == TYPE_DREAM) {
+            } else if (w.mAttrs.type == TYPE_DREAM) {
                 // Don't layout windows behind a dream, so that if it does stuff like hide the
                 // status bar we won't get a bad transition when it goes away.
-                attachedBehindDream = behindDream;
+                mTmpWindow = dreamWin;
             }
-        }
+        }, true /* traverseTopToBottom */);
 
         // Window frames may have changed. Tell the input dispatcher about it.
         mService.mInputMonitor.layoutInputConsumers(dw, dh);
@@ -2818,7 +2011,7 @@
      * @param config of the output bitmap
      * @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot
      */
-    Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height,
+    Bitmap screenshotApplications(IBinder appToken, int width, int height,
             boolean includeFullDisplay, float frameScale, Bitmap.Config config,
             boolean wallpaperOnly) {
         int dw = mDisplayInfo.logicalWidth;
@@ -2831,22 +2024,10 @@
 
         Bitmap bm = null;
 
-        int maxLayer = 0;
+        mScreenshotApplicationState.reset(appToken == null && !wallpaperOnly);
         final Rect frame = new Rect();
         final Rect stackBounds = new Rect();
 
-        boolean screenshotReady;
-        int minLayer;
-        if (appToken == null && !wallpaperOnly) {
-            screenshotReady = true;
-            minLayer = 0;
-        } else {
-            screenshotReady = false;
-            minLayer = Integer.MAX_VALUE;
-        }
-
-        WindowState appWin = null;
-
         boolean includeImeInScreenshot;
         synchronized(mService.mWindowMap) {
             final AppWindowToken imeTargetAppToken = mService.mInputMethodTarget != null
@@ -2867,70 +2048,69 @@
 
         synchronized(mService.mWindowMap) {
             // Figure out the part of the screen that is actually the app.
-            appWin = null;
-            for (int i = mWindows.size() - 1; i >= 0; i--) {
-                final WindowState ws = mWindows.get(i);
-                if (!ws.mHasSurface) {
-                    continue;
+            mScreenshotApplicationState.appWin = null;
+            forAllWindows(w -> {
+                if (!w.mHasSurface) {
+                    return false;
                 }
-                if (ws.mLayer >= aboveAppLayer) {
-                    continue;
+                if (w.mLayer >= aboveAppLayer) {
+                    return false;
                 }
-                if (wallpaperOnly && !ws.mIsWallpaper) {
-                    continue;
+                if (wallpaperOnly && !w.mIsWallpaper) {
+                    return false;
                 }
-                if (ws.mIsImWindow) {
+                if (w.mIsImWindow) {
                     if (!includeImeInScreenshot) {
-                        continue;
+                        return false;
                     }
-                } else if (ws.mIsWallpaper) {
+                } else if (w.mIsWallpaper) {
                     // If this is the wallpaper layer and we're only looking for the wallpaper layer
                     // then the target window state is this one.
                     if (wallpaperOnly) {
-                        appWin = ws;
+                        mScreenshotApplicationState.appWin = w;
                     }
 
-                    if (appWin == null) {
+                    if (mScreenshotApplicationState.appWin == null) {
                         // We have not ran across the target window yet, so it is probably behind
                         // the wallpaper. This can happen when the keyguard is up and all windows
                         // are moved behind the wallpaper. We don't want to include the wallpaper
                         // layer in the screenshot as it will cover-up the layer of the target
                         // window.
-                        continue;
+                        return false;
                     }
                     // Fall through. The target window is in front of the wallpaper. For this
                     // case we want to include the wallpaper layer in the screenshot because
                     // the target window might have some transparent areas.
                 } else if (appToken != null) {
-                    if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
+                    if (w.mAppToken == null || w.mAppToken.token != appToken) {
                         // This app window is of no interest if it is not associated with the
                         // screenshot app.
-                        continue;
+                        return false;
                     }
-                    appWin = ws;
+                    mScreenshotApplicationState.appWin = w;
                 }
 
                 // Include this window.
 
-                final WindowStateAnimator winAnim = ws.mWinAnimator;
+                final WindowStateAnimator winAnim = w.mWinAnimator;
                 int layer = winAnim.mSurfaceController.getLayer();
-                if (maxLayer < layer) {
-                    maxLayer = layer;
+                if (mScreenshotApplicationState.maxLayer < layer) {
+                    mScreenshotApplicationState.maxLayer = layer;
                 }
-                if (minLayer > layer) {
-                    minLayer = layer;
+                if (mScreenshotApplicationState.minLayer > layer) {
+                    mScreenshotApplicationState.minLayer = layer;
                 }
 
                 // Don't include wallpaper in bounds calculation
-                if (!includeFullDisplay && !ws.mIsWallpaper) {
-                    final Rect wf = ws.mFrame;
-                    final Rect cr = ws.mContentInsets;
+                if (!includeFullDisplay && !w.mIsWallpaper) {
+                    final Rect wf = w.mFrame;
+                    final Rect cr = w.mContentInsets;
                     int left = wf.left + cr.left;
                     int top = wf.top + cr.top;
                     int right = wf.right - cr.right;
                     int bottom = wf.bottom - cr.bottom;
                     frame.union(left, top, right, bottom);
-                    ws.getVisibleBounds(stackBounds);
+                    w.getVisibleBounds(stackBounds);
                     if (!Rect.intersects(frame, stackBounds)) {
                         // Set frame empty if there's no intersection.
                         frame.setEmpty();
@@ -2938,16 +2118,22 @@
                 }
 
                 final boolean foundTargetWs =
-                        (ws.mAppToken != null && ws.mAppToken.token == appToken)
-                                || (appWin != null && wallpaperOnly);
-                if (foundTargetWs && ws.isDisplayedLw() && winAnim.getShown()) {
-                    screenshotReady = true;
+                        (w.mAppToken != null && w.mAppToken.token == appToken)
+                                || (mScreenshotApplicationState.appWin != null && wallpaperOnly);
+                if (foundTargetWs && w.isDisplayedLw() && winAnim.getShown()) {
+                    mScreenshotApplicationState.screenshotReady = true;
                 }
 
-                if (ws.isObscuringFullscreen(mDisplayInfo)){
-                    break;
+                if (w.isObscuringFullscreen(mDisplayInfo)){
+                    return true;
                 }
-            }
+                return false;
+            }, true /* traverseTopToBottom */);
+
+            final WindowState appWin = mScreenshotApplicationState.appWin;
+            final boolean screenshotReady = mScreenshotApplicationState.screenshotReady;
+            final int maxLayer = mScreenshotApplicationState.maxLayer;
+            final int minLayer = mScreenshotApplicationState.minLayer;
 
             if (appToken != null && appWin == null) {
                 // Can't find a window to snapshot.
@@ -3019,14 +2205,13 @@
             if (DEBUG_SCREENSHOT) {
                 Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
                         + maxLayer + " appToken=" + appToken);
-                for (int i = 0; i < mWindows.size(); i++) {
-                    final WindowState win = mWindows.get(i);
-                    final WindowSurfaceController controller = win.mWinAnimator.mSurfaceController;
-                    Slog.i(TAG_WM, win + ": " + win.mLayer
-                            + " animLayer=" + win.mWinAnimator.mAnimLayer
+                forAllWindows(w -> {
+                    final WindowSurfaceController controller = w.mWinAnimator.mSurfaceController;
+                    Slog.i(TAG_WM, w + ": " + w.mLayer
+                            + " animLayer=" + w.mWinAnimator.mAnimLayer
                             + " surfaceLayer=" + ((controller == null)
                             ? "null" : controller.getLayer()));
-                }
+                }, false /* traverseTopToBottom */);
             }
 
             final ScreenRotationAnimation screenRotationAnimation =
@@ -3063,6 +2248,9 @@
                 }
             }
             if (allBlack) {
+                final WindowState appWin = mScreenshotApplicationState.appWin;
+                final int maxLayer = mScreenshotApplicationState.maxLayer;
+                final int minLayer = mScreenshotApplicationState.minLayer;
                 Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" +
                         Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
                         (appWin != null ?
@@ -3103,32 +2291,23 @@
     }
 
     void onSeamlessRotationTimeout() {
-        boolean layoutNeeded = false;
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            final WindowState w = mWindows.get(i);
+        // Used to indicate the layout is needed.
+        mTmpWindow = null;
+
+        forAllWindows(w -> {
             if (!w.mSeamlesslyRotated) {
-                continue;
+                return;
             }
-            layoutNeeded = true;
+            mTmpWindow = w;
             w.setDisplayLayoutNeeded();
             mService.markForSeamlessRotation(w, false);
-        }
+        }, true /* traverseTopToBottom */);
 
-        if (layoutNeeded) {
+        if (mTmpWindow != null) {
             mService.mWindowPlacerLocked.performSurfacePlacement();
         }
     }
 
-    static final class GetWindowOnDisplaySearchResult {
-        boolean reachedToken;
-        WindowState foundWindow;
-
-        void reset() {
-            reachedToken = false;
-            foundWindow = null;
-        }
-    }
-
     static final class TaskForResizePointSearchResult {
         boolean searchDone;
         Task taskForResize;
@@ -3139,6 +2318,39 @@
         }
     }
 
+    private static final class ApplySurfaceChangesTransactionState {
+        boolean displayHasContent;
+        boolean obscured;
+        boolean syswin;
+        boolean focusDisplayed;
+        float preferredRefreshRate;
+        int preferredModeId;
+
+        void reset() {
+            displayHasContent = false;
+            obscured = false;
+            syswin = false;
+            focusDisplayed = false;
+            preferredRefreshRate = 0;
+            preferredModeId = 0;
+        }
+    }
+
+    private static final class ScreenshotApplicationState {
+        WindowState appWin;
+        int maxLayer;
+        int minLayer;
+        boolean screenshotReady;
+
+        void reset(boolean screenshotReady) {
+            appWin = null;
+            maxLayer = 0;
+            minLayer = 0;
+            this.screenshotReady = screenshotReady;
+            minLayer = (screenshotReady) ? 0 : Integer.MAX_VALUE;
+        }
+    }
+
     /**
      * Base class for any direct child window container of {@link #DisplayContent} need to inherit
      * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
@@ -3191,15 +2403,6 @@
         void removeStackFromDisplay(TaskStack stack) {
             removeChild(stack);
             stack.onRemovedFromDisplay();
-            // TODO: remove when window list will be gone.
-            // Manually remove records from window list and tap excluded windows list.
-            for (int i = mWindows.size() - 1; i >= 0; --i) {
-                final WindowState windowState = mWindows.get(i);
-                if (stack == windowState.getStack()) {
-                    mWindows.remove(i);
-                    mTapExcludedWindows.remove(windowState);
-                }
-            }
         }
 
         void moveStack(TaskStack stack, boolean toTop) {
@@ -3235,17 +2438,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 +2468,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 +2480,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
@@ -3327,6 +2547,40 @@
         }
 
         @Override
+        int getOrientation() {
+            final WindowManagerPolicy policy = mService.mPolicy;
+            // Find a window requesting orientation.
+            final WindowState win = getWindow((w) -> {
+                if (!w.isVisibleLw() || !w.mPolicyVisibilityAfterAnim) {
+                    return false;
+                }
+                final int req = w.mAttrs.screenOrientation;
+                if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND
+                        || req == SCREEN_ORIENTATION_UNSET) {
+                    return false;
+                }
+                return true;
+            });
+
+            if (win != null) {
+                final int req = win.mAttrs.screenOrientation;
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
+                if (policy.isKeyguardHostWindow(win.mAttrs)) {
+                    mService.mLastKeyguardForcedOrientation = req;
+                }
+                return (mService.mLastWindowForcedOrientation = req);
+            }
+
+            mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+            if (policy.isKeyguardShowingAndNotOccluded()) {
+                return mService.mLastKeyguardForcedOrientation;
+            }
+
+            return SCREEN_ORIENTATION_UNSET;
+        }
+
+        @Override
         String getName() {
             return mName;
         }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index c56f6b8..f8b461e 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -206,10 +206,12 @@
             config.unset();
             config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
             config.screenWidthDp = (int)
-                    (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode) /
+                    (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode,
+                            mDisplayContent.getDisplayId()) /
                             mDisplayContent.getDisplayMetrics().density);
             config.screenHeightDp = (int)
-                    (mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode) /
+                    (mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode,
+                            mDisplayContent.getDisplayId()) /
                             mDisplayContent.getDisplayMetrics().density);
             final Context rotationContext = mService.mContext.createConfigurationContext(config);
             mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
diff --git a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
index 7cb6fc3..70478fe 100644
--- a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.ClipData;
 import android.net.Uri;
 import android.os.Binder;
@@ -61,7 +61,7 @@
         mActivityToken = activityToken;
 
         // Will throw if Activity is not found.
-        IBinder permissionOwner = ActivityManagerNative.getDefault().
+        IBinder permissionOwner = ActivityManager.getService().
                 getUriPermissionOwnerForActivity(mActivityToken);
 
         doTake(permissionOwner);
@@ -71,7 +71,7 @@
         long origId = Binder.clearCallingIdentity();
         try {
             for (int i = 0; i < mUris.size(); i++) {
-                ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
+                ActivityManager.getService().grantUriPermissionFromOwner(
                         permissionOwner, mSourceUid, mTargetPackage, mUris.get(i), mMode,
                         mSourceUserId, mTargetUserId);
             }
@@ -85,7 +85,7 @@
         if (mActivityToken != null || mPermissionOwnerToken != null) {
             return;
         }
-        mPermissionOwnerToken = ActivityManagerNative.getDefault().newUriPermissionOwner("drop");
+        mPermissionOwnerToken = ActivityManager.getService().newUriPermissionOwner("drop");
         mTransientToken = transientToken;
         mTransientToken.linkToDeath(this, 0);
 
@@ -101,7 +101,7 @@
         IBinder permissionOwner = null;
         if (mActivityToken != null) {
             try {
-                permissionOwner = ActivityManagerNative.getDefault().
+                permissionOwner = ActivityManager.getService().
                         getUriPermissionOwnerForActivity(mActivityToken);
             } catch (Exception e) {
                 // Activity is destroyed, permissions already revoked.
@@ -117,7 +117,7 @@
         }
 
         for (int i = 0; i < mUris.size(); ++i) {
-            ActivityManagerNative.getDefault().revokeUriPermissionFromOwner(
+            ActivityManager.getService().revokeUriPermissionFromOwner(
                     permissionOwner, mUris.get(i), mMode, mSourceUserId);
         }
     }
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 4d195e8..40b737d 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -271,8 +271,9 @@
             Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
         }
 
-        mDisplayContent.forAllWindows((w) -> sendDragStartedLw(w, touchX, touchY, mDataDescription),
-                false /* traverseTopToBottom */ );
+        mDisplayContent.forAllWindows(w -> {
+            sendDragStartedLw(w, touchX, touchY, mDataDescription);
+        }, false /* traverseTopToBottom */ );
     }
 
     /* helper - send a ACTION_DRAG_STARTED event, if the
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index a8eb75c..01d1c30 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,17 +16,22 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
 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;
@@ -70,6 +75,10 @@
     // Array of window handles to provide to the input dispatcher.
     private InputWindowHandle[] mInputWindowHandles;
     private int mInputWindowHandleCount;
+    private boolean mAddInputConsumerHandle;
+    private boolean mAddPipInputConsumerHandle;
+    private boolean mAddWallpaperInputConsumerHandle;
+    private boolean mDisableWallpaperTouchEvents;
 
     // Set to true when the first input device configuration change notification
     // is received to indicate that the input devices are ready.
@@ -252,7 +261,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.
@@ -323,12 +332,12 @@
         }
     }
 
-    public void setUpdateInputWindowsNeededLw() {
+    void setUpdateInputWindowsNeededLw() {
         mUpdateInputWindowsNeeded = true;
     }
 
     /* Updates the cached window information provided to the input dispatcher. */
-    public void updateInputWindowsLw(boolean force) {
+    void updateInputWindowsLw(boolean force) {
         if (!force && !mUpdateInputWindowsNeeded) {
             return;
         }
@@ -372,15 +381,92 @@
         }
 
         // Add all windows on the default display.
-        mService.mRoot.updateInputWindows(this, mInputFocus, inDrag);
+        updateInputWindows(inDrag);
+
+        if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
+    }
+
+    private void updateInputWindows(boolean inDrag) {
+
+        clearInputWindowHandlesLw();
+
+        // TODO: multi-display
+        final InputConsumerImpl navInputConsumer =
+                getInputConsumer(INPUT_CONSUMER_NAVIGATION, DEFAULT_DISPLAY);
+        final InputConsumerImpl pipInputConsumer =
+                getInputConsumer(INPUT_CONSUMER_PIP, DEFAULT_DISPLAY);
+        final InputConsumerImpl wallpaperInputConsumer =
+                getInputConsumer(INPUT_CONSUMER_WALLPAPER, DEFAULT_DISPLAY);
+        mAddInputConsumerHandle = navInputConsumer != null;
+        mAddPipInputConsumerHandle = pipInputConsumer != null;
+        mAddWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
+        final Rect pipTouchableBounds = mAddPipInputConsumerHandle ? new Rect() : null;
+        mDisableWallpaperTouchEvents = false;
+
+        final WallpaperController wallpaperController = mService.mRoot.mWallpaperController;
+        mService.mRoot.forAllWindows(w -> {
+            final InputChannel inputChannel = w.mInputChannel;
+            final InputWindowHandle inputWindowHandle = w.mInputWindowHandle;
+            if (inputChannel == null || inputWindowHandle == null || w.mRemoved
+                    || w.isAdjustedForMinimizedDock()) {
+                // Skip this window because it cannot possibly receive input.
+                return;
+            }
+
+            if (mAddPipInputConsumerHandle
+                    && w.getStackId() == PINNED_STACK_ID
+                    && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) {
+                // Update the bounds of the Pip input consumer to match the Pinned stack
+                w.getStack().getBounds(pipTouchableBounds);
+                pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds);
+                addInputWindowHandle(pipInputConsumer.mWindowHandle);
+                mAddPipInputConsumerHandle = false;
+            }
+
+            if (mAddInputConsumerHandle
+                    && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
+                addInputWindowHandle(navInputConsumer.mWindowHandle);
+                mAddInputConsumerHandle = false;
+            }
+
+            if (mAddWallpaperInputConsumerHandle) {
+                if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisibleLw()) {
+                    // Add the wallpaper input consumer above the first visible wallpaper.
+                    addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
+                    mAddWallpaperInputConsumerHandle = false;
+                }
+            }
+
+            final int flags = w.mAttrs.flags;
+            final int privateFlags = w.mAttrs.privateFlags;
+            final int type = w.mAttrs.type;
+
+            final boolean hasFocus = w == mInputFocus;
+            final boolean isVisible = w.isVisibleLw();
+            if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
+                mDisableWallpaperTouchEvents = true;
+            }
+            final boolean hasWallpaper = wallpaperController.isWallpaperTarget(w)
+                    && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
+                    && !mDisableWallpaperTouchEvents;
+
+            // If there's a drag in progress and 'child' is a potential drop target,
+            // make sure it's been told about the drag
+            if (inDrag && isVisible && w.getDisplayContent().isDefaultDisplay) {
+                mService.mDragState.sendDragStartedIfNeededLw(w);
+            }
+
+            addInputWindowHandle(
+                    inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper);
+        }, true /* traverseTopToBottom */);
+
+        if (mAddWallpaperInputConsumerHandle) {
+            // No visible wallpaper found, add the wallpaper input consumer at the end.
+            addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
+        }
 
         // Send windows to native code.
         mService.mInputManager.setInputWindows(mInputWindowHandles);
-
-        // Clear the list in preparation for the next round.
-        clearInputWindowHandlesLw();
-
-        if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
     }
 
     /* Notifies that the input device configuration has changed. */
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/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 88986e3..1962ca7 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -219,7 +219,7 @@
         return false;
     }
 
-    void getWindowsByName(WindowList output, String name) {
+    void getWindowsByName(ArrayList<WindowState> output, String name) {
         int objectId = 0;
         // See if this is an object ID.
         try {
@@ -231,7 +231,7 @@
         getWindowsByName(output, name, objectId);
     }
 
-    private void getWindowsByName(WindowList output, String name, int objectId) {
+    private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
         forAllWindows((w) -> {
             if (name != null) {
                 if (w.mAttrs.getTitle().toString().contains(name)) {
@@ -276,15 +276,6 @@
         return null;
     }
 
-    // TODO: Users would have their own window containers under the display container?
-    void switchUser() {
-        final int count = mChildren.size();
-        for (int i = 0; i < count; ++i) {
-            final DisplayContent dc = mChildren.get(i);
-            dc.switchUser();
-        }
-    }
-
     /**
      * Set new display override config and return array of ids of stacks that were changed during
      * update. If called for the default display, global configuration will also be updated.
@@ -429,14 +420,6 @@
         return hasChanges;
     }
 
-    void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
-        final int count = mChildren.size();
-        for (int i = 0; i < count; ++i) {
-            final DisplayContent dc = mChildren.get(i);
-            dc.updateInputWindows(inputMonitor, inputFocus, inDrag);
-        }
-    }
-
     boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
             boolean secure) {
         final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b889db2..772833c8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -589,46 +589,6 @@
         }
     }
 
-    void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token,
-            DisplayContent.GetWindowOnDisplaySearchResult result) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final AppWindowToken current = mChildren.get(i);
-            if (current == token) {
-                // We have reach the token we are interested in. End search.
-                result.reachedToken = true;
-                return;
-            }
-
-            // We haven't reached the token yet; if this token is not going to the bottom and
-            // has windows on this display, then it is a candidate for what we are looking for.
-            final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current);
-            if (!current.sendingToBottom && tokenWindowList.size() > 0) {
-                result.foundWindow = tokenWindowList.get(0);
-            }
-        }
-    }
-
-    void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token,
-            DisplayContent.GetWindowOnDisplaySearchResult result) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final AppWindowToken current = mChildren.get(i);
-            if (!result.reachedToken) {
-                if (current == token) {
-                    // We have reached the token we are interested in. Get whichever window occurs
-                    // after it that is on the same display.
-                    result.reachedToken = true;
-                }
-                continue;
-            }
-
-            final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current);
-            if (tokenWindowList.size() > 0) {
-                result.foundWindow = tokenWindowList.get(tokenWindowList.size() - 1);
-                return;
-            }
-        }
-    }
-
     @Override
     boolean fillsParent() {
         return mFillsParent || !StackId.isTaskResizeAllowed(mStack.mStackId);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 203ba72..f2c74df 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -859,7 +859,9 @@
     }
 
     // TODO: Should each user have there own stacks?
+    @Override
     void switchUser() {
+        super.switchUser();
         int top = mChildren.size();
         for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
             Task task = mChildren.get(taskNdx);
@@ -1488,30 +1490,6 @@
         }
     }
 
-    void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token,
-            DisplayContent.GetWindowOnDisplaySearchResult result) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final Task task = mChildren.get(i);
-            task.getWindowOnDisplayBeforeToken(dc, token, result);
-            if (result.reachedToken) {
-                // We have reach the token we are interested in. End search.
-                return;
-            }
-        }
-    }
-
-    void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token,
-            DisplayContent.GetWindowOnDisplaySearchResult result) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final Task task = mChildren.get(i);
-            task.getWindowOnDisplayAfterToken(dc, token, result);
-            if (result.foundWindow != null) {
-                // We have found a window after the token. End search.
-                return;
-            }
-        }
-    }
-
     @Override
     int getOrientation() {
         return (StackId.canSpecifyOrientation(mStackId))
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index 2f49c82..8f4f09e 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -16,8 +16,13 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_UNKNOWN_APP_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.annotation.NonNull;
 import android.util.ArrayMap;
+import android.util.Slog;
 
 import com.android.server.wm.WindowManagerService.H;
 
@@ -31,6 +36,8 @@
  */
 class UnknownAppVisibilityController {
 
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "UnknownAppVisibility" : TAG_WM;
+
     /**
      * We are currently waiting until the app is done resuming.
      */
@@ -78,6 +85,9 @@
     }
 
     void appRemoved(@NonNull AppWindowToken appWindow) {
+        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
+            Slog.d(TAG, "App removed appWindow=" + appWindow);
+        }
         mUnknownApps.remove(appWindow);
     }
 
@@ -86,6 +96,9 @@
      * it is resumed and relaid out to resolve the visibility.
      */
     void notifyLaunched(@NonNull AppWindowToken appWindow) {
+        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
+            Slog.d(TAG, "App launched appWindow=" + appWindow);
+        }
         mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RESUME);
     }
 
@@ -95,6 +108,9 @@
     void notifyAppResumedFinished(@NonNull AppWindowToken appWindow) {
         if (mUnknownApps.containsKey(appWindow)
                 && mUnknownApps.get(appWindow) == UNKNOWN_STATE_WAITING_RESUME) {
+            if (DEBUG_UNKNOWN_APP_VISIBILITY) {
+                Slog.d(TAG, "App resume finished appWindow=" + appWindow);
+            }
             mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RELAYOUT);
         }
     }
@@ -106,6 +122,9 @@
         if (!mUnknownApps.containsKey(appWindow)) {
             return;
         }
+        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
+            Slog.d(TAG, "App relayouted appWindow=" + appWindow);
+        }
         int state = mUnknownApps.get(appWindow);
         if (state == UNKNOWN_STATE_WAITING_RELAYOUT) {
             mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
@@ -114,6 +133,9 @@
     }
 
     private void notifyVisibilitiesUpdated() {
+        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
+            Slog.d(TAG, "Visibility updated DONE");
+        }
         boolean changed = false;
         for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
             if (mUnknownApps.valueAt(i) == UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index d3e8e8e..7fd8028 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);
@@ -805,46 +683,30 @@
         }
     }
 
-    void dumpTokens(PrintWriter pw, String prefix, boolean dumpAll) {
-        if (!mWallpaperTokens.isEmpty()) {
-            pw.println();
-            pw.print(prefix); pw.println("Wallpaper tokens:");
-            for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
-                WindowToken token = mWallpaperTokens.get(i);
-                pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
-                pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                } else {
-                    pw.println();
-                }
-            }
-        }
-    }
-
     /** 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..f5db0b6 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -18,11 +18,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;
@@ -481,32 +482,45 @@
         return false;
     }
 
-    /**
-     * Rebuilds the WindowList for the input display content.
-     * @param addIndex The index in the window list to add the next entry to.
-     * @return The next index in the window list to.
-     */
-    // TODO: Hoping we can get rid of WindowList so this method wouldn't be needed.
-    int rebuildWindowList(int addIndex) {
-        final int count = mChildren.size();
-        for (int i = 0; i < count; i++) {
-            final WindowContainer wc = mChildren.get(i);
-            addIndex = wc.rebuildWindowList(addIndex);
+    // TODO: Users would have their own window containers under the display container?
+    void switchUser() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            mChildren.get(i).switchUser();
         }
-        return addIndex;
     }
 
-    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+    /**
+     * For all windows at or below this container call the callback.
+     * @param   callback Calls the {@link ToBooleanFunction#apply} method for each window found and
+     *                   stops the search if {@link ToBooleanFunction#apply} returns true.
+     * @param   traverseTopToBottom If true traverses the hierarchy from top-to-bottom in terms of
+     *                              z-order, else from bottom-to-top.
+     * @return  True if the search ended before we reached the end of the hierarchy due to
+     *          {@link Function#apply} returning true.
+     */
+    boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         if (traverseTopToBottom) {
             for (int i = mChildren.size() - 1; i >= 0; --i) {
-                mChildren.get(i).forAllWindows(callback, traverseTopToBottom);
+                if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             }
         } else {
             final int count = mChildren.size();
             for (int i = 0; i < count; i++) {
-                mChildren.get(i).forAllWindows(callback, traverseTopToBottom);
+                if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
+                    return true;
+                }
             }
         }
+        return false;
+    }
+
+    void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
+        forAllWindows(w -> {
+            callback.accept(w);
+            return false;
+        }, traverseTopToBottom);
     }
 
     WindowState getWindow(Predicate<WindowState> callback) {
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index c06e5cc..32373f9 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -23,6 +23,7 @@
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -63,17 +64,19 @@
     private int mCurBaseLayer;
     private int mCurLayer;
     private boolean mAnyLayerChanged;
+    private int mHighestLayerInImeTargetBaseLayer;
+    private WindowState mImeTarget;
 
     final void assignWindowLayers(DisplayContent dc) {
         if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based",
                 new RuntimeException("here").fillInStackTrace());
 
-        clear();
+        reset();
         dc.forAllWindows((w) -> {
             boolean layerChanged = false;
 
             int oldLayer = w.mLayer;
-            if (w.mBaseLayer == mCurBaseLayer || w.mIsImWindow) {
+            if (w.mBaseLayer == mCurBaseLayer) {
                 mCurLayer += WINDOW_LAYER_MULTIPLIER;
             } else {
                 mCurBaseLayer = mCurLayer = w.mBaseLayer;
@@ -92,6 +95,11 @@
                 mHighestApplicationLayer = Math.max(mHighestApplicationLayer,
                         w.mWinAnimator.mAnimLayer);
             }
+            if (mImeTarget != null && w.mBaseLayer == mImeTarget.mBaseLayer) {
+                mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
+                        w.mWinAnimator.mAnimLayer);
+            }
+
             collectSpecialWindows(w);
 
             if (layerChanged) {
@@ -103,7 +111,7 @@
 
         //TODO (multidisplay): Magnification is supported only for the default display.
         if (mService.mAccessibilityController != null && mAnyLayerChanged
-                && dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                && dc.getDisplayId() == DEFAULT_DISPLAY) {
             mService.mAccessibilityController.onWindowLayersChangedLocked();
         }
 
@@ -120,7 +128,7 @@
         }, false /* traverseTopToBottom */);
     }
 
-    private void clear() {
+    private void reset() {
         mHighestApplicationLayer = 0;
         mPinnedWindows.clear();
         mInputMethodWindows.clear();
@@ -132,6 +140,9 @@
         mCurBaseLayer = 0;
         mCurLayer = 0;
         mAnyLayerChanged = false;
+
+        mImeTarget = mService.mInputMethodTarget;
+        mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
     }
 
     private void collectSpecialWindows(WindowState w) {
@@ -174,22 +185,10 @@
 
         layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
 
-        boolean onTopLauncherVisible = !mOnTopLauncherWindows.isEmpty();
         while (!mOnTopLauncherWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mOnTopLauncherWindows.remove(), layer);
         }
 
-        // Make sure IME windows are showing above the dock divider and on-top launcher windows.
-        if ((mDockDivider != null && mDockDivider.isVisibleLw()) || onTopLauncherVisible) {
-            while (!mInputMethodWindows.isEmpty()) {
-                final WindowState w = mInputMethodWindows.remove();
-                // Only ever move IME windows up, else we brake IME for windows above the divider.
-                if (layer > w.mLayer) {
-                    layer = assignAndIncreaseLayerIfNeeded(w, layer);
-                }
-            }
-        }
-
         // We know that we will be animating a relaunching window in the near future, which will
         // receive a z-order increase. We want the replaced window to immediately receive the same
         // treatment, e.g. to be above the dock divider.
@@ -200,12 +199,26 @@
         while (!mPinnedWindows.isEmpty()) {
             layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
         }
+
+        // Make sure IME is the highest window in the base layer of it's target.
+        if (mImeTarget != null) {
+            if (mImeTarget.mAppToken == null) {
+                // For non-app ime targets adjust the layer we start from to match what we found
+                // when assigning layers. Otherwise, just use the highest app layer we have some far.
+                layer = mHighestLayerInImeTargetBaseLayer + WINDOW_LAYER_MULTIPLIER;
+            }
+
+            while (!mInputMethodWindows.isEmpty()) {
+                layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer);
+            }
+        }
+
     }
 
     private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
         if (win != null) {
             assignAnimLayer(win, layer);
-            // Make sure we leave space inbetween normal windows for dims and such.
+            // Make sure we leave space in-between normal windows for dims and such.
             layer += WINDOW_LAYER_MULTIPLIER;
         }
         return layer;
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index f11281e..1b61fca 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -73,6 +73,7 @@
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
     static final boolean SHOW_STACK_CRAWLS = false;
     static final boolean DEBUG_WINDOW_CROP = false;
+    static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
 
     static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
     static final boolean DEBUG_KEEP_SCREEN_ON = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c4c4bcd..507679b 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;
@@ -607,17 +606,6 @@
     boolean mInputMethodTargetWaitingAnim;
 
     WindowState mInputMethodWindow = null;
-    // TODO: Remove with extreme prejudice! This list is maintained so that we can keep track of
-    // dialogs that should go on top of the IME so they can be re-arranged in the window list any
-    // time the IME changes position in the window list. Normally you would have a dialog be a child
-    // window of the IME, but they don't share the same token since they are added by different
-    // clients. This doesn't really affect what the user sees on screen since this dialogs have an
-    // higher base layer than the IME window, but it will affect users of the window list that
-    // expect the list to represent the order of things on-screen (e.g input service). This makes
-    // the code for managing the window list hard to follow (see all the places it is used).
-    // We can remove the use of this field when we automatically assign layers and z-order the
-    // window list before it is used whenever window container order changes.
-    final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
 
     boolean mHardKeyboardAvailable;
     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
@@ -1018,7 +1006,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 =
@@ -1378,19 +1366,16 @@
 
             boolean imMayMove = true;
 
+            win.mToken.addWindow(win);
             if (type == TYPE_INPUT_METHOD) {
                 win.mGivenInsetsPending = true;
                 mInputMethodWindow = win;
-                win.mToken.addImeWindow(win);
+                displayContent.computeImeTarget(true /* updateImeTarget */);
                 imMayMove = false;
             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
-                mInputMethodDialogs.add(win);
-                win.mToken.addWindow(win);
-                displayContent.moveInputMethodDialogs(
-                        displayContent.findDesiredInputMethodWindowIndex(true));
+                displayContent.computeImeTarget(true /* updateImeTarget */);
                 imMayMove = false;
             } else {
-                win.mToken.addWindow(win);
                 if (type == TYPE_WALLPAPER) {
                     displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1463,7 +1448,7 @@
             }
 
             if (imMayMove) {
-                displayContent.moveInputMethodWindowsIfNeeded(false);
+                displayContent.computeImeTarget(true /* updateImeTarget */);
             }
 
             // Don't do layout here, the window must call
@@ -1647,8 +1632,6 @@
 
         if (mInputMethodWindow == win) {
             mInputMethodWindow = null;
-        } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
-            mInputMethodDialogs.remove(win);
         }
 
         final WindowToken token = win.mToken;
@@ -1678,13 +1661,11 @@
             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
         }
 
-        if (dc != null && dc.removeFromWindowList(win)) {
-            if (!mWindowPlacerLocked.isInLayout()) {
-                dc.assignWindowLayers(true /* setLayoutNeeded */);
-                mWindowPlacerLocked.performSurfacePlacement();
-                if (win.mAppToken != null) {
-                    win.mAppToken.updateReportedVisibilityLocked();
-                }
+        if (dc != null && !mWindowPlacerLocked.isInLayout()) {
+            dc.assignWindowLayers(true /* setLayoutNeeded */);
+            mWindowPlacerLocked.performSurfacePlacement();
+            if (win.mAppToken != null) {
+                win.mAppToken.updateReportedVisibilityLocked();
             }
         }
 
@@ -2065,14 +2046,15 @@
             // reassign them at this point if the IM window state gets shuffled
             boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
             final DisplayContent dc = win.getDisplayContent();
-            if (imMayMove && (dc.moveInputMethodWindowsIfNeeded(false) || toBeDisplayed)) {
-                // Little hack here -- we -should- be able to rely on the function to return true if
-                // the IME has moved and needs its layer recomputed.  However, if the IME was hidden
-                // and isn't actually moved in the list, its layer may be out of data so we make
-                // sure to recompute it.
-                // TODO: Probably not needed once the window list always has the right z-ordering
-                // when the window hierarchy is updated.
-                dc.assignWindowLayers(false /* setLayoutNeeded */);
+            if (imMayMove) {
+                dc.computeImeTarget(true /* updateImeTarget */);
+                if (toBeDisplayed) {
+                    // Little hack here -- we -should- be able to rely on the function to return
+                    // true if the IME has moved and needs its layer recomputed. However, if the IME
+                    // was hidden and isn't actually moved in the list, its layer may be out of data
+                    // so we make sure to recompute it.
+                    dc.assignWindowLayers(false /* setLayoutNeeded */);
+                }
             }
 
             if (wallpaperMayMove) {
@@ -3352,7 +3334,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(false);
                 }
-                displayContent.rebuildAppWindowsAndLayoutIfNeeded();
+                displayContent.layoutAndAssignWindowLayersIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3374,7 +3356,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(true);
                 }
-                stack.getDisplayContent().rebuildAppWindowsAndLayoutIfNeeded();
+                stack.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -4620,7 +4602,7 @@
                 return null;
             }
         }
-        return displayContent.screenshotApplications(appToken, displayId, width, height,
+        return displayContent.screenshotApplications(appToken, width, height,
                 includeFullDisplay, frameScale, config, wallpaperOnly);
     }
 
@@ -4906,9 +4888,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 +4903,7 @@
             }
         }
 
-        dc.forAllWindows((w) -> {
+        dc.forAllWindows(w -> {
             // Discard surface after orientation change, these can't be reused.
             if (w.mAppToken != null) {
                 w.mAppToken.destroySavedSurfaces();
@@ -5182,9 +5164,11 @@
 
         boolean result = true;
 
-        final WindowList windows = new WindowList();
+        final ArrayList<WindowState> windows = new ArrayList();
         synchronized (mWindowMap) {
-            mRoot.forAllWindows(windows::add, false /* traverseTopToBottom */);
+            mRoot.forAllWindows(w -> {
+                windows.add(w);
+            }, false /* traverseTopToBottom */);
         }
 
         BufferedWriter out = null;
@@ -5457,17 +5441,16 @@
         return config;
     }
 
-    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int uiMode,
-            int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
-        final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode);
+    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int displayId, int rotation,
+            int uiMode, int dw, int dh) {
+        final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode, displayId);
         if (width < displayInfo.smallestNominalAppWidth) {
             displayInfo.smallestNominalAppWidth = width;
         }
         if (width > displayInfo.largestNominalAppWidth) {
             displayInfo.largestNominalAppWidth = width;
         }
-        final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode);
+        final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode, displayId);
         if (height < displayInfo.smallestNominalAppHeight) {
             displayInfo.smallestNominalAppHeight = height;
         }
@@ -5477,11 +5460,10 @@
     }
 
     private int reduceConfigLayout(int curLayout, int rotation, float density,
-            int dw, int dh, int uiMode) {
-        // TODO: Multidisplay: for now only use with default display.
+            int dw, int dh, int uiMode, int displayId) {
         // Get the app screen size at this rotation.
-        int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode);
-        int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode);
+        int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId);
+        int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId);
 
         // Compute the screen layout size class for this rotation.
         int longSize = w;
@@ -5496,9 +5478,8 @@
         return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
     }
 
-    private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
-                  int uiMode, int dw, int dh, float density, Configuration outConfig) {
-        // TODO: Multidisplay: for now only use with default display.
+    private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, int displayId,
+            boolean rotated, int uiMode, int dw, int dh, float density, Configuration outConfig) {
 
         // We need to determine the smallest width that will occur under normal
         // operation.  To this, start with the base screen size and compute the
@@ -5516,24 +5497,33 @@
         displayInfo.smallestNominalAppHeight = 1<<30;
         displayInfo.largestNominalAppWidth = 0;
         displayInfo.largestNominalAppHeight = 0;
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, uiMode, unrotDw, unrotDh);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
-        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_0, uiMode, unrotDw,
+                unrotDh);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_90, uiMode, unrotDh,
+                unrotDw);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_180, uiMode, unrotDw,
+                unrotDh);
+        adjustDisplaySizeRanges(displayInfo, displayId, Surface.ROTATION_270, uiMode, unrotDh,
+                unrotDw);
         int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
+                displayId);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
+                displayId);
         outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
         outConfig.screenLayout = sl;
     }
 
     private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
-            DisplayMetrics dm, int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
-        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode);
-        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode);
+            DisplayMetrics dm, int dw, int dh, int displayId) {
+        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
+                displayId);
+        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
+                displayId);
         float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
         int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
         if (curSize == 0 || size < curSize) {
@@ -5542,8 +5532,8 @@
         return curSize;
     }
 
-    private int computeCompatSmallestWidth(boolean rotated, int uiMode, DisplayMetrics dm, int dw, int dh) {
-        // TODO: Multidisplay: for now only use with default display.
+    private int computeCompatSmallestWidth(boolean rotated, int uiMode, DisplayMetrics dm, int dw,
+            int dh, int displayId) {
         mTmpDisplayMetrics.setTo(dm);
         final DisplayMetrics tmpDm = mTmpDisplayMetrics;
         final int unrotDw, unrotDh;
@@ -5554,10 +5544,14 @@
             unrotDw = dw;
             unrotDh = dh;
         }
-        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw);
+        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
+                displayId);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
+                displayId);
         return sw;
     }
 
@@ -5592,8 +5586,9 @@
         }
 
         // Update application display metrics.
-        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode);
-        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode);
+        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode, displayId);
+        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode,
+                displayId);
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         displayInfo.rotation = mRotation;
         displayInfo.logicalWidth = dw;
@@ -5632,15 +5627,15 @@
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
         config.screenWidthDp =
-                (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation, config.uiMode) /
+                (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation, config.uiMode, displayId) /
                         mDisplayMetrics.density);
         config.screenHeightDp =
-                (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation, config.uiMode) /
+                (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation, config.uiMode, displayId) /
                         mDisplayMetrics.density);
         final boolean rotated = (mRotation == Surface.ROTATION_90
                 || mRotation == Surface.ROTATION_270);
 
-        computeSizeRangesAndScreenLayout(displayInfo, rotated, config.uiMode, dw, dh,
+        computeSizeRangesAndScreenLayout(displayInfo, displayId, rotated, config.uiMode, dw, dh,
                 mDisplayMetrics.density, config);
 
         config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
@@ -5651,7 +5646,7 @@
         config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
         config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
         config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode,
-                mDisplayMetrics, dw, dh);
+                mDisplayMetrics, dw, dh, displayId);
         config.densityDpi = displayInfo.logicalDensityDpi;
 
         // Update the configuration based on available input devices, lid switch,
@@ -7300,7 +7295,7 @@
         changes |= FINISH_LAYOUT_REDO_LAYOUT;
         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
                 "Wallpaper layer changed: assigning layers + relayout");
-        dc.moveInputMethodWindowsIfNeeded(true);
+        dc.computeImeTarget(true /* updateImeTarget */);
         mRoot.mWallpaperMayChange = true;
         // Since the window list has been rebuilt, focus might have to be recomputed since the
         // actual order of windows might have changed again.
@@ -7393,10 +7388,25 @@
             mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
             // TODO(multidisplay): Focused windows on default display only.
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
-            final boolean imWindowChanged = displayContent.moveInputMethodWindowsIfNeeded(
-                    mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
-                            && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
+            boolean imWindowChanged = false;
+            if (mInputMethodWindow != null) {
+                final WindowState prevTarget = mInputMethodTarget;
+                final WindowState newTarget =
+                        displayContent.computeImeTarget(true /* updateImeTarget*/);
+
+                imWindowChanged = prevTarget != newTarget;
+
+                if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
+                        && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
+                    final int prevImeAnimLayer = mInputMethodWindow.mWinAnimator.mAnimLayer;
+                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
+                    imWindowChanged |=
+                            prevImeAnimLayer != mInputMethodWindow.mWinAnimator.mAnimLayer;
+                }
+            }
+
             if (imWindowChanged) {
+                mWindowsChanged = true;
                 displayContent.setLayoutNeeded();
                 newFocus = mRoot.computeFocusedWindow();
             }
@@ -7871,7 +7881,6 @@
     private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
         mRoot.dumpTokens(pw, dumpAll);
-        mRoot.mWallpaperController.dumpTokens(pw, "  ", dumpAll);
         if (!mFinishedStarting.isEmpty()) {
             pw.println();
             pw.println("  Finishing start of application tokens:");
@@ -7917,16 +7926,6 @@
             ArrayList<WindowState> windows) {
         mRoot.dumpWindowsNoHeader(pw, dumpAll, windows);
 
-        if (mInputMethodDialogs.size() > 0) {
-            pw.println();
-            pw.println("  Input method dialogs:");
-            for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
-                WindowState w = mInputMethodDialogs.get(i);
-                if (windows == null || windows.contains(w)) {
-                    pw.print("  IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
-                }
-            }
-        }
         if (mPendingRemove.size() > 0) {
             pw.println();
             pw.println("  Remove pending for:");
@@ -8085,7 +8084,7 @@
 
     private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
             boolean dumpAll) {
-        final WindowList windows = new WindowList();
+        final ArrayList<WindowState> windows = new ArrayList();
         if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
             final boolean appsOnly = name.contains("apps");
             final boolean visibleOnly = name.contains("visible");
@@ -8261,7 +8260,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..d959d8c 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;
@@ -74,6 +76,7 @@
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -113,6 +116,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -138,9 +142,6 @@
 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
 
-class WindowList extends ArrayList<WindowState> {
-}
-
 /** A window in the window manager. */
 class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState {
     static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM;
@@ -446,12 +447,6 @@
      */
     boolean mWindowRemovalAllowed;
 
-    /**
-     * Temp for keeping track of windows that have been removed when
-     * rebuilding window list.
-     */
-    boolean mRebuilding;
-
     // Input channel and input window handle used by the input dispatcher.
     final InputWindowHandle mInputWindowHandle;
     InputChannel mInputChannel;
@@ -1355,7 +1350,7 @@
      * being visible.
      */
     boolean isOnScreen() {
-        if (!mHasSurface || mDestroying) {
+        if (!mHasSurface || mDestroying || !mPolicyVisibility) {
             return false;
         }
         final AppWindowToken atoken = mAppToken;
@@ -1719,7 +1714,7 @@
 
         final DisplayContent dc = getDisplayContent();
         if (mService.mInputMethodTarget == this) {
-            dc.moveInputMethodWindowsIfNeeded(false);
+            dc.computeImeTarget(true /* updateImeTarget */);
         }
 
         final int type = mAttrs.type;
@@ -1903,9 +1898,7 @@
     }
 
     int getAnimLayerAdjustment() {
-        final boolean isImeType =
-                mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
-        if (isImeType && mService.mInputMethodTarget != null) {
+        if (mIsImWindow && mService.mInputMethodTarget != null) {
             final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
             if (appToken != null) {
                 return appToken.mAppAnimator.animLayerAdjustment;
@@ -1931,6 +1924,33 @@
         return mLayer + specialAdjustment;
     }
 
+    boolean canBeImeTarget() {
+        final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
+        final int type = mAttrs.type;
+
+        if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
+                && type != TYPE_APPLICATION_STARTING) {
+            return false;
+        }
+
+        if (DEBUG_INPUT_METHOD) {
+            Slog.i(TAG_WM, "isVisibleOrAdding " + this + ": " + isVisibleOrAdding());
+            if (!isVisibleOrAdding()) {
+                Slog.i(TAG_WM, "  mSurfaceController=" + mWinAnimator.mSurfaceController
+                        + " relayoutCalled=" + mRelayoutCalled
+                        + " viewVis=" + mViewVisibility
+                        + " policyVis=" + mPolicyVisibility
+                        + " policyVisAfterAnim=" + mPolicyVisibilityAfterAnim
+                        + " parentHidden=" + isParentWindowHidden()
+                        + " exiting=" + mAnimatingExit + " destroying=" + mDestroying);
+                if (mAppToken != null) {
+                    Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + mAppToken.hiddenRequested);
+                }
+            }
+        }
+        return isVisibleOrAdding();
+    }
+
     void scheduleAnimationIfDimming() {
         final DisplayContent dc = getDisplayContent();
         if (dc == null) {
@@ -2085,7 +2105,7 @@
         return false;
     }
 
-    void removeReplacedWindow() {
+    private void removeReplacedWindow() {
         if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this);
         if (isDimming()) {
             transferDimToReplacement();
@@ -2138,6 +2158,16 @@
         }
     }
 
+    @Override
+    void switchUser() {
+        super.switchUser();
+        if (isHiddenFromUserLocked()) {
+            if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + this
+                    + ", attrs=" + mAttrs.type + ", belonging to " + mOwnerUid);
+            hideLw(false);
+        }
+    }
+
     int getTouchableRegion(Region region, int flags) {
         final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
         if (modal && mAppToken != null) {
@@ -3499,16 +3529,6 @@
         return mIsChildWindow;
     }
 
-    /**
-     * Returns the bottom child window in regards to z-order of this window or null if no children.
-     */
-    WindowState getBottomChild() {
-        // Child windows are z-ordered based on sub-layer using {@link #sWindowSubLayerComparator}
-        // and the child with the lowest z-order will be at the head of the list.
-        WindowState c = mChildren.peekFirst();
-        return c == null ? null : c;
-    }
-
     boolean layoutInParentFrame() {
         return mIsChildWindow
                 && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0;
@@ -3795,59 +3815,20 @@
     }
 
     @Override
-    int rebuildWindowList(int addIndex) {
-        return reAddWindow(addIndex);
-    }
-
-    // TODO: come-up with a better name for this method that represents what it does.
-    // Or, it is probably not going to matter anyways if we are successful in getting rid of
-    // the WindowList concept.
-    int reAddWindow(int index) {
-        final DisplayContent dc = getDisplayContent();
-        // Adding child windows relies on child windows being ordered by mSubLayer using
-        // {@link #sWindowSubLayerComparator}.
-        final int childCount = mChildren.size();
-        boolean winAdded = false;
-        for (int j = 0; j < childCount; j++) {
-            final WindowState child = mChildren.get(j);
-            if (!winAdded && child.mSubLayer >= 0) {
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
-                        "Re-adding child window at " + index + ": " + child);
-                mRebuilding = false;
-                dc.addToWindowList(this, index);
-                index++;
-                winAdded = true;
-            }
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + child);
-            child.mRebuilding = false;
-            dc.addToWindowList(child, index);
-            index++;
-        }
-        if (!winAdded) {
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + this);
-            mRebuilding = false;
-            dc.addToWindowList(this, index);
-            index++;
-        }
-        return index;
-    }
-
-    @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 +3837,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 +3847,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 +3873,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 +3883,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..de80837 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -239,7 +239,8 @@
         mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
 
         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
-        displayContent.rebuildAppWindowList();
+        // TODO: Don't believe this is really needed...
+        //mService.mWindowsChanged = true;
 
         mService.mRoot.mWallpaperMayChange = false;
 
@@ -266,21 +267,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 +283,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 +296,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 +314,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.
@@ -368,12 +357,8 @@
         displayContent.setLayoutNeeded();
 
         // TODO(multidisplay): IMEs are only supported on the default display.
-        // TODO: Probably not needed once the window list always has the right z-ordering
-        // when the window hierarchy is updated.
         final DisplayContent dc = mService.getDefaultDisplayContentLocked();
-        if (!dc.moveInputMethodWindowsIfNeeded(true)) {
-            dc.assignWindowLayers(false /*setLayoutNeeded*/);
-        }
+        dc.computeImeTarget(true /* updateImeTarget */);
         mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                 true /*updateInputWindows*/);
         mService.mFocusMayChange = false;
@@ -578,8 +563,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 +574,6 @@
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "New wallpaper target=" + wallpaperTarget
                         + ", oldWallpaper=" + oldWallpaper
-                        + ", lower target=" + lowerWallpaperTarget
-                        + ", upper target=" + upperWallpaperTarget
                         + ", openingApps=" + openingApps
                         + ", closingApps=" + closingApps);
         mService.mAnimateWallpaperWithTarget = false;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 402bcfb..40bd3fb 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -168,28 +168,6 @@
         return highestAnimLayer;
     }
 
-    WindowState getTopWindow() {
-        if (mChildren.isEmpty()) {
-            return null;
-        }
-        return (WindowState) mChildren.get(mChildren.size() - 1).getTop();
-    }
-
-    /**
-     * Recursive search through a WindowList and all of its windows' children.
-     * @param target The window to search for.
-     * @return The index of win in windows or of the window that is an ancestor of win.
-     */
-    int getWindowIndex(WindowState target) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState w = mChildren.get(i);
-            if (w == target || w.hasChild(target)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
     /**
      * Returns true if the new window is considered greater than the existing window in terms of
      * z-order.
@@ -204,51 +182,16 @@
         if (DEBUG_FOCUS) Slog.d(TAG_WM,
                 "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
 
-        if (!win.isChildWindow()) {
-            if (asAppWindowToken() != null) {
-                mDisplayContent.addAppWindowToWindowList(win);
-            } else {
-                mDisplayContent.addNonAppWindowToWindowList(win);
-            }
-
-            if (!mChildren.contains(win)) {
-                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
-                addChild(win, mWindowComparator);
-            }
-        } else {
-            mDisplayContent.addChildWindowToWindowList(win);
-        }
-    }
-
-    void addImeWindow(WindowState win) {
-        int pos = mDisplayContent.findDesiredInputMethodWindowIndex(true);
-
-        if (pos < 0) {
-            addWindow(win);
-            mDisplayContent.moveInputMethodDialogs(pos);
+        if (win.isChildWindow()) {
+            // Child windows are added to their parent windows.
             return;
         }
-
-        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
-                "Adding input method window " + win + " at " + pos);
-        mDisplayContent.addToWindowList(win, pos);
         if (!mChildren.contains(win)) {
-            addChild(win, null);
+            if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
+            addChild(win, mWindowComparator);
+            mService.mWindowsChanged = true;
+            // TODO: Should we also be setting layout needed here and other places?
         }
-        mDisplayContent.moveInputMethodDialogs(pos + 1);
-    }
-
-    /** Return the first window in the token window list that isn't a starting window or null. */
-    WindowState getFirstNonStartingWindow() {
-        final int count = mChildren.size();
-        // We only care about parent windows so no need to loop through child windows.
-        for (int i = 0; i < count; i++) {
-            final WindowState w = mChildren.get(i);
-            if (w.mAttrs.type != TYPE_APPLICATION_STARTING) {
-                return w;
-            }
-        }
-        return null;
     }
 
     /** Returns true if the token windows list is empty. */
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index c03a460..4d43e8e 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -67,7 +67,8 @@
     libEGL \
     libGLESv2 \
     libnetutils \
-    libhidl \
+    libhidlbase \
+    libhidltransport \
     libhwbinder \
     libutils \
     android.hardware.audio.common@2.0 \
diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp
index e6072bb..a3ab8f6 100644
--- a/services/core/jni/com_android_server_lights_LightsService.cpp
+++ b/services/core/jni/com_android_server_lights_LightsService.cpp
@@ -34,6 +34,9 @@
 using Flash      = ::android::hardware::light::V2_0::Flash;
 using Type       = ::android::hardware::light::V2_0::Type;
 using LightState = ::android::hardware::light::V2_0::LightState;
+using Status     = ::android::hardware::light::V2_0::Status;
+template<typename T>
+using Return     = ::android::hardware::Return<T>;
 
 static sp<ILight> gLight;
 
@@ -108,9 +111,33 @@
 
     state.brightnessMode = brightness;
 
+    Status status;
+
     {
         ALOGD_IF_SLOW(50, "Excessive delay setting light");
-        gLight->setLight(type, state);
+        Return<Status> ret = gLight->setLight(type, state);
+
+        // TODO(b/31348667): this is transport specific status
+        if (!ret.getStatus().isOk()) {
+            ALOGE("Failed to issue set light command.");
+            return;
+        }
+
+        status = static_cast<Status>(ret); // hal status
+    }
+
+    switch (status) {
+        case Status::SUCCESS:
+            break;
+        case Status::LIGHT_NOT_SUPPORTED:
+            ALOGE("Light requested not availale on this device.");
+            break;
+        case Status::BRIGHTNESS_NOT_SUPPORTED:
+            ALOGE("Brightness parameter not supported on this device.");
+            break;
+        case Status::UNKNOWN:
+        default:
+            ALOGE("Unknown error setting light.");
     }
 }
 
diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
index 640fd0e..2f20ecd 100644
--- a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
+++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp
@@ -30,7 +30,7 @@
 static jclass appFuseClass;
 static jmethodID appFuseOnMount;
 
-class Callback : public FuseBridgeLoop::Callback {
+class Callback : public fuse::FuseBridgeLoopCallback {
     JNIEnv* mEnv;
     jobject mSelf;
 
@@ -47,9 +47,8 @@
 
 jboolean com_android_server_storage_AppFuseBridge_start_loop(
         JNIEnv* env, jobject self, jint devJavaFd, jint proxyJavaFd) {
-    FuseBridgeLoop loop;
     Callback callback(env, self);
-    return loop.Start(devJavaFd, proxyJavaFd, &callback);
+    return fuse::StartFuseBridgeLoop(devJavaFd, proxyJavaFd, &callback);
 }
 
 const JNINativeMethod methods[] = {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7e68447..c497cb1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -38,7 +38,6 @@
 import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -206,6 +205,12 @@
 
     private static final String TAG_AFFILIATION_ID = "affiliation-id";
 
+    private static final String TAG_LAST_SECURITY_LOG_RETRIEVAL = "last-security-log-retrieval";
+
+    private static final String TAG_LAST_BUG_REPORT_REQUEST = "last-bug-report-request";
+
+    private static final String TAG_LAST_NETWORK_LOG_RETRIEVAL = "last-network-log-retrieval";
+
     private static final String TAG_ADMIN_BROADCAST_PENDING = "admin-broadcast-pending";
 
     private static final String ATTR_VALUE = "value";
@@ -467,6 +472,12 @@
 
         Set<String> mAffiliationIds = new ArraySet<>();
 
+        long mLastSecurityLogRetrievalTime = -1;
+
+        long mLastBugReportRequestTime = -1;
+
+        long mLastNetworkLogsRetrievalTime = -1;
+
         // Used for initialization of users created by createAndManageUsers.
         boolean mAdminBroadcastPending = false;
         PersistableBundle mInitBundle = null;
@@ -1460,7 +1471,7 @@
         }
 
         IActivityManager getIActivityManager() {
-            return ActivityManagerNative.getDefault();
+            return ActivityManager.getService();
         }
 
         IPackageManager getIPackageManager() {
@@ -2360,6 +2371,27 @@
                 out.endTag(null, TAG_AFFILIATION_ID);
             }
 
+            if (policy.mLastSecurityLogRetrievalTime >= 0) {
+                out.startTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
+                out.attribute(null, ATTR_VALUE,
+                        Long.toString(policy.mLastSecurityLogRetrievalTime));
+                out.endTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
+            }
+
+            if (policy.mLastBugReportRequestTime >= 0) {
+                out.startTag(null, TAG_LAST_BUG_REPORT_REQUEST);
+                out.attribute(null, ATTR_VALUE,
+                        Long.toString(policy.mLastBugReportRequestTime));
+                out.endTag(null, TAG_LAST_BUG_REPORT_REQUEST);
+            }
+
+            if (policy.mLastNetworkLogsRetrievalTime >= 0) {
+                out.startTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
+                out.attribute(null, ATTR_VALUE,
+                        Long.toString(policy.mLastNetworkLogsRetrievalTime));
+                out.endTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
+            }
+
             if (policy.mAdminBroadcastPending) {
                 out.startTag(null, TAG_ADMIN_BROADCAST_PENDING);
                 out.attribute(null, ATTR_VALUE,
@@ -2516,6 +2548,15 @@
                     policy.doNotAskCredentialsOnBoot = true;
                 } else if (TAG_AFFILIATION_ID.equals(tag)) {
                     policy.mAffiliationIds.add(parser.getAttributeValue(null, "id"));
+                } else if (TAG_LAST_SECURITY_LOG_RETRIEVAL.equals(tag)) {
+                    policy.mLastSecurityLogRetrievalTime = Long.parseLong(
+                            parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_LAST_BUG_REPORT_REQUEST.equals(tag)) {
+                    policy.mLastBugReportRequestTime = Long.parseLong(
+                            parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_LAST_NETWORK_LOG_RETRIEVAL.equals(tag)) {
+                    policy.mLastNetworkLogsRetrievalTime = Long.parseLong(
+                            parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
                     String pending = parser.getAttributeValue(null, ATTR_VALUE);
                     policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending);
@@ -5522,9 +5563,18 @@
             return false;
         }
 
+        final long currentTime = System.currentTimeMillis();
+        synchronized (this) {
+            DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
+            if (currentTime > policyData.mLastBugReportRequestTime) {
+                policyData.mLastBugReportRequestTime = currentTime;
+                saveSettingsLocked(UserHandle.USER_SYSTEM);
+            }
+        }
+
         final long callingIdentity = mInjector.binderClearCallingIdentity();
         try {
-            ActivityManagerNative.getDefault().requestBugReport(
+            mInjector.getIActivityManager().requestBugReport(
                     ActivityManager.BUGREPORT_OPTION_REMOTE);
 
             mRemoteBugreportServiceIsActive.set(true);
@@ -6042,6 +6092,7 @@
     }
 
     private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) {
+        disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
         if (admin != null) {
             admin.disableCamera = false;
             admin.userRestrictions = null;
@@ -6053,7 +6104,6 @@
         mOwners.clearDeviceOwner();
         mOwners.writeDeviceOwner();
         updateDeviceOwnerLocked();
-        disableDeviceOwnerManagedSingleUserFeaturesIfNeeded();
         try {
             if (mInjector.getIBackupManager() != null) {
                 // Reactivate backup service.
@@ -6531,6 +6581,12 @@
         }
     }
 
+    private void enforceSystemUid() {
+        if (!isCallerWithSystemUid()) {
+            throw new SecurityException("Only the system can call this method.");
+        }
+    }
+
     private void ensureCallerPackage(@Nullable String packageName) {
         if (packageName == null) {
             Preconditions.checkState(isCallerWithSystemUid(),
@@ -8700,9 +8756,11 @@
                 // Managed user cannot have a managed profile.
                 return false;
             }
+            boolean canRemoveProfile
+                    = !mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
             final long ident = mInjector.binderClearCallingIdentity();
             try {
-                if (!mUserManager.canAddMoreManagedProfiles(callingUserId, true)) {
+                if (!mUserManager.canAddMoreManagedProfiles(callingUserId, canRemoveProfile)) {
                     return false;
                 }
             } finally {
@@ -9170,6 +9228,15 @@
         }
     }
 
+    private synchronized void recordSecurityLogRetrievalTime() {
+        final long currentTime = System.currentTimeMillis();
+        DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
+        if (currentTime > policyData.mLastSecurityLogRetrievalTime) {
+            policyData.mLastSecurityLogRetrievalTime = currentTime;
+            saveSettingsLocked(UserHandle.USER_SYSTEM);
+        }
+    }
+
     @Override
     public ParceledListSlice<SecurityEvent> retrievePreRebootSecurityLogs(ComponentName admin) {
         Preconditions.checkNotNull(admin);
@@ -9179,6 +9246,8 @@
             return null;
         }
 
+        recordSecurityLogRetrievalTime();
+
         ArrayList<SecurityEvent> output = new ArrayList<SecurityEvent>();
         try {
             SecurityLog.readPreviousEvents(output);
@@ -9194,6 +9263,8 @@
         Preconditions.checkNotNull(admin);
         ensureDeviceOwnerManagingSingleUser(admin);
 
+        recordSecurityLogRetrievalTime();
+
         List<SecurityEvent> logs = mSecurityLogMonitor.retrieveLogs();
         return logs != null ? new ParceledListSlice<SecurityEvent>(logs) : null;
     }
@@ -9669,9 +9740,21 @@
         if (mNetworkLogger == null) {
             return null;
         }
-        return isNetworkLoggingEnabledInternalLocked()
-                ? mNetworkLogger.retrieveLogs(batchToken)
-                : null;
+
+        if (!isNetworkLoggingEnabledInternalLocked()) {
+            return null;
+        }
+
+        final long currentTime = System.currentTimeMillis();
+        synchronized (this) {
+            DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
+            if (currentTime > policyData.mLastNetworkLogsRetrievalTime) {
+                policyData.mLastNetworkLogsRetrievalTime = currentTime;
+                saveSettingsLocked(UserHandle.USER_SYSTEM);
+            }
+        }
+
+        return mNetworkLogger.retrieveLogs(batchToken);
     }
 
     /**
@@ -9715,4 +9798,22 @@
         rawIntent.setComponent(info.serviceInfo.getComponentName());
         return rawIntent;
     }
+
+    @Override
+    public long getLastSecurityLogRetrievalTime() {
+        enforceSystemUid();
+        return getUserData(UserHandle.USER_SYSTEM).mLastSecurityLogRetrievalTime;
+     }
+
+    @Override
+    public long getLastBugReportRequestTime() {
+        enforceSystemUid();
+        return getUserData(UserHandle.USER_SYSTEM).mLastBugReportRequestTime;
+     }
+
+    @Override
+    public long getLastNetworkLogRetrievalTime() {
+        enforceSystemUid();
+        return getUserData(UserHandle.USER_SYSTEM).mLastNetworkLogsRetrievalTime;
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3db24fa..ba23f21 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -42,7 +42,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.IMountService;
+import android.os.storage.IStorageManager;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -52,6 +52,7 @@
 
 import com.android.internal.R;
 import com.android.internal.app.NightDisplayController;
+import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 import com.android.internal.os.ZygoteInit;
@@ -167,8 +168,8 @@
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
             "com.android.server.LockSettingsService$Lifecycle";
-    private static final String MOUNT_SERVICE_CLASS =
-            "com.android.server.MountService$Lifecycle";
+    private static final String STORAGE_MANAGER_SERVICE_CLASS =
+            "com.android.server.StorageManagerService$Lifecycle";
     private static final String SEARCH_MANAGER_SERVICE_CLASS =
             "com.android.server.search.SearchManagerService$Lifecycle";
     private static final String THERMAL_OBSERVER_CLASS =
@@ -275,7 +276,9 @@
 
             // Here we go!
             Slog.i(TAG, "Entered the Android system server!");
-            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
+            int uptimeMillis = (int) SystemClock.uptimeMillis();
+            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
+            MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
 
             // In case the runtime switched since last boot (such as when
             // the old runtime was removed in an OTA), set the system
@@ -364,6 +367,7 @@
         if (StrictMode.conditionallyEnableDebugLogging()) {
             Slog.i(TAG, "Enabled StrictMode for system server main thread.");
         }
+        MetricsLogger.histogram(null, "boot_system_server_ready", (int) SystemClock.uptimeMillis());
 
         // Loop forever.
         Looper.loop();
@@ -492,13 +496,16 @@
         }
 
         // Start the package manager.
+        MetricsLogger.histogram(null, "boot_package_manager_init_start",
+                (int) SystemClock.uptimeMillis());
         traceBeginAndSlog("StartPackageManagerService");
         mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
         mFirstBoot = mPackageManagerService.isFirstBoot();
         mPackageManager = mSystemContext.getPackageManager();
         traceEnd();
-
+        MetricsLogger.histogram(null, "boot_package_manager_init_ready",
+                (int) SystemClock.uptimeMillis());
         // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
         // A/B artifacts after boot, before anything else might touch/need them.
         // Note: this isn't needed during decryption (we don't have /data anyways).
@@ -572,7 +579,7 @@
     private void startOtherServices() {
         final Context context = mSystemContext;
         VibratorService vibrator = null;
-        IMountService mountService = null;
+        IStorageManager storageManager = null;
         NetworkManagementService networkManagement = null;
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
@@ -784,17 +791,17 @@
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
             if (!disableStorage &&
                 !"0".equals(SystemProperties.get("system_init.startmountservice"))) {
-                traceBeginAndSlog("StartMountService");
+                traceBeginAndSlog("StartStorageManagerService");
                 try {
                     /*
-                     * NotificationManagerService is dependant on MountService,
-                     * (for media / usb notifications) so we must start MountService first.
+                     * NotificationManagerService is dependant on StorageManagerService,
+                     * (for media / usb notifications) so we must start StorageManagerService first.
                      */
-                    mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
-                    mountService = IMountService.Stub.asInterface(
+                    mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
+                    storageManager = IStorageManager.Stub.asInterface(
                             ServiceManager.getService("mount"));
                 } catch (Throwable e) {
-                    reportWtf("starting Mount Service", e);
+                    reportWtf("starting StorageManager Service", e);
                 }
                 traceEnd();
             }
@@ -993,14 +1000,14 @@
             }
 
             /*
-             * MountService has a few dependencies: Notification Manager and
-             * AppWidget Provider. Make sure MountService is completely started
+             * StorageManagerService has a few dependencies: Notification Manager and
+             * AppWidget Provider. Make sure StorageManagerService is completely started
              * first before continuing.
              */
-            if (mountService != null && !mOnlyCore) {
+            if (storageManager != null && !mOnlyCore) {
                 traceBeginAndSlog("WaitForAsecScan");
                 try {
-                    mountService.waitForAsecScan();
+                    storageManager.waitForAsecScan();
                 } catch (RemoteException ignored) {
                 }
                 traceEnd();
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 6558b6e..d7666d9 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -22,7 +22,6 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -915,7 +914,7 @@
 
         private int resolveCallingUserEnforcingPermissions(int userId) {
             try {
-                return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+                return ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(),
                         Binder.getCallingUid(), userId, true, true, "", null);
             } catch (RemoteException re) {
                 // Shouldn't happen, local.
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index 6b919df..f4c9c86 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -43,6 +43,7 @@
 import android.util.Slog;
 import android.util.TimedRemoteCaller;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.TransferPipe;
 
 import libcore.io.IoUtils;
@@ -112,6 +113,10 @@
 
     private boolean mCanUnbind;
 
+    /** Whether a thread is currently trying to {@link #bindLocked() bind to the print service} */
+    @GuardedBy("mLock")
+    private boolean mIsBinding;
+
     public static interface PrintSpoolerCallbacks {
         public void onPrintJobQueued(PrintJobInfo printJob);
         public void onAllPrintJobsForServiceHandled(ComponentName printService);
@@ -164,10 +169,8 @@
         try {
             return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(),
                     componentName, state, appId);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error getting print jobs.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error getting print jobs.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error getting print jobs.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()");
@@ -188,10 +191,8 @@
         }
         try {
             getRemoteInstanceLazy().createPrintJob(printJob);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error creating print job.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error creating print job.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error creating print job.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()");
@@ -211,10 +212,8 @@
         }
         try {
             getRemoteInstanceLazy().writePrintJobData(fd, printJobId);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error writing print job data.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error writing print job data.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error writing print job data.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()");
@@ -238,10 +237,8 @@
         try {
             return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(),
                     printJobId, appId);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error getting print job info.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error getting print job info.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error getting print job info.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()");
@@ -263,10 +260,8 @@
         try {
             return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(),
                     printJobId, state, error);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error setting print job state.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error setting print job state.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error setting print job state.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()");
@@ -294,7 +289,7 @@
         }
         try {
             getRemoteInstanceLazy().setProgress(printJobId, progress);
-        } catch (RemoteException|TimeoutException re) {
+        } catch (RemoteException | TimeoutException | InterruptedException re) {
             Slog.e(LOG_TAG, "Error setting progress.", re);
         } finally {
             if (DEBUG) {
@@ -321,8 +316,8 @@
         }
         try {
             getRemoteInstanceLazy().setStatus(printJobId, status);
-        } catch (RemoteException|TimeoutException re) {
-            Slog.e(LOG_TAG, "Error setting status.", re);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error setting status.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()");
@@ -350,8 +345,8 @@
         }
         try {
             getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName);
-        } catch (RemoteException|TimeoutException re) {
-            Slog.e(LOG_TAG, "Error setting status.", re);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error setting status.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()");
@@ -380,7 +375,7 @@
         try {
             mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(),
                     printerId, icon);
-        } catch (RemoteException|TimeoutException re) {
+        } catch (RemoteException | TimeoutException | InterruptedException re) {
             Slog.e(LOG_TAG, "Error loading new custom printer icon.", re);
         } finally {
             if (DEBUG) {
@@ -412,8 +407,8 @@
         try {
             return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(),
                     printerId);
-        } catch (RemoteException|TimeoutException re) {
-            Slog.e(LOG_TAG, "Error getting custom printer icon.", re);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error getting custom printer icon.", e);
             return null;
         } finally {
             if (DEBUG) {
@@ -438,8 +433,8 @@
         }
         try {
             mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy());
-        } catch (RemoteException|TimeoutException re) {
-            Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", re);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG,
@@ -462,10 +457,8 @@
         try {
             return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(),
                     printJobId, tag);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error setting print job tag.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error setting print job tag.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error setting print job tag.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()");
@@ -487,10 +480,8 @@
         try {
             getRemoteInstanceLazy().setPrintJobCancelling(printJobId,
                     cancelling);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error setting print job cancelling.", re);
-        } catch (TimeoutException te) {
-            Slog.e(LOG_TAG, "Error setting print job cancelling.", te);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error setting print job cancelling.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
@@ -516,8 +507,8 @@
         }
         try {
             getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep);
-        } catch (RemoteException|TimeoutException re) {
-            Slog.e(LOG_TAG, "Error pruning approved print services.", re);
+        } catch (RemoteException | TimeoutException | InterruptedException e) {
+            Slog.e(LOG_TAG, "Error pruning approved print services.", e);
         } finally {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier()
@@ -538,9 +529,7 @@
         }
         try {
             getRemoteInstanceLazy().removeObsoletePrintJobs();
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re);
-        } catch (TimeoutException te) {
+        } catch (RemoteException | TimeoutException | InterruptedException te) {
             Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te);
         } finally {
             if (DEBUG) {
@@ -578,7 +567,7 @@
             try {
                 TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
                         new String[] { prefix });
-            } catch (IOException | TimeoutException | RemoteException e) {
+            } catch (IOException | TimeoutException | RemoteException | InterruptedException e) {
                 pw.println("Failed to dump remote instance: " + e);
             }
         }
@@ -595,7 +584,7 @@
         mCallbacks.onPrintJobStateChanged(printJob);
     }
 
-    private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException {
+    private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException, InterruptedException {
         synchronized (mLock) {
             if (mRemoteInstance != null) {
                 return mRemoteInstance;
@@ -605,43 +594,50 @@
         }
     }
 
-    private void bindLocked() throws TimeoutException {
+    private void bindLocked() throws TimeoutException, InterruptedException {
+        while (mIsBinding) {
+            mLock.wait();
+        }
+
         if (mRemoteInstance != null) {
             return;
         }
+
+        mIsBinding = true;
+
         if (DEBUG) {
             Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " +
                     (mIsLowPriority ? "low priority" : ""));
         }
 
-        int flags;
-        if (mIsLowPriority) {
-            flags = Context.BIND_AUTO_CREATE;
-        } else {
-            flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
-        }
-
-        mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle);
-
-        final long startMillis = SystemClock.uptimeMillis();
-        while (true) {
-            if (mRemoteInstance != null) {
-                break;
+        try {
+            int flags;
+            if (mIsLowPriority) {
+                flags = Context.BIND_AUTO_CREATE;
+            } else {
+                flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
             }
-            final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
-            final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis;
-            if (remainingMillis <= 0) {
-                throw new TimeoutException("Cannot get spooler!");
-            }
-            try {
+
+            mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle);
+
+            final long startMillis = SystemClock.uptimeMillis();
+            while (true) {
+                if (mRemoteInstance != null) {
+                    break;
+                }
+                final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+                final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis;
+                if (remainingMillis <= 0) {
+                    throw new TimeoutException("Cannot get spooler!");
+                }
                 mLock.wait(remainingMillis);
-            } catch (InterruptedException ie) {
-                /* ignore */
             }
-        }
 
-        mCanUnbind = true;
-        mLock.notifyAll();
+            mCanUnbind = true;
+        } finally {
+            mIsBinding = false;
+            mLock.notifyAll();
+        }
     }
 
     private void unbindLocked() {
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/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index d20e351..39c5238 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -15,6 +15,10 @@
  */
 package com.android.server.notification;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
 import com.android.server.lights.Light;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
@@ -37,7 +41,6 @@
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
-import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.StatusBarNotification;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -75,7 +78,6 @@
     private String mTag = null;
     private int mUid = 1000;
     private int mPid = 2000;
-    private int mScore = 10;
     private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
 
     private static final long[] CUSTOM_VIBRATION = new long[] {
@@ -86,6 +88,7 @@
     private static final int CUSTOM_LIGHT_COLOR = Color.BLACK;
     private static final int CUSTOM_LIGHT_ON = 10000;
     private static final int CUSTOM_LIGHT_OFF = 10000;
+    private static final long[] FALLBACK_VIBRATION = new long[] {100, 100, 100};
 
     @Before
     public void setUp() {
@@ -104,7 +107,7 @@
         mService.setStatusBarManager(mStatusBar);
         mService.setLights(mLight);
         mService.setScreenOn(false);
-        mService.setSystemNotificationSound("beep!");
+        mService.setFallbackVibrationPattern(FALLBACK_VIBRATION);
     }
 
     //
@@ -161,23 +164,16 @@
                 false /* noisy */, true /* buzzy*/, false /* lights */);
     }
 
+    private NotificationRecord getBuzzyBeepyNotification() {
+        return getNotificationRecord(mId, false /* insistent */, false /* once */,
+                true /* noisy */, true /* buzzy*/, false /* lights */);
+    }
+
     private NotificationRecord getLightsNotification() {
         return getNotificationRecord(mId, false /* insistent */, true /* once */,
                 false /* noisy */, true /* buzzy*/, true /* lights */);
     }
 
-    private NotificationRecord getCustomBuzzyOnceNotification() {
-        return getNotificationRecord(mId, false /* insistent */, true /* once */,
-                false /* noisy */, true /* buzzy*/, false /* lights */,
-                false /* defaultVibration */, true /* defaultSound */, true /* defaultLights */);
-    }
-
-    private NotificationRecord getCustomBeepyNotification() {
-        return getNotificationRecord(mId, false /* insistent */, false /* once */,
-                true /* noisy */, false /* buzzy*/, false /* lights */,
-                true /* defaultVibration */, false /* defaultSound */, true /* defaultLights */);
-    }
-
     private NotificationRecord getCustomLightsNotification() {
         return getNotificationRecord(mId, false /* insistent */, true /* once */,
                 false /* noisy */, true /* buzzy*/, true /* lights */,
@@ -192,6 +188,8 @@
     private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
             boolean noisy, boolean buzzy, boolean lights, boolean defaultVibration,
             boolean defaultSound, boolean defaultLights) {
+        NotificationChannel channel =
+                new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_HIGH);
         final Builder builder = new Builder(getContext())
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -202,8 +200,10 @@
         if (noisy) {
             if (defaultSound) {
                 defaults |= Notification.DEFAULT_SOUND;
+                channel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);
             } else {
                 builder.setSound(CUSTOM_SOUND);
+                channel.setSound(CUSTOM_SOUND);
             }
         }
         if (buzzy) {
@@ -212,6 +212,7 @@
             } else {
                 builder.setVibrate(CUSTOM_VIBRATION);
             }
+            channel.setVibration(true);
         }
         if (lights) {
             if (defaultLights) {
@@ -219,6 +220,7 @@
             } else {
                 builder.setLights(CUSTOM_LIGHT_COLOR, CUSTOM_LIGHT_ON, CUSTOM_LIGHT_OFF);
             }
+            channel.setLights(true);
         }
         builder.setDefaults(defaults);
 
@@ -226,8 +228,7 @@
         if (insistent) {
             n.flags |= Notification.FLAG_INSISTENT;
         }
-        NotificationChannel channel =
-                new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_HIGH);
+
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, channel, id, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
         NotificationRecord r = new NotificationRecord(getContext(), sbn);
@@ -282,11 +283,6 @@
                 eq(0), (AudioAttributes) anyObject());
     }
 
-    private void verifyCustomVibrate() {
-        verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(CUSTOM_VIBRATION), eq(-1),
-                (AudioAttributes) anyObject());
-    }
-
     private void verifyStopVibrate() {
         verify(mVibrator, times(1)).cancel();
     }
@@ -333,30 +329,6 @@
     }
 
     @Test
-    public void testBeepFromChannel() throws Exception {
-        NotificationRecord r = getQuietNotification();
-        r.getChannel().setRingtone(Settings.System.DEFAULT_NOTIFICATION_URI);
-        r.setImportance(NotificationManager.IMPORTANCE_DEFAULT, "for testing");
-
-        mService.buzzBeepBlinkLocked(r);
-
-        verifyBeepLooped();
-        verifyNeverVibrate();
-    }
-
-    @Test
-    public void testVibrateFromChannel() throws Exception {
-        NotificationRecord r = getQuietNotification();
-        r.getChannel().setVibration(true);
-        r.setImportance(NotificationManager.IMPORTANCE_DEFAULT, "for testing");
-
-        mService.buzzBeepBlinkLocked(r);
-
-        verifyNeverBeep();
-        verifyVibrate();
-    }
-
-    @Test
     public void testLightsFromChannel() throws Exception {
         NotificationRecord r = getQuietNotification();
         r.setImportance(NotificationManager.IMPORTANCE_DEFAULT, "for testing");
@@ -377,26 +349,6 @@
     }
 
     @Test
-    public void testChannelNoOverwriteCustomVibration() throws Exception {
-        NotificationRecord r = getCustomBuzzyOnceNotification();
-        r.getChannel().setVibration(true);
-
-        mService.buzzBeepBlinkLocked(r);
-
-        verifyCustomVibrate();
-    }
-
-    @Test
-    public void testChannelNoOverwriteCustomBeep() throws Exception {
-        NotificationRecord r = getCustomBeepyNotification();
-        r.getChannel().setRingtone(Settings.System.DEFAULT_RINGTONE_URI);
-
-        mService.buzzBeepBlinkLocked(r);
-
-        verifyCustomBeep();
-    }
-
-    @Test
     public void testChannelNoOverwriteCustomLights() throws Exception {
         NotificationRecord r = getCustomLightsNotification();
         r.getChannel().setLights(true);
@@ -542,22 +494,39 @@
     }
 
     @Test
-    public void testDemoteSoundToVibrate() throws Exception {
-        NotificationRecord r = getBeepyNotification();
+    public void testNoDemoteSoundToVibrateIfVibrateGiven() throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+        assertTrue(r.getSound() != null);
 
         // the phone is quiet
-        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
 
         mService.buzzBeepBlinkLocked(r);
 
-        verifyNeverBeep();
-        verifyVibrate();
+       verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(r.getVibration()),
+                    eq(-1), (AudioAttributes) anyObject());
     }
 
     @Test
-    public void testDemoteInsistenteSoundToVibrate() throws Exception {
+    public void testDemoteSoundToVibrate() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+        assertTrue(r.getSound() != null);
+        assertNull(r.getVibration());
+
+        // the phone is quiet
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION),
+                eq(-1), (AudioAttributes) anyObject());
+    }
+
+    @Test
+    public void testDemoteInsistentSoundToVibrate() throws Exception {
         NotificationRecord r = getInsistentBeepyNotification();
+        assertTrue(r.getSound() != null);
+        assertNull(r.getVibration());
 
         // the phone is quiet
         when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
@@ -677,6 +646,7 @@
 
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
+        verifyVibrate();
 
         // quiet update should stop making noise
         mService.buzzBeepBlinkLocked(s);
@@ -684,14 +654,14 @@
     }
 
     @Test
-    public void testQuietOnceUpdateCancelsvibrate() throws Exception {
+    public void testQuietOnceUpdateCancelVibrate() throws Exception {
         NotificationRecord r = getBuzzyNotification();
         NotificationRecord s = getQuietOnceNotification();
         s.isUpdate = true;
 
         // set up internal state
         mService.buzzBeepBlinkLocked(r);
-        Mockito.reset(mVibrator);
+        verifyVibrate();
 
         // stop making noise - this is a weird corner case, but quiet should override once
         mService.buzzBeepBlinkLocked(s);
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
new file mode 100644
index 0000000..b8f3832
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -0,0 +1,287 @@
+/*
+ * 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.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
+import android.net.Uri;
+import android.os.Build;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Objects;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationRecordTest {
+
+    private final Context mMockContext = Mockito.mock(Context.class);
+    @Mock PackageManager mPm;
+
+    private final String pkg = "com.android.server.notification";
+    private final int uid = 0;
+    private final String pkg2 = "pkg2";
+    private final int uid2 = 1111111;
+    private final int id1 = 1;
+    private final int id2 = 2;
+    private final String tag1 = "tag1";
+    private final String tag2 = "tag2";
+    private final String channelId = "channel";
+    NotificationChannel channel =
+            new NotificationChannel(channelId, "test", NotificationManager.IMPORTANCE_DEFAULT);
+    NotificationChannel defaultChannel =
+            new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
+                    NotificationManager.IMPORTANCE_UNSPECIFIED);
+    private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+    final ApplicationInfo legacy = new ApplicationInfo();
+    final ApplicationInfo upgrade = new ApplicationInfo();
+
+
+    private static final long[] CUSTOM_VIBRATION = new long[] {
+            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400,
+            300, 400, 300, 400, 300, 400, 300, 400, 300, 400, 300, 400 };
+    private static final Uri CUSTOM_SOUND = Settings.System.DEFAULT_ALARM_ALERT_URI;
+    private static final AudioAttributes CUSTOM_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+            .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
+            .build();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mMockContext.getResources()).thenReturn(
+                InstrumentationRegistry.getContext().getResources());
+        when(mMockContext.getPackageManager()).thenReturn(mPm);
+
+        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
+        try {
+            when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy);
+            when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade);
+        } catch (PackageManager.NameNotFoundException e) {}
+    }
+
+    private StatusBarNotification getNotification(boolean preO, boolean noisy, boolean defaultSound,
+            boolean buzzy, boolean defaultVibration) {
+        when(mMockContext.getApplicationInfo()).thenReturn(preO ? legacy : upgrade);
+        final Builder builder = new Builder(mMockContext)
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setPriority(Notification.PRIORITY_HIGH);
+
+        int defaults = 0;
+        if (noisy) {
+            if (defaultSound) {
+                defaults |= Notification.DEFAULT_SOUND;
+            } else {
+                builder.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
+            }
+        }
+        if (buzzy) {
+            if (defaultVibration) {
+                defaults |= Notification.DEFAULT_VIBRATE;
+            } else {
+                builder.setVibrate(CUSTOM_VIBRATION);
+            }
+        }
+        builder.setDefaults(defaults);
+        if (!preO) {
+            builder.setChannel(channelId);
+        }
+
+
+        Notification n = builder.build();
+        if (preO) {
+            return new StatusBarNotification(pkg, pkg, defaultChannel, id1, tag1, uid, uid, n,
+                    mUser, null, uid);
+        } else {
+            return new StatusBarNotification(pkg2, pkg2, channel, id2, tag2, uid2, uid2, n,
+                    mUser, null, uid2);
+        }
+    }
+
+    //
+    // Tests
+    //
+
+    @Test
+    public void testSound_default_preUpgradeUsesNotification() throws Exception {
+        defaultChannel.setSound(null);
+        // pre upgrade, default sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, record.getSound());
+    }
+
+    @Test
+    public void testSound_custom_preUpgradeUsesNotification() throws Exception {
+        defaultChannel.setSound(null);
+        // pre upgrade, custom sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_SOUND, record.getSound());
+    }
+
+    @Test
+    public void testSound_default_userLocked_preUpgrade() throws Exception {
+        defaultChannel.setSound(CUSTOM_SOUND);
+        defaultChannel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
+        // pre upgrade, default sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_SOUND, record.getSound());
+    }
+
+    @Test
+    public void testSound_default_upgradeUsesChannel() throws Exception {
+        channel.setSound(CUSTOM_SOUND);
+        // post upgrade, default sound.
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_SOUND, record.getSound());
+    }
+
+    @Test
+    public void testVibration_default_preUpgradeUsesNotification() throws Exception {
+        defaultChannel.setVibration(false);
+        // pre upgrade, default vibration.
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
+                false /* defaultSound */, true /* buzzy */, true /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertNotNull(record.getVibration());
+    }
+
+    @Test
+    public void testVibration_custom_preUpgradeUsesNotification() throws Exception {
+        defaultChannel.setVibration(false);
+        // pre upgrade, custom vibration.
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
+                false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_VIBRATION, record.getVibration());
+    }
+
+    @Test
+    public void testVibration_custom_userLocked_preUpgrade() throws Exception {
+        defaultChannel.setVibration(true);
+        defaultChannel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
+        // pre upgrade, custom vibration.
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
+                false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
+    }
+
+    @Test
+    public void testVibration_custom_upgradeUsesChannel() throws Exception {
+        channel.setVibration(true);
+        // post upgrade, custom vibration.
+        StatusBarNotification sbn = getNotification(false /*preO */, false /* noisy */,
+                false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
+    }
+
+    @Test
+    public void testAudioAttributes_preUpgrade() throws Exception {
+        defaultChannel.setSound(null);
+        // pre upgrade, default sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
+    }
+
+    @Test
+    public void testAudioAttributes_upgrade() throws Exception {
+        channel.setSound(null);
+        // post upgrade, default sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
+    }
+
+    @Test
+    public void testImportance_preUpgrade() throws Exception {
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
+    }
+
+    @Test
+    public void testImportance_locked_preUpgrade() throws Exception {
+        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+        defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(NotificationManager.IMPORTANCE_LOW, record.getImportance());
+    }
+
+    @Test
+    public void testImportance_upgrade() throws Exception {
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn);
+        assertEquals(NotificationManager.IMPORTANCE_DEFAULT, record.getImportance());
+    }
+}
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index 92c67b5..3df0d66 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -52,7 +52,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -225,7 +224,7 @@
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel2 =
                 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
-        channel2.setRingtone(new Uri.Builder().scheme("test").build());
+        channel2.setSound(new Uri.Builder().scheme("test").build());
         channel2.setLights(true);
         channel2.setBypassDnd(true);
         channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
@@ -441,15 +440,15 @@
         // all fields locked by user
         final NotificationChannel channel =
             new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
-        channel.setRingtone(new Uri.Builder().scheme("test").build());
-        channel.lockFields(NotificationChannel.USER_LOCKED_RINGTONE);
+        channel.setSound(new Uri.Builder().scheme("test").build());
+        channel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
 
         mHelper.createNotificationChannel(pkg, uid, channel);
 
         // same id, try to update all fields
         final NotificationChannel channel2 =
             new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
-        channel2.setRingtone(new Uri.Builder().scheme("test2").build());
+        channel2.setSound(new Uri.Builder().scheme("test2").build());
 
         mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
 
@@ -462,7 +461,7 @@
         // no fields locked by user
         final NotificationChannel channel =
                 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
-        channel.setRingtone(new Uri.Builder().scheme("test").build());
+        channel.setSound(new Uri.Builder().scheme("test").build());
         channel.setLights(true);
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
@@ -472,7 +471,7 @@
         // same id, try to update all fields
         final NotificationChannel channel2 =
                 new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
-        channel2.setRingtone(new Uri.Builder().scheme("test2").build());
+        channel2.setSound(new Uri.Builder().scheme("test2").build());
         channel2.setLights(false);
         channel2.setBypassDnd(false);
         channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index bd9e6d1..ba25b16 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -32,7 +31,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        service = ActivityManagerNative.getDefault();
+        service = ActivityManager.getService();
     }
 
     public void testTaskIdsForRunningUsers() throws RemoteException {
@@ -52,4 +51,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index c9c691d..0359096 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -22,8 +22,8 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.ITaskStackListener;
 import android.app.Instrumentation.ActivityMonitor;
@@ -63,7 +63,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mService = ActivityManagerNative.getDefault();
+        mService = ActivityManager.getService();
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 80be62b..4927f0c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -22,6 +22,7 @@
 import android.content.pm.PackageManagerInternal;
 import android.database.ContentObserver;
 import android.media.IAudioService;
+import android.net.IIpConnectivityMetrics;
 import android.net.Uri;
 import android.os.Looper;
 import android.os.PowerManagerInternal;
@@ -153,6 +154,11 @@
         }
 
         @Override
+        IIpConnectivityMetrics getIIpConnectivityMetrics() {
+            return context.iipConnectivityMetrics;
+        }
+
+        @Override
         IWindowManager getIWindowManager() {
             return context.iwindowManager;
         }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 56ff621..e55cafb 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -25,6 +25,9 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.net.IIpConnectivityMetrics;
 import android.net.wifi.WifiInfo;
 import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
@@ -38,6 +41,7 @@
 import android.util.ArraySet;
 import android.util.Pair;
 
+import com.android.internal.R;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
@@ -53,6 +57,7 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
@@ -2178,6 +2183,26 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
     }
 
+    public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
+            throws Exception {
+        setDeviceOwner();
+
+        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
+                .thenReturn(true);
+        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
+        when(mContext.userManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER))
+                .thenReturn(true);
+        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+                false /* we can't remove a managed profile*/)).thenReturn(false);
+        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
+                true)).thenReturn(true);
+        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
+
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+
+        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
+    }
+
     public void testForceUpdateUserSetupComplete_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
         try {
@@ -2248,6 +2273,150 @@
         assertFalse(dpms.hasUserSetupCompleted());
     }
 
+    private long getLastSecurityLogRetrievalTime() {
+        final long ident = mContext.binder.clearCallingIdentity();
+        final long lastSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
+        mContext.binder.restoreCallingIdentity(ident);
+        return lastSecurityLogRetrievalTime;
+    }
+
+    public void testGetLastSecurityLogRetrievalTime() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        when(mContext.userManager.getUserCount()).thenReturn(1);
+        when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
+                .thenReturn(true);
+
+        // No logs were retrieved so far.
+        assertEquals(-1, getLastSecurityLogRetrievalTime());
+
+        // Enabling logging should not change the timestamp.
+        dpm.setSecurityLoggingEnabled(admin1, true);
+        assertEquals(-1, getLastSecurityLogRetrievalTime());
+
+        // Retrieving the logs should update the timestamp.
+        final long beforeRetrieval = System.currentTimeMillis();
+        dpm.retrieveSecurityLogs(admin1);
+        final long firstSecurityLogRetrievalTime = getLastSecurityLogRetrievalTime();
+        final long afterRetrieval = System.currentTimeMillis();
+        assertTrue(firstSecurityLogRetrievalTime >= beforeRetrieval);
+        assertTrue(firstSecurityLogRetrievalTime <= afterRetrieval);
+
+        // Retrieving the pre-boot logs should update the timestamp.
+        Thread.sleep(2);
+        dpm.retrievePreRebootSecurityLogs(admin1);
+        final long secondSecurityLogRetrievalTime = getLastSecurityLogRetrievalTime();
+        assertTrue(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime);
+
+        // Checking the timestamp again should not change it.
+        Thread.sleep(2);
+        assertEquals(secondSecurityLogRetrievalTime, getLastSecurityLogRetrievalTime());
+
+        // Retrieving the logs again should update the timestamp.
+        dpm.retrieveSecurityLogs(admin1);
+        final long thirdSecurityLogRetrievalTime = getLastSecurityLogRetrievalTime();
+        assertTrue(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime);
+
+        // Disabling logging should not change the timestamp.
+        Thread.sleep(2);
+        dpm.setSecurityLoggingEnabled(admin1, false);
+        assertEquals(thirdSecurityLogRetrievalTime, getLastSecurityLogRetrievalTime());
+
+        // Restarting the DPMS should not lose the timestamp.
+        initializeDpms();
+        assertEquals(thirdSecurityLogRetrievalTime, getLastSecurityLogRetrievalTime());
+    }
+
+    private long getLastBugReportRequestTime() {
+        final long ident = mContext.binder.clearCallingIdentity();
+        final long lastBugRequestTime = dpm.getLastBugReportRequestTime();
+        mContext.binder.restoreCallingIdentity(ident);
+        return lastBugRequestTime;
+    }
+
+    public void testGetLastBugReportRequestTime() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        when(mContext.userManager.getUserCount()).thenReturn(1);
+        mContext.packageName = admin1.getPackageName();
+        mContext.applicationInfo = new ApplicationInfo();
+        when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject()))
+                .thenReturn(Color.WHITE);
+        when(mContext.resources.getColor(eq(R.color.notification_material_background_color),
+                anyObject())).thenReturn(Color.WHITE);
+
+        // No bug reports were requested so far.
+        assertEquals(-1, getLastSecurityLogRetrievalTime());
+
+        // Requesting a bug report should update the timestamp.
+        final long beforeRequest = System.currentTimeMillis();
+        dpm.requestBugreport(admin1);
+        final long bugReportRequestTime = getLastBugReportRequestTime();
+        final long afterRequest = System.currentTimeMillis();
+        assertTrue(bugReportRequestTime >= beforeRequest);
+        assertTrue(bugReportRequestTime <= afterRequest);
+
+        // Checking the timestamp again should not change it.
+        Thread.sleep(2);
+        assertEquals(bugReportRequestTime, getLastBugReportRequestTime());
+
+        // Restarting the DPMS should not lose the timestamp.
+        initializeDpms();
+        assertEquals(bugReportRequestTime, getLastBugReportRequestTime());
+    }
+
+    private long getLastNetworkLogRetrievalTime() {
+        final long ident = mContext.binder.clearCallingIdentity();
+        final long lastNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
+        mContext.binder.restoreCallingIdentity(ident);
+        return lastNetworkLogRetrievalTime;
+    }
+
+    public void testGetLastNetworkLogRetrievalTime() throws Exception {
+        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+        setupDeviceOwner();
+        when(mContext.userManager.getUserCount()).thenReturn(1);
+        when(mContext.iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
+                .thenReturn(true);
+
+        // No logs were retrieved so far.
+        assertEquals(-1, getLastNetworkLogRetrievalTime());
+
+        // Attempting to retrieve logs without enabling logging should not change the timestamp.
+        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
+        assertEquals(-1, getLastNetworkLogRetrievalTime());
+
+        // Enabling logging should not change the timestamp.
+        dpm.setNetworkLoggingEnabled(admin1, true);
+        assertEquals(-1, getLastNetworkLogRetrievalTime());
+
+        // Retrieving the logs should update the timestamp.
+        final long beforeRetrieval = System.currentTimeMillis();
+        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
+        final long firstNetworkLogRetrievalTime = getLastNetworkLogRetrievalTime();
+        final long afterRetrieval = System.currentTimeMillis();
+        assertTrue(firstNetworkLogRetrievalTime >= beforeRetrieval);
+        assertTrue(firstNetworkLogRetrievalTime <= afterRetrieval);
+
+        // Checking the timestamp again should not change it.
+        Thread.sleep(2);
+        assertEquals(firstNetworkLogRetrievalTime, getLastNetworkLogRetrievalTime());
+
+        // Retrieving the logs again should update the timestamp.
+        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
+        final long secondNetworkLogRetrievalTime = getLastNetworkLogRetrievalTime();
+        assertTrue(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime);
+
+        // Disabling logging should not change the timestamp.
+        Thread.sleep(2);
+        dpm.setNetworkLoggingEnabled(admin1, false);
+        assertEquals(secondNetworkLogRetrievalTime, getLastNetworkLogRetrievalTime());
+
+        // Restarting the DPMS should not lose the timestamp.
+        initializeDpms();
+        assertEquals(secondNetworkLogRetrievalTime, getLastNetworkLogRetrievalTime());
+    }
+
     private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
         when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
                 userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 37430ad..d74c6dc 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -26,11 +26,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.media.IAudioService;
+import android.net.IIpConnectivityMetrics;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.os.Handler;
@@ -249,6 +252,7 @@
 
     public final MockBinder binder;
     public final EnvironmentForMock environment;
+    public final Resources resources;
     public final SystemPropertiesForMock systemProperties;
     public final UserManager userManager;
     public final UserManagerInternal userManagerInternal;
@@ -257,6 +261,7 @@
     public final PowerManagerForMock powerManager;
     public final PowerManagerInternal powerManagerInternal;
     public final NotificationManager notificationManager;
+    public final IIpConnectivityMetrics iipConnectivityMetrics;
     public final IWindowManager iwindowManager;
     public final IActivityManager iactivityManager;
     public final IPackageManager ipackageManager;
@@ -278,6 +283,10 @@
 
     public final BuildMock buildMock = new BuildMock();
 
+    public String packageName = null;
+
+    public ApplicationInfo applicationInfo = null;
+
     public DpmMockContext(Context context, File dataDir) {
         realTestContext = context;
 
@@ -286,7 +295,8 @@
 
         binder = new MockBinder();
         environment = mock(EnvironmentForMock.class);
-        systemProperties= mock(SystemPropertiesForMock.class);
+        resources = mock(Resources.class);
+        systemProperties = mock(SystemPropertiesForMock.class);
         userManager = mock(UserManager.class);
         userManagerInternal = mock(UserManagerInternal.class);
         userManagerForMock = mock(UserManagerForMock.class);
@@ -294,6 +304,7 @@
         powerManager = mock(PowerManagerForMock.class);
         powerManagerInternal = mock(PowerManagerInternal.class);
         notificationManager = mock(NotificationManager.class);
+        iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
         iwindowManager = mock(IWindowManager.class);
         iactivityManager = mock(IActivityManager.class);
         ipackageManager = mock(IPackageManager.class);
@@ -416,6 +427,32 @@
     }
 
     @Override
+    public Resources getResources() {
+        return resources;
+    }
+
+    @Override
+    public Resources.Theme getTheme() {
+        return spiedContext.getTheme();
+    }
+
+    @Override
+    public String getPackageName() {
+        if (packageName != null) {
+            return packageName;
+        }
+        return super.getPackageName();
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo() {
+        if (applicationInfo != null) {
+            return applicationInfo;
+        }
+        return super.getApplicationInfo();
+    }
+
+    @Override
     public Object getSystemService(String name) {
         switch (name) {
             case Context.USER_SERVICE:
@@ -615,4 +652,9 @@
     public ContentResolver getContentResolver() {
         return contentResolver;
     }
+
+    @Override
+    public int getUserId() {
+        return UserHandle.getUserId(binder.getCallingUid());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
new file mode 100644
index 0000000..379d4fe
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.pm;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+
+import com.android.internal.os.RoSystemProperties;
+import com.android.server.SystemConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static junit.framework.Assert.assertTrue;
+
+
+/**
+ * Presubmit tests for {@link PackageManager}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class PackageManagerPresubmitTest {
+
+    private Context mContext;
+
+    private PackageManager mPackageManager;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    /**
+     * <p>This test ensures that all signature|privileged permissions are granted to core apps like
+     * systemui/settings. If CONTROL_PRIVAPP_PERMISSIONS is set, the test also verifies that
+     * granted permissions are whitelisted in {@link SystemConfig}
+     */
+    @Test
+    @SmallTest
+    @Presubmit
+    public void testPrivAppPermissions() throws PackageManager.NameNotFoundException {
+        String[] testPackages = {"com.android.settings", "com.android.shell",
+                "com.android.systemui"};
+        for (String testPackage : testPackages) {
+            testPackagePrivAppPermission(testPackage);
+        }
+    }
+
+    private void testPackagePrivAppPermission(String testPackage)
+            throws PackageManager.NameNotFoundException {
+        PackageInfo packageInfo = mPackageManager.getPackageInfo(testPackage,
+                PackageManager.GET_PERMISSIONS);
+        ArraySet<String> privAppPermissions = SystemConfig.getInstance()
+                .getPrivAppPermissions(testPackage);
+        for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
+            String pName = packageInfo.requestedPermissions[i];
+            int protectionLevel;
+            boolean platformPermission;
+            try {
+                PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(pName, 0);
+                platformPermission = PackageManagerService.PLATFORM_PACKAGE_NAME.equals(
+                        permissionInfo.packageName);
+                protectionLevel = permissionInfo.protectionLevel;
+            } catch (PackageManager.NameNotFoundException e) {
+                continue;
+            }
+            if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
+                boolean granted = (packageInfo.requestedPermissionsFlags[i]
+                        & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
+                assertTrue("Permission " + pName + " should be granted to " + testPackage, granted);
+                // if CONTROL_PRIVAPP_PERMISSIONS enabled, platform permissions must be whitelisted
+                // in SystemConfig
+                if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS) {
+                    assertTrue("Permission " + pName
+                                    + " should be declared in the xml file for package "
+                                    + testPackage,
+                            privAppPermissions.contains(pName));
+                }
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 772b2a2..207939f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -45,16 +45,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class AppWindowTokenTests {
-
-    private static WindowManagerService sWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
-    }
+public class AppWindowTokenTests extends WindowTestsBase {
 
     @Test
     public void testAddWindow_Order() throws Exception {
@@ -62,10 +53,11 @@
 
         assertEquals(0, token.getWindowsCount());
 
-        final WindowState win1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token);
-        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token);
-        final WindowState win4 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, token, "win1");
+        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, token,
+                "startingWin");
+        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, token, "baseWin");
+        final WindowState win4 = createWindow(null, TYPE_APPLICATION, token, "win4");
 
         token.addWindow(win1);
         token.addWindow(startingWin);
@@ -92,24 +84,18 @@
 
         assertNull(token.findMainWindow());
 
-        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
+        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
         token.addWindow(window1);
         assertEquals(window1, token.findMainWindow());
         window1.mAnimatingExit = true;
         assertEquals(window1, token.findMainWindow());
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token);
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, token, "window2");
         token.addWindow(window2);
         assertEquals(window2, token.findMainWindow());
     }
 
-    private WindowState createWindow(WindowState parent, int type, WindowToken token) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(sWm, null, mIWindow, token, parent, 0, 0, attrs, 0, 0);
-    }
-
     /* Used so we can gain access to some protected members of the {@link AppWindowToken} class */
     private class TestAppWindowToken extends AppWindowToken {
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 0533efc..0801a88 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,28 +16,15 @@
 
 package com.android.server.wm;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import android.content.Context;
-import android.content.res.Configuration;
-import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.WindowManager;
 
 import java.util.ArrayList;
 
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.AppOpsManager.OP_NONE;
-import static android.content.res.Configuration.EMPTY;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -47,7 +34,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
 
 /**
  * Tests for the {@link DisplayContent} class.
@@ -58,21 +44,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class DisplayContentTests {
-
-    private static WindowManagerService sWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-    private final Session mMockSession = mock(Session.class);
-    private Display mDisplay;
-    private int mNextStackId = FIRST_DYNAMIC_STACK_ID;
-    private int mNextTaskId = 0;
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
-        mDisplay = context.getDisplay();
-    }
+public class DisplayContentTests extends WindowTestsBase {
 
     @Test
     public void testForAllWindows() throws Exception {
@@ -98,7 +70,7 @@
         final ArrayList<WindowState> windows = new ArrayList();
 
         // Test forward traversal.
-        dc.forAllWindows(windows::add, false /* traverseTopToBottom */);
+        dc.forAllWindows(w -> {windows.add(w);}, false /* traverseTopToBottom */);
 
         assertEquals(wallpaperWindow, windows.get(0));
         assertEquals(exitingAppWindow, windows.get(1));
@@ -112,7 +84,7 @@
 
         // Test backward traversal.
         windows.clear();
-        dc.forAllWindows(windows::add, true /* traverseTopToBottom */);
+        dc.forAllWindows(w -> {windows.add(w);}, true /* traverseTopToBottom */);
 
         assertEquals(wallpaperWindow, windows.get(8));
         assertEquals(exitingAppWindow, windows.get(7));
@@ -124,36 +96,4 @@
         assertEquals(imeWindow, windows.get(1));
         assertEquals(imeDialogWindow, windows.get(0));
     }
-
-    private WindowToken createWindowToken(DisplayContent dc, int type) {
-        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
-            return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
-        }
-
-        final int stackId = mNextStackId++;
-        dc.addStackToDisplay(stackId, true);
-        final TaskStack stack = sWm.mStackIdToStack.get(stackId);
-        final Task task = new Task(mNextTaskId++, stack, 0, sWm, null, EMPTY, false);
-        stack.addTask(task, true);
-        final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
-        task.addAppToken(0, token, 0, false);
-        return token;
-    }
-
-    private WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
-        final WindowToken token = createWindowToken(dc, type);
-        return createWindow(parent, type, token, name);
-    }
-
-    private WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-        attrs.setTitle(name);
-
-        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0);
-        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
-        // adding it to the token...
-        token.addWindow(w);
-        return w;
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 38a98b2..ed4c79f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -272,22 +272,26 @@
     }
 
     @Override
-    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
     @Override
-    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId) {
         return 0;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
new file mode 100644
index 0000000..5a035d6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+/**
+ * Tests for the {@link WindowLayersController} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowLayersControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowLayersControllerTests extends WindowTestsBase {
+
+    private static boolean sOneTimeSetupDone = false;
+    private static WindowLayersController sLayersController;
+    private static DisplayContent sDisplayContent;
+    private static WindowState sImeWindow;
+    private static WindowState sImeDialogWindow;
+    private static WindowState sStatusBarWindow;
+    private static WindowState sDockedDividerWindow;
+    private static WindowState sNavBarWindow;
+    private static WindowState sAppWindow;
+    private static WindowState sChildAppWindow;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        if (sOneTimeSetupDone) {
+            return;
+        }
+        sOneTimeSetupDone = true;
+        sLayersController = new WindowLayersController(sWm);
+        sDisplayContent =
+                new DisplayContent(mDisplay, sWm, sLayersController, new WallpaperController(sWm));
+        final WindowState wallpaperWindow =
+                createWindow(null, TYPE_WALLPAPER, sDisplayContent, "wallpaperWindow");
+        sImeWindow = createWindow(null, TYPE_INPUT_METHOD, sDisplayContent, "sImeWindow");
+        sImeDialogWindow =
+                createWindow(null, TYPE_INPUT_METHOD_DIALOG, sDisplayContent, "sImeDialogWindow");
+        sStatusBarWindow = createWindow(null, TYPE_STATUS_BAR, sDisplayContent, "sStatusBarWindow");
+        sNavBarWindow =
+                createWindow(null, TYPE_NAVIGATION_BAR, sStatusBarWindow.mToken, "sNavBarWindow");
+        sDockedDividerWindow =
+                createWindow(null, TYPE_DOCK_DIVIDER, sDisplayContent, "sDockedDividerWindow");
+        sAppWindow = createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "sAppWindow");
+        sChildAppWindow = createWindow(sAppWindow,
+                TYPE_APPLICATION_ATTACHED_DIALOG, sAppWindow.mToken, "sChildAppWindow");
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
+        sWm.mInputMethodTarget = null;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // The Ime has an higher base layer than app windows and lower base layer than system
+        // windows, so it should be above app windows and below system windows if there isn't an IME
+        // target.
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
+        final WindowState imeAppTarget =
+                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+        sWm.mInputMethodTarget = imeAppTarget;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // Ime should be above all app windows and below system windows if it is targeting an app
+        // window.
+        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
+        final WindowState imeSystemOverlayTarget =
+                createWindow(null, TYPE_SYSTEM_OVERLAY, sDisplayContent, "imeSystemOverlayTarget");
+
+        sWm.mInputMethodTarget = imeSystemOverlayTarget;
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        // The IME target base layer is higher than all window except for the nav bar window, so the
+        // IME should be above all windows except for the nav bar.
+        assertWindowLayerGreaterThan(sImeWindow, imeSystemOverlayTarget);
+        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
+        assertWindowLayerGreaterThan(sImeWindow, sStatusBarWindow);
+        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+    }
+
+    private void assertWindowLayerGreaterThan(WindowState first, WindowState second)
+            throws Exception {
+        assertGreaterThan(first.mWinAnimator.mAnimLayer, second.mWinAnimator.mAnimLayer);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 3df1df9..3f47d5c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -41,32 +41,30 @@
 /**
  * Tests for the {@link WindowState} class.
  *
- * Build: mmma -j32 frameworks/base/services/tests/servicestests
- * Install: adb install -r out/target/product/$TARGET_PRODUCT/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * Run: adb shell am instrument -w -e class com.android.server.wm.WindowStateTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * runtest frameworks-services -c com.android.server.wm.WindowStateTests
  */
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class WindowStateTests {
+public class WindowStateTests extends WindowTestsBase {
 
-    private static WindowManagerService sWm = null;
     private WindowToken mWindowToken;
-    private final IWindow mIWindow = new TestIWindow();
 
     @Before
     public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        super.setUp();
         mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
                 sWm.getDefaultDisplayContentLocked());
     }
 
     @Test
     public void testIsParentWindowHidden() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertFalse(parentWindow.mHidden);
         assertFalse(parentWindow.isParentWindowHidden());
@@ -81,10 +79,14 @@
 
     @Test
     public void testIsChildWindow() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
+        final WindowState randomWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow");
 
         assertFalse(parentWindow.isChildWindow());
         assertTrue(child1.isChildWindow());
@@ -94,12 +96,13 @@
 
     @Test
     public void testHasChild() throws Exception {
-        final WindowState win1 = createWindow(null, TYPE_APPLICATION);
-        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW);
-        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW);
-        final WindowState win2 = createWindow(null, TYPE_APPLICATION);
-        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW);
-        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION);
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win1");
+        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win11");
+        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, mWindowToken, "win12");
+        final WindowState win2 = createWindow(null, TYPE_APPLICATION, mWindowToken, "win2");
+        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, mWindowToken, "win21");
+        final WindowState randomWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "randomWindow");
 
         assertTrue(win1.hasChild(win11));
         assertTrue(win1.hasChild(win12));
@@ -114,34 +117,13 @@
     }
 
     @Test
-    public void testGetBottomChild() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        assertNull(parentWindow.getBottomChild());
-
-        final WindowState child1 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
-        assertEquals(child1, parentWindow.getBottomChild());
-
-        final WindowState child2 = createWindow(parentWindow, TYPE_APPLICATION_PANEL);
-        // Since child1 and child2 are at the same layer, then child2 is expect to be added on top
-        // on child1
-        assertEquals(child1, parentWindow.getBottomChild());
-
-        final WindowState child3 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
-        // Since child3 is a negative layer, we would expect it to be added below current children
-        // with positive layers.
-        assertEquals(child3, parentWindow.getBottomChild());
-
-        final WindowState child4 = createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY);
-        // We would also expect additional negative layers to be added below existing negative
-        // layers.
-        assertEquals(child4, parentWindow.getBottomChild());
-    }
-
-    @Test
     public void testGetParentWindow() throws Exception {
-        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW);
+        final WindowState parentWindow =
+                createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow");
+        final WindowState child1 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 =
+                createWindow(parentWindow, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertNull(parentWindow.getParentWindow());
         assertEquals(parentWindow, child1.getParentWindow());
@@ -150,9 +132,9 @@
 
     @Test
     public void testGetTopParentWindow() throws Exception {
-        final WindowState root = createWindow(null, TYPE_APPLICATION);
-        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW);
-        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW);
+        final WindowState root = createWindow(null, TYPE_APPLICATION, mWindowToken, "root");
+        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, mWindowToken, "child1");
+        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, mWindowToken, "child2");
 
         assertEquals(root, root.getTopParentWindow());
         assertEquals(root, child1.getTopParentWindow());
@@ -160,9 +142,12 @@
         assertEquals(root, child2.getTopParentWindow());
     }
 
-    private WindowState createWindow(WindowState parent, int type) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(sWm, null, mIWindow, mWindowToken, parent, 0, 0, attrs, 0, 0);
+    @Test
+    public void testIsOnScreen_hiddenByPolicy() {
+        final WindowState window = createWindow(null, TYPE_APPLICATION, mWindowToken, "window");
+        window.setHasSurface(true);
+        assertTrue(window.isOnScreen());
+        window.hideLw(false /* doAnimation */);
+        assertFalse(window.isOnScreen());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
new file mode 100644
index 0000000..9681bd2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Assert;
+import org.junit.Before;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.support.test.InstrumentationRegistry;
+import android.view.Display;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.res.Configuration.EMPTY;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Common base class for window manager unit test classes.
+ */
+public class WindowTestsBase {
+    static WindowManagerService sWm = null;
+    private final IWindow mIWindow = new TestIWindow();
+    private final Session mMockSession = mock(Session.class);
+    Display mDisplay;
+    private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
+    private static int sNextTaskId = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        mDisplay = context.getDisplay();
+    }
+
+    /** Asserts that the first entry is greater than the second entry. */
+    void assertGreaterThan(int first, int second) throws Exception {
+        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
+    }
+
+    WindowToken createWindowToken(DisplayContent dc, int type) {
+        if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
+            return new WindowToken(sWm, mock(IBinder.class), type, false, dc);
+        }
+
+        final int stackId = sNextStackId++;
+        dc.addStackToDisplay(stackId, true);
+        final TaskStack stack = sWm.mStackIdToStack.get(stackId);
+        final Task task = new Task(sNextTaskId++, stack, 0, sWm, null, EMPTY, false);
+        stack.addTask(task, true);
+        final AppWindowToken token = new AppWindowToken(sWm, null, false, dc);
+        task.addAppToken(0, token, 0, false);
+        return token;
+    }
+
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
+        final WindowToken token = createWindowToken(dc, type);
+        return createWindow(parent, type, token, name);
+    }
+
+    WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
+        attrs.setTitle(name);
+
+        final WindowState w = new WindowState(sWm, mMockSession, mIWindow, token, parent, OP_NONE,
+                0, attrs, 0, 0);
+        // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
+        // adding it to the token...
+        token.addWindow(w);
+        return w;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index d12d672a..d6bfa17 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -47,17 +47,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class WindowTokenTests {
-
-    private WindowManagerService mWm = null;
-    private final IWindow mIWindow = new TestIWindow();
-    private final Session mMockSession = mock(Session.class);
-
-    @Before
-    public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mWm = TestWindowManagerPolicy.getWindowManagerService(context);
-    }
+public class WindowTokenTests extends WindowTestsBase {
 
     @Test
     public void testAddWindow() throws Exception {
@@ -65,11 +55,11 @@
 
         assertEquals(0, token.getWindowsCount());
 
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
 
         token.addWindow(window1);
         // NOTE: Child windows will not be added to the token as window containers can only
@@ -91,12 +81,12 @@
     @Test
     public void testChildRemoval() throws Exception {
         final TestWindowToken token = new TestWindowToken();
-        final DisplayContent dc = mWm.getDefaultDisplayContentLocked();
+        final DisplayContent dc = sWm.getDefaultDisplayContentLocked();
 
         assertEquals(token, dc.getWindowToken(token.token));
 
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
         token.addWindow(window1);
         token.addWindow(window2);
 
@@ -113,11 +103,11 @@
     @Test
     public void testAdjustAnimLayer() throws Exception {
         final TestWindowToken token = new TestWindowToken();
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token);
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
 
         token.addWindow(window1);
         token.addWindow(window2);
@@ -136,60 +126,11 @@
         assertEquals(window3StartLayer + adj, highestLayer);
     }
 
-    @Test
-    public void testGetTopWindow() throws Exception {
-        final TestWindowToken token = new TestWindowToken();
-
-        assertNull(token.getTopWindow());
-
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        token.addWindow(window1);
-        assertEquals(window1, token.getTopWindow());
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        assertEquals(window12, token.getTopWindow());
-
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        token.addWindow(window2);
-        // Since new windows are added to the bottom of the token, we would still expect the
-        // previous one to the top.
-        assertEquals(window12, token.getTopWindow());
-    }
-
-    @Test
-    public void testGetWindowIndex() throws Exception {
-        final TestWindowToken token = new TestWindowToken();
-
-        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token);
-        assertEquals(-1, token.getWindowIndex(window1));
-        token.addWindow(window1);
-        assertEquals(0, token.getWindowIndex(window1));
-        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token);
-        // Child windows should report the same index as their parents.
-        assertEquals(0, token.getWindowIndex(window11));
-        assertEquals(0, token.getWindowIndex(window12));
-
-        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token);
-        assertEquals(-1, token.getWindowIndex(window2));
-        token.addWindow(window2);
-        // Since new windows are added to the bottom of the token, we would expect the added window
-        // to be at index 0.
-        assertEquals(0, token.getWindowIndex(window2));
-        assertEquals(1, token.getWindowIndex(window1));
-    }
-
-    private WindowState createWindow(WindowState parent, int type, WindowToken token) {
-        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
-
-        return new WindowState(mWm, mMockSession, mIWindow, token, parent, OP_NONE, 0, attrs, 0, 0);
-    }
-
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
     private class TestWindowToken extends WindowToken {
 
         TestWindowToken() {
-            super(mWm, mock(IBinder.class), 0, false, mWm.getDefaultDisplayContentLocked());
+            super(sWm, mock(IBinder.class), 0, false, sWm.getDefaultDisplayContentLocked());
         }
 
         int getWindowsCount() {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 04104b5..7217c3b 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -17,7 +17,7 @@
 package com.android.server.usage;
 
 import android.Manifest;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
@@ -462,7 +462,7 @@
 
         final int[] runningUserIds;
         try {
-            runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds();
+            runningUserIds = ActivityManager.getService().getRunningUserIds();
             if (checkUserId != UserHandle.USER_ALL
                     && !ArrayUtils.contains(runningUserIds, checkUserId)) {
                 return false;
@@ -1311,7 +1311,7 @@
         @Override
         public boolean isAppInactive(String packageName, int userId) {
             try {
-                userId = ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+                userId = ActivityManager.getService().handleIncomingUser(Binder.getCallingPid(),
                         Binder.getCallingUid(), userId, false, true, "isAppInactive", null);
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
@@ -1329,7 +1329,7 @@
         public void setAppInactive(String packageName, boolean idle, int userId) {
             final int callingUid = Binder.getCallingUid();
             try {
-                userId = ActivityManagerNative.getDefault().handleIncomingUser(
+                userId = ActivityManager.getService().handleIncomingUser(
                         Binder.getCallingPid(), callingUid, userId, false, true,
                         "setAppIdle", null);
             } catch (RemoteException re) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 3daa87c..0544fae 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -362,11 +362,6 @@
                             UsbManager.removeFunction(persisted, UsbManager.USB_FUNCTION_MTP));
                 }
 
-                String buildType = SystemProperties.get(BUILD_TYPE_PROPERTY);
-                if (buildType.equals(BUILD_TYPE_USERDEBUG) || buildType.equals(BUILD_TYPE_ENG)) {
-                    setAdbEnabled(true);
-                }
-
                 setEnabledFunctions(null, false, false);
 
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
@@ -483,7 +478,7 @@
                 SystemProperties.set(USB_PERSISTENT_CONFIG_PROPERTY, newFunction);
 
                 // Remove mtp from the config if file transfer is not enabled
-                if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) && 
+                if (oldFunctions.equals(UsbManager.USB_FUNCTION_MTP) &&
                         !mUsbDataUnlocked && enable) {
                     oldFunctions = UsbManager.USB_FUNCTION_NONE;
                 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index a46ccee..4357dca 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -117,7 +116,7 @@
         mServiceStub = stub;
         mUser = userHandle;
         mComponent = service;
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         VoiceInteractionServiceInfo info;
         try {
             info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 7dacf16..4267ec4 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -17,7 +17,6 @@
 package com.android.server.voiceinteraction;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.assist.AssistContent;
@@ -182,7 +181,7 @@
         mCallback = callback;
         mCallingUid = callingUid;
         mHandler = handler;
-        mAm = ActivityManagerNative.getDefault();
+        mAm = ActivityManager.getService();
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         mAppOps = context.getSystemService(AppOpsManager.class);
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 016490c..c2a0ff1 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -515,9 +515,12 @@
                         final boolean isUnknown = args.argi2 == 1;
                         if (!mAreAccountsInitialized) {
                             Log.d(this, "Enqueueing pre-init request %s", id);
-                            mPreInitializationConnectionRequests.add(new Runnable() {
+                            mPreInitializationConnectionRequests.add(
+                                    new android.telecom.Logging.Runnable(
+                                            SESSION_HANDLER + SESSION_CREATE_CONN + ".pICR",
+                                            null /*lock*/) {
                                 @Override
-                                public void run() {
+                                public void loggedRun() {
                                     createConnection(
                                             connectionManagerPhoneAccount,
                                             id,
@@ -525,7 +528,7 @@
                                             isIncoming,
                                             isUnknown);
                                 }
-                            });
+                            }.prepare());
                         } else {
                             createConnection(
                                     connectionManagerPhoneAccount,
@@ -1381,9 +1384,9 @@
             public void onResult(
                     final List<ComponentName> componentNames,
                     final List<IBinder> services) {
-                mHandler.post(new Runnable() {
+                mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oR", null /*lock*/) {
                     @Override
-                    public void run() {
+                    public void loggedRun() {
                         for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
                             mRemoteConnectionManager.addConnectionService(
                                     componentNames.get(i),
@@ -1392,17 +1395,17 @@
                         onAccountsInitialized();
                         Log.d(this, "remote connection services found: " + services);
                     }
-                });
+                }.prepare());
             }
 
             @Override
             public void onError() {
-                mHandler.post(new Runnable() {
+                mHandler.post(new android.telecom.Logging.Runnable("oAA.qRCS.oE", null /*lock*/) {
                     @Override
-                    public void run() {
+                    public void loggedRun() {
                         mAreAccountsInitialized = true;
                     }
-                });
+                }.prepare());
             }
         });
     }
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 446bbbb..ced6627 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -48,13 +48,13 @@
     // Generic tag for all Telecom logging
     @VisibleForTesting
     public static String TAG = "TelecomFramework";
+    public static boolean DEBUG = isLoggable(android.util.Log.DEBUG);
+    public static boolean INFO = isLoggable(android.util.Log.INFO);
+    public static boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
+    public static boolean WARN = isLoggable(android.util.Log.WARN);
+    public static boolean ERROR = isLoggable(android.util.Log.ERROR);
 
     private static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
-    public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG);
-    public static final boolean INFO = isLoggable(android.util.Log.INFO);
-    public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE);
-    public static final boolean WARN = isLoggable(android.util.Log.WARN);
-    public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
 
     // Used to synchronize singleton logging lazy initialization
     private static final Object sSingletonSync = new Object();
@@ -340,6 +340,11 @@
 
     public static void setTag(String tag) {
         TAG = tag;
+        DEBUG = isLoggable(android.util.Log.DEBUG);
+        INFO = isLoggable(android.util.Log.INFO);
+        VERBOSE = isLoggable(android.util.Log.VERBOSE);
+        WARN = isLoggable(android.util.Log.WARN);
+        ERROR = isLoggable(android.util.Log.ERROR);
     }
 
     /**
diff --git a/telecomm/java/android/telecom/Logging/Runnable.java b/telecomm/java/android/telecom/Logging/Runnable.java
index b2cf3a3..6e81053 100644
--- a/telecomm/java/android/telecom/Logging/Runnable.java
+++ b/telecomm/java/android/telecom/Logging/Runnable.java
@@ -96,4 +96,4 @@
      */
     abstract public void loggedRun();
 
-}
+}
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java
index 3a7b8c0..c45bd6b 100644
--- a/telecomm/java/android/telecom/Logging/Session.java
+++ b/telecomm/java/android/telecom/Logging/Session.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telecom.Log;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -26,20 +27,23 @@
 import java.util.ArrayList;
 
 /**
- * The session that stores information about a thread's point of entry into the Telecom code that
- * persists until the thread exits Telecom.
+ * Stores information about a thread's point of entry into that should persist until that thread
+ * exits.
  * @hide
  */
 public class Session {
 
     public static final String START_SESSION = "START_SESSION";
+    public static final String START_EXTERNAL_SESSION = "START_EXTERNAL_SESSION";
     public static final String CREATE_SUBSESSION = "CREATE_SUBSESSION";
     public static final String CONTINUE_SUBSESSION = "CONTINUE_SUBSESSION";
     public static final String END_SUBSESSION = "END_SUBSESSION";
     public static final String END_SESSION = "END_SESSION";
 
     public static final String SUBSESSION_SEPARATION_CHAR = "->";
+    public static final String SESSION_SEPARATION_CHAR_CHILD = "_";
     public static final String EXTERNAL_INDICATOR = "E-";
+    public static final String TRUNCATE_STRING = "...";
 
     /**
      * Initial value of mExecutionEndTimeMs and the final value of {@link #getLocalExecutionTime()}
@@ -49,15 +53,19 @@
 
     public static class Info implements Parcelable {
         public final String sessionId;
-        public final String shortMethodName;
+        public final String methodPath;
 
-        private Info(String id, String methodName) {
+        private Info(String id, String path) {
             sessionId = id;
-            shortMethodName = methodName;
+            methodPath = path;
         }
 
         public static Info getInfo (Session s) {
-            return new Info(s.getFullSessionId(), s.getShortMethodName());
+            // Create Info based on the truncated method path if the session is external, so we do
+            // not get multiple stacking external sessions (unless we have DEBUG level logging or
+            // lower).
+            return new Info(s.getFullSessionId(), s.getFullMethodPath(
+                    !Log.DEBUG && s.isSessionExternal()));
         }
 
         /** Responsible for creating Info objects for deserialized Parcels. */
@@ -86,7 +94,7 @@
         @Override
         public void writeToParcel(Parcel destination, int flags) {
             destination.writeString(sessionId);
-            destination.writeString(shortMethodName);
+            destination.writeString(methodPath);
         }
     }
 
@@ -226,7 +234,15 @@
         if (parentSession == null) {
             return mSessionId;
         } else {
-            return parentSession.getFullSessionId() + "_" + mSessionId;
+            if (Log.VERBOSE) {
+                return parentSession.getFullSessionId() +
+                        // Append "_X" to subsession to show subsession designation.
+                        SESSION_SEPARATION_CHAR_CHILD + mSessionId;
+            } else {
+                // Only worry about the base ID at the top of the tree.
+                return parentSession.getFullSessionId();
+            }
+
         }
     }
 
@@ -259,16 +275,18 @@
     }
 
     // Recursively concatenate mShortMethodName with the parent Sessions to create full method
-    // path. Caches this string so that multiple calls for the path will be quick.
-    public String getFullMethodPath() {
+    // path. if truncatePath is set to true, all other external sessions (except for the most
+    // recent) will be truncated to "..."
+    public String getFullMethodPath(boolean truncatePath) {
         StringBuilder sb = new StringBuilder();
-        getFullMethodPath(sb);
+        getFullMethodPath(sb, truncatePath);
         return sb.toString();
     }
 
-    private synchronized void getFullMethodPath(StringBuilder sb) {
-        // Don't calculate if we have already figured it out!
-        if (!TextUtils.isEmpty(mFullMethodPathCache)) {
+    private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath) {
+        // Return cached value for method path. When returning the truncated path, recalculate the
+        // full path without using the cached value.
+        if (!TextUtils.isEmpty(mFullMethodPathCache) && !truncatePath) {
             sb.append(mFullMethodPathCache);
             return;
         }
@@ -278,25 +296,37 @@
             // Check to see if the session has been renamed yet. If it has not, then the session
             // has not been continued.
             isSessionStarted = !mShortMethodName.equals(parentSession.mShortMethodName);
-            parentSession.getFullMethodPath(sb);
+            parentSession.getFullMethodPath(sb, truncatePath);
             sb.append(SUBSESSION_SEPARATION_CHAR);
         }
         // Encapsulate the external session's method name so it is obvious what part of the session
-        // is external.
+        // is external or truncate it if we do not want the entire history.
         if (isExternal()) {
-            sb.append("(");
-            sb.append(mShortMethodName);
-            sb.append(")");
+            if (truncatePath) {
+                sb.append(TRUNCATE_STRING);
+            } else {
+                sb.append("(");
+                sb.append(mShortMethodName);
+                sb.append(")");
+            }
         } else {
             sb.append(mShortMethodName);
         }
-
-        if(isSessionStarted) {
+        // If we are returning the truncated path, do not save that path as the full path.
+        if (isSessionStarted && !truncatePath) {
             // Cache this value so that we do not have to do this work next time!
             // We do not cache the value if the session being evaluated hasn't been continued yet.
             mFullMethodPathCache = sb.toString();
         }
     }
+    // Recursively move to the top of the tree to see if the parent session is external.
+    private boolean isSessionExternal() {
+        if (getParentSession() == null) {
+            return isExternal();
+        } else {
+            return getParentSession().isSessionExternal();
+        }
+    }
 
     @Override
     public int hashCode() {
@@ -350,7 +380,7 @@
             return mParentSession.toString();
         } else {
             StringBuilder methodName = new StringBuilder();
-            methodName.append(getFullMethodPath());
+            methodName.append(getFullMethodPath(false /*truncatePath*/));
             if (mOwnerInfo != null && !mOwnerInfo.isEmpty()) {
                 methodName.append("(InCall package: ");
                 methodName.append(mOwnerInfo);
diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java
index 8ced7f81..949f7b7 100644
--- a/telecomm/java/android/telecom/Logging/SessionManager.java
+++ b/telecomm/java/android/telecom/Logging/SessionManager.java
@@ -177,8 +177,9 @@
         }
 
         // Create Session from Info and add to the sessionMapper under this ID.
+        Log.d(LOGGING_TAG, Session.START_EXTERNAL_SESSION);
         Session externalSession = new Session(Session.EXTERNAL_INDICATOR + sessionInfo.sessionId,
-                sessionInfo.shortMethodName, System.currentTimeMillis(),
+                sessionInfo.methodPath, System.currentTimeMillis(),
                 false /*isStartedFromActiveSession*/, null);
         externalSession.setIsExternal(true);
         // Mark the external session as already completed, since we have no way of knowing when
@@ -190,8 +191,6 @@
         // Create a subsession from this external Session parent node
         Session childSession = createSubsession();
         continueSession(childSession, shortMethodName);
-
-        Log.d(LOGGING_TAG, Session.START_SESSION);
     }
 
     /**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 60a27bd..1f06283 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -312,6 +312,13 @@
      */
     public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
 
+    /**
+     * Flag indicating whether we should downgrade/terminate VT calls and disable VT when
+     * data enabled changed (e.g. reach data limit or turn off data).
+     * @hide
+     */
+    public static final String KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS =
+            "ignore_data_enabled_changed_for_video_calls";
 
     /**
      * Flag specifying whether WFC over IMS should be available for carrier: independent of
@@ -1108,6 +1115,7 @@
         sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true);
         sDefaults.putString(KEY_DEFAULT_VM_NUMBER_STRING, "");
+        sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, false);
         sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false);
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index e87cba1..c484fd3 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Rlog;
+import android.util.Log;
 import android.content.res.Resources;
 
 /**
@@ -51,11 +52,6 @@
     //Use int max, as -1 is a valid value in signal strength
     public static final int INVALID = 0x7FFFFFFF;
 
-    private static final int RSRP_THRESH_TYPE_STRICT = 0;
-    private static final int[] RSRP_THRESH_STRICT = new int[] {-140, -115, -105, -95, -85, -44};
-    private static final int[] RSRP_THRESH_LENIENT = new int[] {-140, -128, -118, -108, -98, -44};
-
-
     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
     private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
     private int mCdmaDbm;   // This value is the RSSI value
@@ -791,22 +787,20 @@
          */
         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
 
-        int rsrpThreshType = Resources.getSystem().getInteger(com.android.internal.R.integer.
-                config_LTE_RSRP_threshold_type);
-        int[] threshRsrp;
-        if (rsrpThreshType == RSRP_THRESH_TYPE_STRICT) {
-            threshRsrp = RSRP_THRESH_STRICT;
+        int[] threshRsrp = Resources.getSystem().getIntArray(
+                com.android.internal.R.array.config_lteDbmThresholds);
+        if (threshRsrp.length != 6) {
+            Log.wtf(LOG_TAG, "getLteLevel - config_lteDbmThresholds has invalid num of elements."
+                    + " Cannot evaluate RSRP signal.");
         } else {
-            threshRsrp = RSRP_THRESH_LENIENT;
+            if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1;
+            else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+            else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+            else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+            else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
+            else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
         }
 
-        if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1;
-        else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
-        else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
-        else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
-        else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
-        else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
         /*
          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
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/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 330dbab..fee3aa5 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -316,6 +316,12 @@
 
     /** @hide */
     @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
     public List<EphemeralApplicationInfo> getEphemeralApplications() {
         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/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index b3ed9e1..0b169bd 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -272,6 +272,11 @@
     }
 
     @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
     public List<EphemeralApplicationInfo> getEphemeralApplications() {
         return null;
     }
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 5c53af9..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomCalendar.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CalendarView;
-
-public class CustomCalendar extends CalendarView {
-    public CustomCalendar(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        setDate(871732800000L, false, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java
deleted file mode 100644
index cb750f4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/CustomDate.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.DatePicker;
-
-public class CustomDate extends DatePicker {
-    public CustomDate(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        init(2015, 0, 20, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
new file mode 100644
index 0000000..3b819e5
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.test.myapplication.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CalendarView;
+
+public class CustomCalendar extends CalendarView {
+    public CustomCalendar(Context context) {
+        super(context);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        setDate(871732800000L, false, true);
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
new file mode 100644
index 0000000..f3877f1
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.test.myapplication.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.DatePicker;
+
+public class CustomDate extends DatePicker {
+    public CustomDate(Context context) {
+        super(context);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init();
+    }
+
+    private void init() {
+        init(2015, 0, 20, null);
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
new file mode 100644
index 0000000..58ad46d
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * This package contains custom widgets used to set a specific time for the DayTimePicker during
+ * testing.
+ * The classes here are both used from the Android project and from the Bridge test project.
+ */
+package com.android.layoutlib.test.myapplication.widgets;
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
index 50646ab..e9aa9e1 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<com.android.layoutlib.test.myapplication.ArraysCheckWidget xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.layoutlib.test.myapplication.ArraysCheckWidget
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical" android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml
deleted file mode 100644
index 5322411..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/empty.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
index c1f663e..ff14ce0 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
@@ -15,10 +15,10 @@
         android:checked="true"
         android:layout_gravity="center"
         />
-    <com.android.layoutlib.test.myapplication.CustomDate
+    <com.android.layoutlib.test.myapplication.widgets.CustomDate
         android:layout_width="100dp"
         android:layout_height="wrap_content"/>
-    <com.android.layoutlib.test.myapplication.CustomCalendar
+    <com.android.layoutlib.test.myapplication.widgets.CustomCalendar
         android:layout_width="200dp"
         android:layout_gravity="center_horizontal"
         android:layout_height="200dp"/>
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 55cfd6d..5423e87 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -39,6 +39,7 @@
 import com.android.resources.Density;
 import com.android.resources.Navigation;
 import com.android.resources.ResourceType;
+import com.android.tools.layoutlib.java.System_Delegate;
 import com.android.utils.ILogger;
 
 import org.junit.AfterClass;
@@ -51,6 +52,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.PackageInstaller.Session;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -58,11 +60,28 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.CopyOption;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 import com.google.android.collect.Lists;
 
@@ -105,6 +124,8 @@
     private static final String APP_TEST_DIR = "/testApp/MyApplication";
     /** Location of the app's res dir inside {@link #TEST_RES_DIR}*/
     private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
+    private static final String APP_CLASSES_LOCATION =
+            APP_TEST_DIR + "/build/intermediates/classes/debug/";
 
     private static LayoutLog sLayoutLibLog;
     private static FrameworkResources sFrameworkRepo;
@@ -115,6 +136,11 @@
     /** List of log messages generated by a render call. It can be used to find specific errors */
     private static ArrayList<String> sRenderMessages = Lists.newArrayList();
 
+    // Default class loader with access to the app classes
+    private ClassLoader mDefaultClassLoader =
+            new URLClassLoader(new URL[]{this.getClass().getResource(APP_CLASSES_LOCATION)},
+                    getClass().getClassLoader());
+
     @Rule
     public TestWatcher sRenderMessageWatcher = new TestWatcher() {
         @Override
@@ -192,6 +218,7 @@
         }
         File[] hosts = host.listFiles(path -> path.isDirectory() &&
                 (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
+        assert hosts != null;
         for (File hostOut : hosts) {
             String platformDir = getPlatformDirFromHostOut(hostOut);
             if (platformDir != null) {
@@ -213,6 +240,7 @@
             // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
             return path.isDirectory() && path.getName().startsWith("sdk");
         });
+        assert sdkDirs != null;
         for (File dir : sdkDirs) {
             String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
             if (platformDir != null) {
@@ -225,6 +253,7 @@
     private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
         File[] possibleSdks = sdkDir.listFiles(
                 path -> path.isDirectory() && path.getName().contains("android-sdk"));
+        assert possibleSdks != null;
         for (File possibleSdk : possibleSdks) {
             File platformsDir = new File(possibleSdk, "platforms");
             File[] platforms = platformsDir.listFiles(
@@ -312,10 +341,48 @@
         renderAndVerify("activity.xml", "activity.png");
     }
 
+    private static void gc() {
+        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
+        Object obj = new Object();
+        WeakReference ref = new WeakReference<>(obj);
+        //noinspection UnusedAssignment
+        obj = null;
+        while(ref.get() != null) {
+            System.gc();
+            System.runFinalization();
+        }
+
+        System.gc();
+        System.runFinalization();
+    }
+
+    /** Test allwidgets.xml */
+    @Test
+    public void testAllWidgets() throws ClassNotFoundException {
+        renderAndVerify("allwidgets.xml", "allwidgets.png");
+
+        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
+    }
+
+    @Test
+    public void testArrayCheck() throws ClassNotFoundException {
+        renderAndVerify("array_check.xml", "array_check.png");
+    }
+
+    @Test
+    public void testAllWidgetsTablet() throws ClassNotFoundException {
+        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
+
+        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
+        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
+    }
+
     @Test
     public void testActivityActionBar() throws ClassNotFoundException {
         LayoutPullParser parser = createLayoutPullParser("simple_activity.xml");
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -341,42 +408,6 @@
         renderAndVerify(params, "simple_activity.png");
     }
 
-    /** Test allwidgets.xml */
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets.png");
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testArrayCheck() throws ClassNotFoundException {
-        renderAndVerify("array_check.xml", "array_check.png");
-    }
-
-    @Test
-    public void testAllWidgetsTablet() throws ClassNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    private static void gc() {
-        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
-        Object obj = new Object();
-        WeakReference ref = new WeakReference<Object>(obj);
-        obj = null;
-        while(ref.get() != null) {
-            System.gc();
-            System.runFinalization();
-        }
-
-        System.gc();
-        System.runFinalization();
-    }
-
     @AfterClass
     public static void tearDown() {
         sLayoutLibLog = null;
@@ -397,7 +428,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("expand_vert_layout.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         ConfigGenerator customConfigGenerator = new ConfigGenerator()
@@ -431,7 +463,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("indeterminate_progressbar.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -456,7 +489,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("vector_drawable.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -474,7 +508,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("vector_drawable_android.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -490,7 +525,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser("scrolled.xml");
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
 
         SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
@@ -501,6 +537,7 @@
 
         RenderResult result = renderAndVerify(params, "scrolled.png");
         assertNotNull(result);
+        assertNotNull(result.getResult());
         assertTrue(result.getResult().isSuccess());
 
         ViewInfo rootLayout = result.getRootViews().get(0);
@@ -520,7 +557,15 @@
     @Test
     public void testGetResourceNameVariants() throws Exception {
         // Setup
-        SessionParams params = createSessionParams("empty.xml", ConfigGenerator.NEXUS_4);
+        // Create the layout pull parser for our resources (empty.xml can not be part of the test
+        // app as it won't compile).
+        LayoutPullParser parser = new LayoutPullParser("/empty.xml");
+        // Create LayoutLibCallback.
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+        layoutLibCallback.initResources();
+        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
+                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
         AssetManager assetManager = AssetManager.getSystem();
         DisplayMetrics metrics = new DisplayMetrics();
         Configuration configuration = RenderAction.getConfiguration(params);
@@ -562,6 +607,8 @@
             throws ClassNotFoundException {
         // TODO: Set up action bar handler properly to test menu rendering.
         // Create session params.
+        System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
+        System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
         RenderSession session = sBridge.createSession(params);
 
         if (frameTimeNanos != -1) {
@@ -629,7 +676,8 @@
         // Create the layout pull parser.
         LayoutPullParser parser = createLayoutPullParser(layoutFileName);
         // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
+        LayoutLibTestCallback layoutLibCallback =
+                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
         layoutLibCallback.initResources();
         // TODO: Set up action bar handler properly to test menu rendering.
         // Create session params.
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 96ae523..bae2dc0c 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -42,6 +42,9 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Map;
 
 import com.google.android.collect.Maps;
@@ -59,10 +62,11 @@
     private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
     private final ILogger mLog;
     private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
-    private final ClassLoader mModuleClassLoader = new ModuleClassLoader(PROJECT_CLASSES_LOCATION);
+    private final ClassLoader mModuleClassLoader;
 
-    public LayoutLibTestCallback(ILogger logger) {
+    public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
         mLog = logger;
+        mModuleClassLoader = classLoader;
     }
 
     public void initResources() throws ClassNotFoundException {
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
deleted file mode 100644
index 110f4c8..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ModuleClassLoader.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.setup;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-
-/**
- * The ClassLoader to load the project's classes.
- */
-public class ModuleClassLoader extends ClassLoader {
-
-    private final Map<String, Class<?>> mClasses = Maps.newHashMap();
-    private final String mClassLocation;
-
-    public ModuleClassLoader(String classLocation) {
-        mClassLocation = classLocation;
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        Class<?> aClass = mClasses.get(name);
-        if (aClass != null) {
-            return aClass;
-        }
-        String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class");
-        InputStream classInputStream = getClass().getResourceAsStream(pathName);
-        if (classInputStream == null) {
-            throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName);
-        }
-        byte[] data;
-        try {
-            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-            int nRead;
-            data = new byte[16384];  // 16k
-            while ((nRead = classInputStream.read(data, 0, data.length)) != -1) {
-                buffer.write(data, 0, nRead);
-            }
-            buffer.flush();
-            data = buffer.toByteArray();
-        } catch (IOException e) {
-            // Wrap the exception with ClassNotFoundException so that caller can deal with it.
-            throw new ClassNotFoundException("Unable to load class " + name, e);
-        }
-        aClass = defineClass(name, data, 0, data.length);
-        mClasses.put(name, aClass);
-        return aClass;
-    }
-}
diff --git a/tools/preload2/Android.mk b/tools/preload2/Android.mk
index ce877b3..09d95ff 100644
--- a/tools/preload2/Android.mk
+++ b/tools/preload2/Android.mk
@@ -5,7 +5,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 
 # To connect to devices (and take hprof dumps).
-LOCAL_STATIC_JAVA_LIBRARIES := ddmlib-prebuilt
+LOCAL_STATIC_JAVA_LIBRARIES := ddmlib-prebuilt tools-common-prebuilt
 
 # To process hprof dumps.
 LOCAL_STATIC_JAVA_LIBRARIES += perflib-prebuilt trove-prebuilt guavalib
diff --git a/wifi/java/android/net/wifi/EAPConstants.java b/wifi/java/android/net/wifi/EAPConstants.java
new file mode 100644
index 0000000..b5f7c94
--- /dev/null
+++ b/wifi/java/android/net/wifi/EAPConstants.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+/**
+ * Utility class containing EAP (Extensible Authentication Protocol) Related constants.
+ *
+ * @hide
+ */
+public final class EAPConstants {
+    // Constant definition for EAP types. Refer to
+    // http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml for more info.
+    public static final int EAP_MD5 = 4;
+    public static final int EAP_OTP = 5;
+    public static final int EAP_RSA = 9;
+    public static final int EAP_KEA = 11;
+    public static final int EAP_KEA_VALIDATE = 12;
+    public static final int EAP_TLS = 13;
+    public static final int EAP_LEAP = 17;
+    public static final int EAP_SIM = 18;
+    public static final int EAP_TTLS = 21;
+    public static final int EAP_AKA = 23;
+    public static final int EAP_3Com = 24;
+    public static final int EAP_MSCHAPv2 = 26;
+    public static final int EAP_PEAP = 29;
+    public static final int EAP_POTP = 32;
+    public static final int EAP_ActiontecWireless = 35;
+    public static final int EAP_HTTPDigest = 38;
+    public static final int EAP_SPEKE = 41;
+    public static final int EAP_MOBAC = 42;
+    public static final int EAP_FAST = 43;
+    public static final int EAP_ZLXEAP = 44;
+    public static final int EAP_Link = 45;
+    public static final int EAP_PAX = 46;
+    public static final int EAP_PSK = 47;
+    public static final int EAP_SAKE = 48;
+    public static final int EAP_IKEv2 = 49;
+    public static final int EAP_AKA_PRIME = 50;
+    public static final int EAP_GPSK = 51;
+    public static final int EAP_PWD = 52;
+    public static final int EAP_EKE = 53;
+    public static final int EAP_TEAP = 55;
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index bc38284..9e897bf 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -59,11 +59,6 @@
 
     int addOrUpdateNetwork(in WifiConfiguration config);
 
-    int addPasspointManagementObject(String mo);
-
-    int modifyPasspointManagementObject(String fqdn,
-                                        in List<PasspointManagementObjectDefinition> mos);
-
     boolean addPasspointConfiguration(in PasspointConfiguration config);
 
     boolean removePasspointConfiguration(in String fqdn);
@@ -132,8 +127,6 @@
 
     WifiConfiguration getWifiApConfiguration();
 
-    WifiConfiguration buildWifiConfig(String uriString, String mimeType, in byte[] data);
-
     void setWifiApConfiguration(in WifiConfiguration wifiConfig);
 
     Messenger getWifiServiceMessenger();
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 465addf..da87135 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -66,6 +66,93 @@
      * supported by the access point.
      */
     public String capabilities;
+
+    /**
+     * @hide
+     * No security protocol.
+     */
+    public static final int PROTOCOL_NONE = 0;
+    /**
+     * @hide
+     * Security protocol type: WPA version 1.
+     */
+    public static final int PROTOCOL_WPA = 1;
+    /**
+     * @hide
+     * Security protocol type: WPA version 2, also called RSN.
+     */
+    public static final int PROTOCOL_WPA2 = 2;
+    /**
+     * @hide
+     * Security protocol type:
+     * OSU Server-only authenticated layer 2 Encryption Network.
+     * Used for Hotspot 2.0.
+     */
+    public static final int PROTOCOL_OSEN = 3;
+
+    /**
+     * @hide
+     * No security key management scheme.
+     */
+    public static final int KEY_MGMT_NONE = 0;
+    /**
+     * @hide
+     * Security key management scheme: PSK.
+     */
+    public static final int KEY_MGMT_PSK = 1;
+    /**
+     * @hide
+     * Security key management scheme: EAP.
+     */
+    public static final int KEY_MGMT_EAP = 2;
+    /**
+     * @hide
+     * Security key management scheme: FT_PSK.
+     */
+    public static final int KEY_MGMT_FT_PSK = 3;
+    /**
+     * @hide
+     * Security key management scheme: FT_EAP.
+     */
+    public static final int KEY_MGMT_FT_EAP = 4;
+    /**
+     * @hide
+     * Security key management scheme: PSK_SHA256
+     */
+    public static final int KEY_MGMT_PSK_SHA256 = 5;
+    /**
+     * @hide
+     * Security key management scheme: EAP_SHA256.
+     */
+    public static final int KEY_MGMT_EAP_SHA256 = 6;
+    /**
+     * @hide
+     * Security key management scheme: OSEN.
+     * Used for Hotspot 2.0.
+     */
+    public static final int KEY_MGMT_OSEN = 7;
+
+    /**
+     * @hide
+     * No cipher suite.
+     */
+    public static final int CIPHER_NONE = 0;
+    /**
+     * @hide
+     * No group addressed, only used for group data cipher.
+     */
+    public static final int CIPHER_NO_GROUP_ADDRESSED = 1;
+    /**
+     * @hide
+     * Cipher suite: TKIP
+     */
+    public static final int CIPHER_TKIP = 2;
+    /**
+     * @hide
+     * Cipher suite: CCMP
+     */
+    public static final int CIPHER_CCMP = 3;
+
     /**
      * The detected signal level in dBm, also known as the RSSI.
      *
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 98a6ca5..674c161 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -842,36 +842,6 @@
     }
 
     /**
-     * Add a Hotspot 2.0 release 2 Management Object
-     * @param mo The MO in XML form
-     * @return -1 for failure
-     * @hide
-     */
-    public int addPasspointManagementObject(String mo) {
-        try {
-            return mService.addPasspointManagementObject(mo);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Modify a Hotspot 2.0 release 2 Management Object
-     * @param fqdn The FQDN of the service provider
-     * @param mos A List of MO definitions to be updated
-     * @return the number of nodes updated, or -1 for failure
-     * @hide
-     */
-    public int modifyPasspointManagementObject(String fqdn,
-                                               List<PasspointManagementObjectDefinition> mos) {
-        try {
-            return mService.modifyPasspointManagementObject(fqdn, mos);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Add a Passpoint configuration.  The configuration provides a credential
      * for connecting to Passpoint networks that are operated by the Passpoint
      * service provider specified in the configuration.
@@ -1628,20 +1598,6 @@
     }
 
     /**
-     * Builds a WifiConfiguration from Hotspot 2.0 MIME file.
-     * @return AP details in WifiConfiguration
-     *
-     * @hide Dont open yet
-     */
-    public WifiConfiguration buildWifiConfig(String uriString, String mimeType, byte[] data) {
-        try {
-            return mService.buildWifiConfig(uriString, mimeType, data);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Sets the Wi-Fi AP Configuration.
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      *
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 5d3ad058..ba493a0 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -32,9 +32,8 @@
 /**
  * Defines the configuration of a Aware publish session. Built using
  * {@link PublishConfig.Builder}. A publish session is created using
- * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
- * WifiAwareDiscoverySessionCallback)}
- * or updated using
+ * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+ * android.os.Handler)} or updated using
  * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}.
  *
  * @hide PROPOSED_AWARE_API
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 2a6cc93..5e14f8f 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -32,9 +32,8 @@
 /**
  * Defines the configuration of a Aware subscribe session. Built using
  * {@link SubscribeConfig.Builder}. Subscribe is done using
- * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
- * WifiAwareDiscoverySessionCallback)}
- * or
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+ * android.os.Handler)} or
  * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
  *
  * @hide PROPOSED_AWARE_API
@@ -403,8 +402,8 @@
          * Sets the match style of the subscription - how are matches from a
          * single match session (corresponding to the same publish action on the
          * peer) reported to the host (using the
-         * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
-         * ). The options are: only report the first match and ignore the rest
+         * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+         * byte[], byte[])}). The options are: only report the first match and ignore the rest
          * {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single
          * match {@link SubscribeConfig#MATCH_STYLE_ALL} (the default).
          *
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
index 2cace61..1e8dbd9 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
@@ -18,7 +18,7 @@
 
 /**
  * Base class for Aware attach callbacks. Should be extended by applications and set when calling
- * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}. These are callbacks
+ * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}. These are callbacks
  * applying to the Aware connection as a whole - not to specific publish or subscribe sessions -
  * for that see {@link WifiAwareDiscoverySessionCallback}.
  *
@@ -27,7 +27,7 @@
 public class WifiAwareAttachCallback {
     /**
      * Called when Aware attach operation
-     * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}
+     * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}
      * is completed and that we can now start discovery sessions or connections.
      *
      * @param session The Aware object on which we can execute further Aware operations - e.g.
@@ -39,7 +39,7 @@
 
     /**
      * Called when Aware attach operation
-     * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} failed.
+     * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)} failed.
      */
     public void onAttachFailed() {
         /* empty */
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
index 6232c14..072ccab 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
@@ -58,7 +58,8 @@
      * message exchange. Restricts the parameters of the
      * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
      * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
-     * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants.
+     * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])}
+     * variants.
      *
      * @return A positive integer, maximum length of byte array for Aware messaging.
      */
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
index 07f7523..e8335d1 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
@@ -32,10 +32,10 @@
  * {@link WifiAwarePublishDiscoverySession} and {@link WifiAwareSubscribeDiscoverySession}. This
  * class provides functionality common to both publish and subscribe discovery sessions:
  * <ul>
- *     <li>Sending messages: {@link #sendMessage(Object, int, byte[])} or
- *     {@link #sendMessage(Object, int, byte[], int)} methods.
+ *     <li>Sending messages: {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[])} or
+ *     {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)} methods.
  *     <li>Creating a network-specifier when requesting a Aware connection:
- *     {@link #createNetworkSpecifier(int, Object, byte[])}.
+ *     {@link #createNetworkSpecifier(int, WifiAwareManager.PeerHandle, byte[])}.
  * </ul>
  * The {@link #destroy()} method must be called to destroy discovery sessions once they are
  * no longer needed.
@@ -62,7 +62,7 @@
 
     /**
      * Return the maximum permitted retry count when sending messages using
-     * {@link #sendMessage(Object, int, byte[], int)}.
+     * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}.
      *
      * @return Maximum retry count when sending messages.
      */
@@ -139,21 +139,24 @@
     /**
      * Sends a message to the specified destination. Aware messages are transmitted in the context
      * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} event.
      * <p>
      *     Aware messages are not guaranteed delivery. Callbacks on
      *     {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
-     *     (possibly after several retries) -
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
+     *     failed (possibly after several retries) -
      *     {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
      * <p>
      *     The peer will get a callback indicating a message was received using
-     *     {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     *     byte[])}.
      *
      * @param peerHandle The peer's handle for the message. Must be a result of an
-     *        {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
-     *        or
-     *        {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     * byte[])} events.
      * @param messageId An arbitrary integer used by the caller to identify the message. The same
      *            integer ID will be returned in the callbacks indicating message send success or
      *            failure. The {@code messageId} is not used internally by the Aware service - it
@@ -164,8 +167,8 @@
      *            (note: no retransmissions are attempted in other failure cases). A value of 0
      *            indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}.
      */
-    public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message,
-            int retryCount) {
+    public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId,
+            @Nullable byte[] message, int retryCount) {
         if (mTerminated) {
             Log.w(TAG, "sendMessage: called on terminated session");
             return;
@@ -183,37 +186,43 @@
     /**
      * Sends a message to the specified destination. Aware messages are transmitted in the context
      * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} event.
      * <p>
      *     Aware messages are not guaranteed delivery. Callbacks on
      *     {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
-     *     (possibly after several retries) -
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission
+     *     failed (possibly after several retries) -
      *     {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
      * <p>
-     *     The peer will get a callback indicating a message was received using
-     *     {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
-     * Equivalent to {@link #sendMessage(Object, int, byte[], int)} with a {@code retryCount} of
-     * 0.
+     * The peer will get a callback indicating a message was received using
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     * byte[])}.
+     * Equivalent to {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}
+     * with a {@code retryCount} of 0.
      *
      * @param peerHandle The peer's handle for the message. Must be a result of an
-     *        {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
-     *        or
-     *        {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     * byte[])} events.
      * @param messageId An arbitrary integer used by the caller to identify the message. The same
      *            integer ID will be returned in the callbacks indicating message send success or
      *            failure. The {@code messageId} is not used internally by the Aware service - it
      *                  can be arbitrary and non-unique.
      * @param message The message to be transmitted.
      */
-    public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message) {
+    public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId,
+            @Nullable byte[] message) {
         sendMessage(peerHandle, messageId, message, 0);
     }
 
     /**
      * Start a ranging operation with the specified peers. The peer IDs are obtained from an
-     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
-     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} operation - can
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     * byte[])} operation - can
      * only range devices which are part of an ongoing discovery session.
      *
      * @param params   RTT parameters - each corresponding to a specific peer ID (the array sizes
@@ -256,11 +265,12 @@
      * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
      * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
      * @param peerHandle The peer's handle obtained through
-     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
-     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. On a RESPONDER
-     *               this value is used to gate the acceptance of a connection request from only
-     *               that peer. A RESPONDER may specified a null - indicating that it will accept
-     *               connection requests from any device.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
+     * byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
+     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
+     *                   from only that peer. A RESPONDER may specified a null - indicating that
+     *                   it will accept connection requests from any device.
      * @param token An arbitrary token (message) to be used to match connection initiation request
      *              to a responder setup. A RESPONDER is set up with a {@code token} which must
      *              be matched by the token provided by the INITIATOR. A null token is permitted
@@ -274,7 +284,7 @@
      * [or other varieties of that API].
      */
     public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
-            @Nullable Object peerHandle, @Nullable byte[] token) {
+            @Nullable WifiAwareManager.PeerHandle peerHandle, @Nullable byte[] token) {
         if (mTerminated) {
             Log.w(TAG, "createNetworkSpecifier: called on terminated session");
             return null;
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
index 9dfa24f..6331c9c 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
@@ -26,11 +26,10 @@
  * Base class for Aware session events callbacks. Should be extended by
  * applications wanting notifications. The callbacks are set when a
  * publish or subscribe session is created using
- * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
- * WifiAwareDiscoverySessionCallback)}
- * or
- * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
- * WifiAwareDiscoverySessionCallback)} .
+ * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+ * android.os.Handler)} or
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+ * android.os.Handler)}.
  * <p>
  * A single callback is set at session creation - it cannot be replaced.
  *
@@ -62,9 +61,8 @@
 
     /**
      * Called when a publish operation is started successfully in response to a
-     * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
-     * WifiAwareDiscoverySessionCallback)}
-     * operation.
+     * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+     * android.os.Handler)} operation.
      *
      * @param session The {@link WifiAwarePublishDiscoverySession} used to control the
      *            discovery session.
@@ -75,9 +73,8 @@
 
     /**
      * Called when a subscribe operation is started successfully in response to a
-     * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
-     * WifiAwareDiscoverySessionCallback)}
-     * operation.
+     * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+     * android.os.Handler)} operation.
      *
      * @param session The {@link WifiAwareSubscribeDiscoverySession} used to control the
      *            discovery session.
@@ -98,12 +95,10 @@
 
     /**
      * Called when a publish or subscribe discovery session cannot be created:
-     * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
-     * WifiAwareDiscoverySessionCallback)}
-     * or
-     * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
-     * WifiAwareDiscoverySessionCallback)},
-     * or when a configuration update fails:
+     * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+     * android.os.Handler)} or
+     * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+     * android.os.Handler)}, or when a configuration update fails:
      * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or
      * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
      * <p>
@@ -138,13 +133,14 @@
      * @param matchFilter The filter (Tx on advertiser and Rx on listener) which
      *            resulted in this service discovery.
      */
-    public void onServiceDiscovered(Object peerHandle, byte[] serviceSpecificInfo,
-            byte[] matchFilter) {
+    public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle,
+            byte[] serviceSpecificInfo, byte[] matchFilter) {
         /* empty */
     }
 
     /**
-     * Called in response to {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])}
+     * Called in response to
+     * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])}
      * when a message is transmitted successfully - i.e. when it was received successfully by the
      * peer (corresponds to an ACK being received).
      * <p>
@@ -154,18 +150,18 @@
      *
      * @param messageId The arbitrary message ID specified when sending the message.
      */
-    public void onMessageSent(@SuppressWarnings("unused") int messageId) {
+    public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) {
         /* empty */
     }
 
     /**
      * Called when message transmission fails - when no ACK is received from the peer.
      * Retries when ACKs are not received are done by hardware, MAC, and in the Aware stack (using
-     * the {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)} method) -
-     * this event is received after all retries are exhausted.
+     * the {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int,
+     * byte[], int)} method) - this event is received after all retries are exhausted.
      * <p>
      * Note that either this callback or
-     * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)} will be received
+     * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)} will be received
      * - never both.
      *
      * @param messageId The arbitrary message ID specified when sending the message.
@@ -176,13 +172,14 @@
 
     /**
      * Called when a message is received from a discovery session peer - in response to the
-     * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} or
-     * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)}.
+     * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int,
+     * byte[])} or {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle,
+     * int, byte[], int)}.
      *
      * @param peerHandle An opaque handle to the peer matching our discovery operation.
      * @param message A byte array containing the message.
      */
-    public void onMessageReceived(Object peerHandle, byte[] message) {
+    public void onMessageReceived(WifiAwareManager.PeerHandle peerHandle, byte[] message) {
         /* empty */
     }
 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 10b70ab..a34ef47 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -56,14 +56,14 @@
  * The class provides access to:
  * <ul>
  * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(Handler, WifiAwareAttachCallback)}.
+ * {@link #attach(WifiAwareAttachCallback, Handler)}.
  * <li>Create discovery sessions (publish or subscribe sessions). Refer to
- * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} and
- * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, WifiAwareDiscoverySessionCallback)}.
+ * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} and
+ * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, Handler)}.
  * <li>Create a Aware network specifier to be used with
  * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
  * to set-up a Aware connection with a peer. Refer to
- * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])} and
+ * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])} and
  * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
  * </ul>
  * <p>
@@ -73,7 +73,7 @@
  *     broadcast. Note that this broadcast is not sticky - you should register for it and then
  *     check the above API to avoid a race condition.
  * <p>
- *     An application must use {@link #attach(Handler, WifiAwareAttachCallback)} to initialize a
+ *     An application must use {@link #attach(WifiAwareAttachCallback, Handler)} to initialize a
  *     Aware cluster - before making any other Aware operation. Aware cluster membership is a
  *     device-wide operation - the API guarantees that the device is in a cluster or joins a
  *     Aware cluster (or starts one if none can be found). Information about attach success (or
@@ -86,12 +86,11 @@
  *     application detaches.
  * <p>
  *     Once a Aware attach is confirmed use the
- *     {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)}
+ *     {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)}
  *     or
- *     {@link WifiAwareSession#subscribe(Handler, SubscribeConfig,
- *     WifiAwareDiscoverySessionCallback)}
- *     to create publish or subscribe Aware discovery sessions. Events are called on the provided
- *     callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the
+ *     {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback,
+ *     Handler)} to create publish or subscribe Aware discovery sessions. Events are called on the
+ *     provided callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the
  *     {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}
  *     and
  *     {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(
@@ -102,7 +101,7 @@
  *     the session {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} and
  *     {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
  *     also be used to send messages using the
- *     {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} APIs. When an
+ *     {@link WifiAwareDiscoveryBaseSession#sendMessage(PeerHandle, int, byte[])} APIs. When an
  *     application is finished with a discovery session it <b>must</b> terminate it using the
  *     {@link WifiAwareDiscoveryBaseSession#destroy()} API.
  * <p>
@@ -115,7 +114,7 @@
  *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
  *        <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
  *        {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or
- *        {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
+ *        {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])}.
  *    </ul>
  *
  * @hide PROPOSED_AWARE_API
@@ -225,7 +224,7 @@
      * Connection creation role is that of INITIATOR. Used to create a network specifier string
      * when requesting a Aware network.
      *
-     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
+     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])
      * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
      */
     public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
@@ -234,7 +233,7 @@
      * Connection creation role is that of RESPONDER. Used to create a network specifier string
      * when requesting a Aware network.
      *
-     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
+     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])
      * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
      */
     public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
@@ -326,13 +325,13 @@
      * then this function will simply indicate success immediately using the same {@code
      * attachCallback}.
      *
+     * @param attachCallback A callback for attach events, extended from
+     * {@link WifiAwareAttachCallback}.
      * @param handler The Handler on whose thread to execute the callbacks of the {@code
      * attachCallback} object. If a null is provided then the application's main thread will be
      *                used.
-     * @param attachCallback A callback for attach events, extended from
-     * {@link WifiAwareAttachCallback}.
      */
-    public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback) {
+    public void attach(@NonNull WifiAwareAttachCallback attachCallback, @Nullable Handler handler) {
         attach(handler, null, attachCallback, null);
     }
 
@@ -352,20 +351,21 @@
      * on startup and whenever it is updated (it is randomized at regular intervals for privacy).
      * The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
      * permission to execute this attach request. Otherwise, use the
-     * {@link #attach(Handler, WifiAwareAttachCallback)} version. Note that aside from permission
+     * {@link #attach(WifiAwareAttachCallback, Handler)} version. Note that aside from permission
      * requirements this listener will wake up the host at regular intervals causing higher power
      * consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
      *
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
-     *                application's main thread will be used.
      * @param attachCallback A callback for attach events, extended from
      * {@link WifiAwareAttachCallback}.
      * @param identityChangedListener A listener for changed identity, extended from
      * {@link WifiAwareIdentityChangedListener}.
+     * @param handler The Handler on whose thread to execute the callbacks of the {@code
+     * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
+     *                application's main thread will be used.
      */
-    public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback,
-            @NonNull WifiAwareIdentityChangedListener identityChangedListener) {
+    public void attach(@NonNull WifiAwareAttachCallback attachCallback,
+            @NonNull WifiAwareIdentityChangedListener identityChangedListener,
+            @Nullable Handler handler) {
         attach(handler, null, attachCallback, identityChangedListener);
     }
 
@@ -481,7 +481,7 @@
     }
 
     /** @hide */
-    public void sendMessage(int clientId, int sessionId, Object peerHandle, byte[] message,
+    public void sendMessage(int clientId, int sessionId, PeerHandle peerHandle, byte[] message,
             int messageId, int retryCount) {
         if (peerHandle == null) {
             throw new IllegalArgumentException(
@@ -490,13 +490,13 @@
 
         if (VDBG) {
             Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId
-                    + ", peerHandle=" + ((OpaquePeerHandle) peerHandle).peerId + ", messageId="
+                    + ", peerHandle=" + peerHandle.peerId + ", messageId="
                     + messageId + ", retryCount=" + retryCount);
         }
 
         try {
-            mService.sendMessage(clientId, sessionId, ((OpaquePeerHandle) peerHandle).peerId,
-                    message, messageId, retryCount);
+            mService.sendMessage(clientId, sessionId, peerHandle.peerId, message, messageId,
+                    retryCount);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -524,12 +524,12 @@
     }
 
     /** @hide */
-    public String createNetworkSpecifier(int clientId, int role, int sessionId, Object peerHandle,
-            byte[] token) {
+    public String createNetworkSpecifier(int clientId, int role, int sessionId,
+            PeerHandle peerHandle, byte[] token) {
         if (VDBG) {
             Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
-                    + ", peerHandle=" + ((peerHandle == null) ? peerHandle
-                    : ((OpaquePeerHandle) peerHandle).peerId) + ", token=" + token);
+                    + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
+                    + ", token=" + token);
         }
 
         int type;
@@ -569,7 +569,7 @@
             json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId);
             json.put(NETWORK_SPECIFIER_KEY_SESSION_ID, sessionId);
             if (peerHandle != null) {
-                json.put(NETWORK_SPECIFIER_KEY_PEER_ID, ((OpaquePeerHandle) peerHandle).peerId);
+                json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId);
             }
             if (token != null) {
                 json.put(NETWORK_SPECIFIER_KEY_TOKEN,
@@ -876,18 +876,18 @@
                             break;
                         case CALLBACK_MATCH:
                             mOriginalCallback.onServiceDiscovered(
-                                    new OpaquePeerHandle(msg.arg1),
+                                    new PeerHandle(msg.arg1),
                                     msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
                                     msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2));
                             break;
                         case CALLBACK_MESSAGE_SEND_SUCCESS:
-                            mOriginalCallback.onMessageSent(msg.arg1);
+                            mOriginalCallback.onMessageSendSucceeded(msg.arg1);
                             break;
                         case CALLBACK_MESSAGE_SEND_FAIL:
                             mOriginalCallback.onMessageSendFailed(msg.arg1);
                             break;
                         case CALLBACK_MESSAGE_RECEIVED:
-                            mOriginalCallback.onMessageReceived(new OpaquePeerHandle(msg.arg1),
+                            mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1),
                                     (byte[]) msg.obj);
                             break;
                     }
@@ -1019,12 +1019,14 @@
         }
     }
 
-    /** @hide */
-    public static class OpaquePeerHandle {
-        public OpaquePeerHandle(int peerId) {
+    /** @hide PROPOSED_AWARE_API */
+    public static class PeerHandle {
+        /** @hide */
+        public PeerHandle(int peerId) {
             this.peerId = peerId;
         }
 
+        /** @hide */
         public int peerId;
     }
 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
index 610a92c..68786d1 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
@@ -21,9 +21,8 @@
 
 /**
  * A class representing a Aware publish session. Created when
- * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
- * WifiAwareDiscoverySessionCallback)}
- * is called and a discovery session is created and returned in
+ * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback,
+ * android.os.Handler)} is called and a discovery session is created and returned in
  * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}. See
  * baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}. This
  * object allows updating an existing/running publish discovery session using
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 357bd43..acb60a4 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -65,7 +65,7 @@
      * session-wide destroy.
      * <p>
      * An application may re-attach after a destroy using
-     * {@link WifiAwareManager#attach(Handler, WifiAwareAttachCallback)} .
+     * {@link WifiAwareManager#attach(WifiAwareAttachCallback, Handler)} .
      */
     public void destroy() {
         WifiAwareManager mgr = mMgr.get();
@@ -116,15 +116,15 @@
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
      * permission to start a publish discovery session.
      *
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * callback} object. If a null is provided then the application's main thread will be used.
      * @param publishConfig The {@link PublishConfig} specifying the
      *            configuration of the requested publish session.
      * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
      *                 session event callbacks.
+     * @param handler The Handler on whose thread to execute the callbacks of the {@code
+     * callback} object. If a null is provided then the application's main thread will be used.
      */
-    public void publish(@Nullable Handler handler, @NonNull PublishConfig publishConfig,
-            @NonNull WifiAwareDiscoverySessionCallback callback) {
+    public void publish(@NonNull PublishConfig publishConfig,
+            @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.e(TAG, "publish: called post GC on WifiAwareManager");
@@ -162,15 +162,15 @@
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
      * permission to start a subscribe discovery session.
      *
-     * @param handler The Handler on whose thread to execute the callbacks of the {@code
-     * callback} object. If a null is provided then the application's main thread will be used.
      * @param subscribeConfig The {@link SubscribeConfig} specifying the
      *            configuration of the requested subscribe session.
      * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
      *                 session event callbacks.
+     * @param handler The Handler on whose thread to execute the callbacks of the {@code
+     * callback} object. If a null is provided then the application's main thread will be used.
      */
-    public void subscribe(@Nullable Handler handler, @NonNull SubscribeConfig subscribeConfig,
-            @NonNull WifiAwareDiscoverySessionCallback callback) {
+    public void subscribe(@NonNull SubscribeConfig subscribeConfig,
+            @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.e(TAG, "publish: called post GC on WifiAwareManager");
@@ -193,7 +193,8 @@
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
      *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
      *     when using Aware discovery use the alternative network specifier method -
-     *     {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
+     *     {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int,
+     *     WifiAwareManager.PeerHandle, byte[])}.
      *
      * @param role  The role of this device:
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
index 7c48f54..a0ec809 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
@@ -21,8 +21,8 @@
 
 /**
  * A class representing a Aware subscribe session. Created when
- * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
- * WifiAwareDiscoverySessionCallback)}
+ * {@link WifiAwareSession#subscribe(SubscribeConfig,
+ * WifiAwareDiscoverySessionCallback, android.os.Handler)}
  * is called and a discovery session is created and returned in
  * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(WifiAwareSubscribeDiscoverySession)}.
  * See baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}.
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 18aae53..a62a0fb 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -61,6 +61,21 @@
                     credential.equals(that.credential));
     }
 
+    /**
+     * Validate the configuration data.
+     *
+     * @return true on success or false on failure
+     */
+    public boolean validate() {
+        if (homeSp == null || !homeSp.validate()) {
+            return false;
+        }
+        if (credential == null || !credential.validate()) {
+            return false;
+        }
+        return true;
+    }
+
     public static final Creator<PasspointConfiguration> CREATOR =
         new Creator<PasspointConfiguration>() {
             @Override
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index 92dbd8a..57e65eb 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -16,15 +16,21 @@
 
 package android.net.wifi.hotspot2.pps;
 
+import android.net.wifi.EAPConstants;
 import android.net.wifi.ParcelUtil;
 import android.os.Parcelable;
 import android.os.Parcel;
 import android.text.TextUtils;
+import android.util.Log;
 
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Class representing Credential subtree in the PerProviderSubscription (PPS)
@@ -40,6 +46,14 @@
  * @hide
  */
 public final class Credential implements Parcelable {
+    private static final String TAG = "Credential";
+
+    /**
+     * Max string length for realm.  Refer to Credential/Realm node in Hotspot 2.0 Release 2
+     * Technical Specification Section 9.1 for more info.
+     */
+    private static final int MAX_REALM_LENGTH = 253;
+
     /**
      * The realm associated with this credential.  It will be used to determine
      * if this credential can be used to authenticate with a given hotspot by
@@ -53,6 +67,26 @@
      */
     public static final class UserCredential implements Parcelable {
         /**
+         * Maximum string length for username.  Refer to Credential/UsernamePassword/Username
+         * node in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
+         */
+        private static final int MAX_USERNAME_LENGTH = 63;
+
+        /**
+         * Maximum string length for password.  Refer to Credential/UsernamePassword/Password
+         * in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
+         */
+        private static final int MAX_PASSWORD_LENGTH = 255;
+
+        /**
+         * Supported Non-EAP inner methods.  Refer to
+         * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical
+         * Specification Section 9.1 for more info.
+         */
+        private static final Set<String> SUPPORTED_AUTH =
+                new HashSet<String>(Arrays.asList("PAP", "CHAP", "MS-CHAP", "MS-CHAP-V2"));
+
+        /**
          * Username of the credential.
          */
         public String username = null;
@@ -104,6 +138,44 @@
                     TextUtils.equals(nonEapInnerMethod, that.nonEapInnerMethod);
         }
 
+        /**
+         * Validate the configuration data.
+         *
+         * @return true on success or false on failure
+         */
+        public boolean validate() {
+            if (TextUtils.isEmpty(username)) {
+                Log.d(TAG, "Missing username");
+                return false;
+            }
+            if (username.length() > MAX_USERNAME_LENGTH) {
+                Log.d(TAG, "username exceeding maximum length: " + username.length());
+                return false;
+            }
+
+            if (TextUtils.isEmpty(password)) {
+                Log.d(TAG, "Missing password");
+                return false;
+            }
+            if (password.length() > MAX_PASSWORD_LENGTH) {
+                Log.d(TAG, "password exceeding maximum length: " + password.length());
+                return false;
+            }
+
+            // Only supports EAP-TTLS for user credential.
+            if (eapType != EAPConstants.EAP_TTLS) {
+                Log.d(TAG, "Invalid EAP Type for user credential: " + eapType);
+                return false;
+            }
+
+            // Verify Non-EAP inner method for EAP-TTLS.
+            if (!SUPPORTED_AUTH.contains(nonEapInnerMethod)) {
+                Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + nonEapInnerMethod);
+                return false;
+            }
+            return true;
+        }
+
         public static final Creator<UserCredential> CREATOR =
             new Creator<UserCredential>() {
                 @Override
@@ -125,12 +197,22 @@
     public UserCredential userCredential = null;
 
     /**
-     * Certificate based credential.
+     * Certificate based credential.  This is used for EAP-TLS.
      * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree.
      */
     public static final class CertificateCredential implements Parcelable {
         /**
-         * Certificate type. Valid values are "802.1ar" and "x509v3".
+         * Supported certificate types.
+         */
+        private static final String CERT_TYPE_X509V3 = "x509v3";
+
+        /**
+         * Certificate SHA-256 fingerprint length.
+         */
+        private static final int CERT_SHA256_FINGER_PRINT_LENGTH = 32;
+
+        /**
+         * Certificate type.
          */
         public String certType = null;
 
@@ -164,6 +246,24 @@
                     Arrays.equals(certSha256FingerPrint, that.certSha256FingerPrint);
         }
 
+        /**
+         * Validate the configuration data.
+         *
+         * @return true on success or false on failure
+         */
+        public boolean validate() {
+            if (!TextUtils.equals(CERT_TYPE_X509V3, certType)) {
+                Log.d(TAG, "Unsupported certificate type: " + certType);
+                return false;
+            }
+            if (certSha256FingerPrint == null ||
+                    certSha256FingerPrint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
+                Log.d(TAG, "Invalid SHA-256 fingerprint");
+                return false;
+            }
+            return true;
+        }
+
         public static final Creator<CertificateCredential> CREATOR =
             new Creator<CertificateCredential>() {
                 @Override
@@ -188,7 +288,14 @@
      */
     public static final class SimCredential implements Parcelable {
         /**
-         * International Mobile device Subscriber Identity.
+         * Maximum string length for IMSI.
+         */
+        public static final int MAX_IMSI_LENGTH = 15;
+
+        /**
+         * International Mobile Subscriber Identity, is used to identify the user
+         * of a cellular network and is a unique identification associated with all
+         * cellular networks
          */
         public String imsi = null;
 
@@ -225,6 +332,26 @@
             dest.writeInt(eapType);
         }
 
+        /**
+         * Validate the configuration data.
+         *
+         * @return true on success or false on failure
+         */
+        public boolean validate() {
+            // Note: this only validate the format of IMSI string itself.  Additional verification
+            // will be done by WifiService at the time of provisioning to verify against the IMSI
+            // of the SIM card installed in the device.
+            if (!verifyImsi()) {
+                return false;
+            }
+            if (eapType != EAPConstants.EAP_SIM && eapType != EAPConstants.EAP_AKA &&
+                    eapType != EAPConstants.EAP_AKA_PRIME) {
+                Log.d(TAG, "Invalid EAP Type for SIM credential: " + eapType);
+                return false;
+            }
+            return true;
+        }
+
         public static final Creator<SimCredential> CREATOR =
             new Creator<SimCredential>() {
                 @Override
@@ -240,6 +367,43 @@
                     return new SimCredential[size];
                 }
             };
+
+        /**
+         * Verify the IMSI (International Mobile Subscriber Identity) string.  The string
+         * should contain zero or more numeric digits, and might ends with a "*" for prefix
+         * matching.
+         *
+         * @return true if IMSI is valid, false otherwise.
+         */
+        private boolean verifyImsi() {
+            if (TextUtils.isEmpty(imsi)) {
+                Log.d(TAG, "Missing IMSI");
+                return false;
+            }
+            if (imsi.length() > MAX_IMSI_LENGTH) {
+                Log.d(TAG, "IMSI exceeding maximum length: " + imsi.length());
+                return false;
+            }
+
+            // Locate the first non-digit character.
+            int nonDigit;
+            char stopChar = '\0';
+            for (nonDigit = 0; nonDigit < imsi.length(); nonDigit++) {
+                stopChar = imsi.charAt(nonDigit);
+                if (stopChar < '0' || stopChar > '9') {
+                    break;
+                }
+            }
+
+            if (nonDigit == imsi.length()) {
+                return true;
+            }
+            else if (nonDigit == imsi.length()-1 && stopChar == '*') {
+                // Prefix matching.
+                return true;
+            }
+            return false;
+        }
     }
     public SimCredential simCredential = null;
 
@@ -296,6 +460,42 @@
                 isPrivateKeyEquals(clientPrivateKey, that.clientPrivateKey);
     }
 
+    /**
+     * Validate the configuration data.
+     *
+     * @return true on success or false on failure
+     */
+    public boolean validate() {
+        if (TextUtils.isEmpty(realm)) {
+            Log.d(TAG, "Missing realm");
+            return false;
+        }
+        if (realm.length() > MAX_REALM_LENGTH) {
+            Log.d(TAG, "realm exceeding maximum length: " + realm.length());
+            return false;
+        }
+
+        // Verify the credential.
+        if (userCredential != null) {
+            if (!verifyUserCredential()) {
+                return false;
+            }
+        } else if (certCredential != null) {
+            if (!verifyCertCredential()) {
+                return false;
+            }
+        } else if (simCredential != null) {
+            if (!verifySimCredential()) {
+                return false;
+            }
+        } else {
+            Log.d(TAG, "Missing required credential");
+            return false;
+        }
+
+        return true;
+    }
+
     public static final Creator<Credential> CREATOR =
         new Creator<Credential>() {
             @Override
@@ -317,6 +517,91 @@
             }
         };
 
+    /**
+     * Verify user credential.
+     *
+     * @return true if user credential is valid, false otherwise.
+     */
+    private boolean verifyUserCredential() {
+        if (userCredential == null) {
+            Log.d(TAG, "Missing user credential");
+            return false;
+        }
+        if (certCredential != null || simCredential != null) {
+            Log.d(TAG, "Contained more than one type of credential");
+            return false;
+        }
+        if (!userCredential.validate()) {
+            return false;
+        }
+        if (caCertificate == null) {
+            Log.d(TAG, "Missing CA Certificate for user credential");
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Verify certificate credential, which is used for EAP-TLS.  This will verify
+     * that the necessary client key and certificates are provided.
+     *
+     * @return true if certificate credential is valid, false otherwise.
+     */
+    private boolean verifyCertCredential() {
+        if (certCredential == null) {
+            Log.d(TAG, "Missing certificate credential");
+            return false;
+        }
+        if (userCredential != null || simCredential != null) {
+            Log.d(TAG, "Contained more than one type of credential");
+            return false;
+        }
+
+        if (!certCredential.validate()) {
+            return false;
+        }
+
+        // Verify required key and certificates for certificate credential.
+        if (caCertificate == null) {
+            Log.d(TAG, "Missing CA Certificate for certificate credential");
+            return false;
+        }
+        if (clientPrivateKey == null) {
+            Log.d(TAG, "Missing client private key for certificate credential");
+            return false;
+        }
+        try {
+            // Verify SHA-256 fingerprint for client certificate.
+            if (!verifySha256Fingerprint(clientCertificateChain,
+                    certCredential.certSha256FingerPrint)) {
+                Log.d(TAG, "SHA-256 fingerprint mismatch");
+                return false;
+            }
+        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
+            Log.d(TAG, "Failed to verify SHA-256 fingerprint: " + e.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Verify SIM credential.
+     *
+     * @return true if SIM credential is valid, false otherwise.
+     */
+    private boolean verifySimCredential() {
+        if (simCredential == null) {
+            Log.d(TAG, "Missing SIM credential");
+            return false;
+        }
+        if (userCredential != null || certCredential != null) {
+            Log.d(TAG, "Contained more than one type of credential");
+            return false;
+        }
+        return simCredential.validate();
+    }
+
     private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
         if (key1 == null && key2 == null) {
             return true;
@@ -373,4 +658,31 @@
 
         return true;
     }
+
+    /**
+     * Verify that the digest for a certificate in the certificate chain matches expected
+     * fingerprint.  The certificate that matches the fingerprint is the client certificate.
+     *
+     * @param certChain Chain of certificates
+     * @param expectedFingerprint The expected SHA-256 digest of the client certificate
+     * @return true if the certificate chain contains a matching certificate, false otherwise
+     * @throws NoSuchAlgorithmException
+     * @throws CertificateEncodingException
+     */
+    private static boolean verifySha256Fingerprint(X509Certificate[] certChain,
+                                                   byte[] expectedFingerprint)
+            throws NoSuchAlgorithmException, CertificateEncodingException {
+        if (certChain == null) {
+            return false;
+        }
+        MessageDigest digester = MessageDigest.getInstance("SHA-256");
+        for (X509Certificate certificate : certChain) {
+            digester.reset();
+            byte[] fingerprint = digester.digest(certificate.getEncoded());
+            if (Arrays.equals(expectedFingerprint, fingerprint)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
index 2acc8be..5837c06 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
@@ -19,6 +19,7 @@
 import android.os.Parcelable;
 import android.os.Parcel;
 import android.text.TextUtils;
+import android.util.Log;
 
 import java.util.Arrays;
 
@@ -34,6 +35,8 @@
  * @hide
  */
 public final class HomeSP implements Parcelable {
+    private static final String TAG = "HomeSP";
+
     /**
      * FQDN (Fully Qualified Domain Name) of this home service provider.
      */
@@ -77,6 +80,23 @@
                 Arrays.equals(roamingConsortiumOIs, that.roamingConsortiumOIs);
     }
 
+    /**
+     * Validate HomeSP data.
+     *
+     * @return true on success or false on failure
+     */
+    public boolean validate() {
+        if (TextUtils.isEmpty(fqdn)) {
+            Log.d(TAG, "Missing FQDN");
+            return false;
+        }
+        if (TextUtils.isEmpty(friendlyName)) {
+            Log.d(TAG, "Missing friendly name");
+            return false;
+        }
+        return true;
+    }
+
     public static final Creator<HomeSP> CREATOR =
         new Creator<HomeSP>() {
             @Override
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index be11f0e..b4a3acf 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -16,8 +16,10 @@
 
 package android.net.wifi.hotspot2;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.net.wifi.EAPConstants;
 import android.net.wifi.hotspot2.pps.Credential;
 import android.net.wifi.hotspot2.pps.HomeSP;
 import android.os.Parcel;
@@ -44,7 +46,9 @@
         cred.realm = "realm";
         cred.userCredential = null;
         cred.certCredential = null;
-        cred.simCredential = null;
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_SIM;
         cred.caCertificate = null;
         cred.clientCertificateChain = null;
         cred.clientPrivateKey = null;
@@ -61,11 +65,20 @@
         assertTrue(readConfig.equals(writeConfig));
     }
 
+    /**
+     * Verify parcel read/write for a default configuration.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithDefault() throws Exception {
         verifyParcel(new PasspointConfiguration());
     }
 
+    /**
+     * Verify parcel read/write for a configuration that contained both HomeSP and Credential.
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithHomeSPAndCredential() throws Exception {
         PasspointConfiguration config = new PasspointConfiguration();
@@ -74,6 +87,11 @@
         verifyParcel(config);
     }
 
+    /**
+     * Verify parcel read/write for a configuration that contained only HomeSP.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithHomeSPOnly() throws Exception {
         PasspointConfiguration config = new PasspointConfiguration();
@@ -81,10 +99,63 @@
         verifyParcel(config);
     }
 
+    /**
+     * Verify parcel read/write for a configuration that contained only Credential.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithCredentialOnly() throws Exception {
         PasspointConfiguration config = new PasspointConfiguration();
         config.credential = createCredential();
         verifyParcel(config);
     }
+
+    /**
+     * Verify that a default/empty configuration is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateDefaultConfig() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        assertFalse(config.validate());
+    }
+
+    /**
+     * Verify that a configuration without Credential is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateConfigWithoutCredential() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.homeSp = createHomeSp();
+        assertFalse(config.validate());
+    }
+
+    /**
+     * Verify that a a configuration without HomeSP is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateConfigWithoutHomeSp() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.credential = createCredential();
+        assertFalse(config.validate());
+    }
+
+    /**
+     * Verify a valid configuration.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateValidConfig() throws Exception {
+        PasspointConfiguration config = new PasspointConfiguration();
+        config.homeSp = createHomeSp();
+        config.credential = createCredential();
+        assertTrue(config.validate());
+    }
 }
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index 68ac4ef..223aa52 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -16,14 +16,19 @@
 
 package android.net.wifi.hotspot2.pps;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import android.net.wifi.EAPConstants;
 import android.net.wifi.FakeKeys;
 import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
 
+import java.security.MessageDigest;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 
 import org.junit.Test;
 
@@ -52,15 +57,15 @@
     private static Credential createCredentialWithCertificateCredential() {
         Credential.CertificateCredential certCred = new Credential.CertificateCredential();
         certCred.certType = "x509v3";
-        certCred.certSha256FingerPrint = new byte[256];
+        certCred.certSha256FingerPrint = new byte[32];
         return createCredential(null, certCred, null, FakeKeys.CA_CERT0,
                 new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
     }
 
     private static Credential createCredentialWithSimCredential() {
         Credential.SimCredential simCred = new Credential.SimCredential();
-        simCred.imsi = "imsi";
-        simCred.eapType = 1;
+        simCred.imsi = "1234*";
+        simCred.eapType = EAPConstants.EAP_SIM;
         return createCredential(null, null, simCred, null, null, null);
     }
 
@@ -68,7 +73,7 @@
         Credential.UserCredential userCred = new Credential.UserCredential();
         userCred.username = "username";
         userCred.password = "password";
-        userCred.eapType = 1;
+        userCred.eapType = EAPConstants.EAP_TTLS;
         userCred.nonEapInnerMethod = "MS-CHAP";
         return createCredential(userCred, null, null, FakeKeys.CA_CERT0,
                 new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
@@ -83,23 +88,386 @@
         assertTrue(readCred.equals(writeCred));
     }
 
+    /**
+     * Verify parcel read/write for a default/empty credential.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithDefault() throws Exception {
         verifyParcel(new Credential());
     }
 
+    /**
+     * Verify parcel read/write for a certificate credential.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithCertificateCredential() throws Exception {
         verifyParcel(createCredentialWithCertificateCredential());
     }
 
+    /**
+     * Verify parcel read/write for a SIM credential.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithSimCredential() throws Exception {
         verifyParcel(createCredentialWithSimCredential());
     }
 
+    /**
+     * Verify parcel read/write for an user credential.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithUserCredential() throws Exception {
         verifyParcel(createCredentialWithUserCredential());
     }
-}
+
+    /**
+     * Verify a valid user credential.
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredential() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertTrue(cred.validate());
+    }
+
+    /**
+     * Verify that an user credential without CA Certificate is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithoutCaCert() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that an user credential with EAP type other than EAP-TTLS is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithEapTls() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertFalse(cred.validate());
+    }
+
+
+    /**
+     * Verify that an user credential without realm is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithoutRealm() throws Exception {
+        Credential cred = new Credential();
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that an user credential without username is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithoutUsername() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that an user credential without password is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithoutPassword() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that an user credential without auth methoh (non-EAP inner method) is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateUserCredentialWithoutAuthMethod() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify a certificate credential. CA Certificate, client certificate chain,
+     * and client private key are all required.  Also the digest for client
+     * certificate must match the fingerprint specified in the certificate credential.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateCertCredential() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup certificate credential.
+        cred.certCredential = new Credential.CertificateCredential();
+        cred.certCredential.certType = "x509v3";
+        cred.certCredential.certSha256FingerPrint =
+                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
+        // Setup certificates and private key.
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
+        cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+        assertTrue(cred.validate());
+    }
+
+    /**
+     * Verify that an certificate credential without CA Certificate is invalid.
+     *
+     * @throws Exception
+     */
+    public void validateCertCredentialWithoutCaCert() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup certificate credential.
+        cred.certCredential = new Credential.CertificateCredential();
+        cred.certCredential.certType = "x509v3";
+        cred.certCredential.certSha256FingerPrint =
+                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
+        // Setup certificates and private key.
+        cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
+        cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a certificate credential without client certificate chain is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateCertCredentialWithoutClientCertChain() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup certificate credential.
+        cred.certCredential = new Credential.CertificateCredential();
+        cred.certCredential.certType = "x509v3";
+        cred.certCredential.certSha256FingerPrint =
+                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
+        // Setup certificates and private key.
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a certificate credential without client private key is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup certificate credential.
+        cred.certCredential = new Credential.CertificateCredential();
+        cred.certCredential.certType = "x509v3";
+        cred.certCredential.certSha256FingerPrint =
+                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
+        // Setup certificates and private key.
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a certificate credential with mismatch client certificate fingerprint
+     * is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateCertCredentialWithMismatchFingerprint() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup certificate credential.
+        cred.certCredential = new Credential.CertificateCredential();
+        cred.certCredential.certType = "x509v3";
+        cred.certCredential.certSha256FingerPrint = new byte[32];
+        Arrays.fill(cred.certCredential.certSha256FingerPrint, (byte)0);
+        // Setup certificates and private key.
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
+        cred.clientPrivateKey = FakeKeys.RSA_KEY1;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify a SIM credential using EAP-SIM.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithEapSim() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_SIM;
+        assertTrue(cred.validate());
+    }
+
+    /**
+     * Verify a SIM credential using EAP-AKA.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithEapAka() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_AKA;
+        assertTrue(cred.validate());
+    }
+
+    /**
+     * Verify a SIM credential using EAP-AKA-PRIME.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithEapAkaPrime() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_AKA_PRIME;
+        assertTrue(cred.validate());
+    }
+
+    /**
+     * Verify that a SIM credential without IMSI is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithoutIMSI() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.eapType = EAPConstants.EAP_SIM;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a SIM credential with an invalid IMSI is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithInvalidIMSI() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "dummy";
+        cred.simCredential.eapType = EAPConstants.EAP_SIM;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a SIM credential with invalid EAP type is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateSimCredentialWithEapTls() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_TLS;
+        assertFalse(cred.validate());
+    }
+
+    /**
+     * Verify that a credential contained both an user and a SIM credential is invalid.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateCredentialWithUserAndSimCredential() throws Exception {
+        Credential cred = new Credential();
+        cred.realm = "realm";
+        // Setup user credential with EAP-TTLS.
+        cred.userCredential = new Credential.UserCredential();
+        cred.userCredential.username = "username";
+        cred.userCredential.password = "password";
+        cred.userCredential.eapType = EAPConstants.EAP_TTLS;
+        cred.userCredential.nonEapInnerMethod = "MS-CHAP";
+        cred.caCertificate = FakeKeys.CA_CERT0;
+        // Setup SIM credential.
+        cred.simCredential = new Credential.SimCredential();
+        cred.simCredential.imsi = "1234*";
+        cred.simCredential.eapType = EAPConstants.EAP_SIM;
+        assertFalse(cred.validate());
+    }
+}
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
index 0d2da64..fff1477 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
@@ -16,13 +16,12 @@
 
 package android.net.wifi.hotspot2.pps;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import java.util.HashMap;
-
 import org.junit.Test;
 
 /**
@@ -47,13 +46,76 @@
         assertTrue(readHomeSp.equals(writeHomeSp));
     }
 
+    /**
+     * Verify parcel read/write for an empty HomeSP.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithEmptyHomeSP() throws Exception {
         verifyParcel(new HomeSP());
     }
 
+    /**
+     * Verify parcel read/write for a valid HomeSP.
+     *
+     * @throws Exception
+     */
     @Test
     public void verifyParcelWithValidHomeSP() throws Exception {
         verifyParcel(createHomeSp());
     }
+
+    /**
+     * Verify that a HomeSP is valid when both FQDN and Friendly Name
+     * are provided.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateValidHomeSP() throws Exception {
+        HomeSP homeSp = new HomeSP();
+        homeSp.fqdn = "fqdn";
+        homeSp.friendlyName = "friendly name";
+        assertTrue(homeSp.validate());
+    }
+
+    /**
+     * Verify that a HomeSP is not valid when FQDN is not provided
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateHomeSpWithoutFqdn() throws Exception {
+        HomeSP homeSp = new HomeSP();
+        homeSp.friendlyName = "friendly name";
+        assertFalse(homeSp.validate());
+    }
+
+    /**
+     * Verify that a HomeSP is not valid when Friendly Name is not provided
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateHomeSpWithoutFriendlyName() throws Exception {
+        HomeSP homeSp = new HomeSP();
+        homeSp.fqdn = "fqdn";
+        assertFalse(homeSp.validate());
+    }
+
+    /**
+     * Verify that a HomeSP is valid when the optional Roaming Consortium OIs are
+     * provided.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void validateHomeSpWithRoamingConsoritums() throws Exception {
+        HomeSP homeSp = new HomeSP();
+        homeSp.fqdn = "fqdn";
+        homeSp.friendlyName = "friendly name";
+        homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66};
+        assertTrue(homeSp.validate());
+    }
 }