Merge "Fix FragmentManager.FragmentLifecycleCallbacks scope"
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/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 61d0ce4..25741b3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5352,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();
@@ -63357,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();
@@ -63366,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);
@@ -63437,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 7c56ec0..e75bd64 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4556,7 +4556,7 @@
     method public final void attachBaseContext(android.content.Context);
     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";
@@ -5507,7 +5507,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);
@@ -5515,7 +5515,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();
@@ -5527,7 +5527,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
   }
@@ -66883,7 +66883,10 @@
     method public java.lang.String getComment();
     method public long getCompressedSize();
     method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
     method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
     method public int getMethod();
     method public java.lang.String getName();
     method public long getSize();
@@ -66892,7 +66895,10 @@
     method public void setComment(java.lang.String);
     method public void setCompressedSize(long);
     method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
     method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
     method public void setMethod(int);
     method public void setSize(long);
     method public void setTime(long);
@@ -66963,6 +66969,7 @@
     method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
     method public java.lang.String getName();
     method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
     field public static final int CENATT = 36; // 0x24
     field public static final int CENATX = 38; // 0x26
     field public static final int CENCOM = 32; // 0x20
diff --git a/api/test-current.txt b/api/test-current.txt
index 47b4af8..4a54733 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5362,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();
@@ -63618,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();
@@ -63627,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);
@@ -63698,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/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/EphemeralResolverService.java b/core/java/android/app/EphemeralResolverService.java
index d8d7340..7e3f626 100644
--- a/core/java/android/app/EphemeralResolverService.java
+++ b/core/java/android/app/EphemeralResolverService.java
@@ -68,9 +68,9 @@
     /**
      * 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");
     }
 
@@ -96,11 +96,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 +136,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/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..8c9837b 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(boolean is24Hour);
+    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.
-     */
+            IVoiceInteractor voiceInteractor);
+    void handleTrustStorageUpdate();
+    void attachAgent(String path);
 }
\ No newline at end of file
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/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/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/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/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/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/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-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/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/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index da6d994..408159b 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -34,8 +34,6 @@
 CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
         SkBitmap* bitmap) {
     ATRACE_CALL();
-    mRenderThread.eglManager().initialize();
-
     // Setup the source
     sp<GraphicBuffer> sourceBuffer;
     sp<Fence> sourceFence;
@@ -61,13 +59,19 @@
         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) sourceBuffer->getNativeBuffer();
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) graphicBuffer->getNativeBuffer();
     EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
 
     EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
@@ -78,8 +82,8 @@
         return CopyResult::UnknownError;
     }
 
-    CopyResult copyResult = copyImageInto(sourceImage, texTransform, sourceBuffer->getWidth(),
-            sourceBuffer->getHeight(), srcRect, bitmap);
+    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
@@ -89,6 +93,14 @@
     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);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index 7ec2a96..f4ebabc 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -28,6 +28,8 @@
 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) {}
@@ -35,6 +37,9 @@
 
     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 {
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index 7fbc4bf..b763953 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -23,6 +23,7 @@
 #include <gui/Surface.h>
 
 namespace android {
+class GraphicBuffer;
 namespace uirenderer {
 
 // Keep in sync with PixelCopy.java codes
@@ -42,6 +43,7 @@
      */
     virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect,
             SkBitmap* bitmap) = 0;
+    virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) = 0;
 
 protected:
     explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {}
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index c028f115..d6b6548 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -459,14 +459,15 @@
 }
 
 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);
-    outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
 }
 
 void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
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/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index f95d98c..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>
@@ -116,11 +120,18 @@
 
 void Typeface::setRobotoTypefaceForTest() {
     const char* kRobotoFont = "/system/fonts/Roboto-Regular.ttf";
-    sk_sp<SkTypeface> typeface = SkTypeface::MakeFromFile(kRobotoFont);
+
+    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), nullptr, 0, 0);
+    minikin::MinikinFont* font = new MinikinFontSkia(std::move(typeface), data, st.st_size, 0);
     family->addFont(font);
     font->Unref();
 
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/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index a4a83ef..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;
 }
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/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 2c48242..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 {
@@ -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 223958a..e13d0ce 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -23,6 +23,7 @@
 #include "OpenGLReadback.h"
 #include "RenderProxy.h"
 #include "VulkanManager.h"
+#include "utils/FatVector.h"
 
 #include <gui/DisplayEventReceiver.h>
 #include <gui/ISurfaceComposer.h>
@@ -311,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/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/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/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/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/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/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/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/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6701431..f4ddc06 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -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 */);
@@ -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);
         }
@@ -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);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index b5fecfb..8fd1d2f 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1881,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();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 77d36f2..1437c83 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6324,13 +6324,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");
@@ -13523,9 +13528,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 {
@@ -16909,13 +16916,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--) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index ccd94cb..dff7cef 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1524,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
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a530b3d..604b3ed 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -80,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;
@@ -243,7 +241,6 @@
     private int mDefaultNotificationLedOn;
 
     private int mDefaultNotificationLedOff;
-    private long[] mDefaultVibrationPattern;
 
     private long[] mFallbackVibrationPattern;
     private boolean mUseAttentionLight;
@@ -304,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;
@@ -822,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);
 
@@ -835,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);
@@ -860,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);
-            }
         }
     }
 
@@ -939,8 +927,8 @@
     }
 
     @VisibleForTesting
-    void setSystemNotificationSound(String systemNotificationSound) {
-        mSystemNotificationSound = systemNotificationSound;
+    void setFallbackVibrationPattern(long[] vibrationPattern) {
+        mFallbackVibrationPattern = vibrationPattern;
     }
 
     @Override
@@ -1068,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,
@@ -3034,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.
@@ -3078,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
@@ -3168,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
index 82f796dac..7ddd058 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolver.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolver.java
@@ -39,6 +39,7 @@
 
 import com.android.server.pm.EphemeralResolverConnection.PhaseTwoCallback;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
@@ -72,19 +73,19 @@
             EphemeralResolverConnection connection, EphemeralRequest requestObj,
             ActivityInfo ephemeralInstaller, Handler callbackHandler) {
         final Intent intent = requestObj.origIntent;
-        final EphemeralDigest digest =
-                new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/);
-        final int[] shaPrefix = digest.getDigestPrefix();
-        final byte[][] digestBytes = digest.getDigestBytes();
+        final String hostName = intent.getData().getHost();
+        final EphemeralDigest digest = new EphemeralDigest(hostName, 5 /*maxDigests*/);
 
         final PhaseTwoCallback callback = new PhaseTwoCallback() {
             @Override
-            void onPhaseTwoResolved(List<EphemeralResolveInfo> ephemeralResolveInfoList,
+            void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo,
                     int sequence) {
                 final String packageName;
                 final String splitName;
-                if (ephemeralResolveInfoList != null
-                        && ephemeralResolveInfoList.size() > 0) {
+                if (ephemeralResolveInfo != null) {
+                    final ArrayList<EphemeralResolveInfo> ephemeralResolveInfoList =
+                            new ArrayList<EphemeralResolveInfo>(1);
+                    ephemeralResolveInfoList.add(ephemeralResolveInfo);
                     final EphemeralResponse ephemeralIntentInfo =
                             EphemeralResolver.filterEphemeralIntent(
                                     ephemeralResolveInfoList, intent, null /*resolvedType*/,
@@ -118,7 +119,7 @@
             }
         };
         connection.getEphemeralIntentFilterList(
-                shaPrefix, callback, callbackHandler, 0 /*sequence*/);
+                hostName, callback, callbackHandler, 0 /*sequence*/);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 20d9813..2b6ce10 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -84,24 +84,24 @@
         return null;
     }
 
-    public final void getEphemeralIntentFilterList(int digestPrefix[], PhaseTwoCallback callback,
+    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 ArrayList<EphemeralResolveInfo> ephemeralResolveInfoList =
-                        data.getParcelableArrayList(EphemeralResolverService.EXTRA_RESOLVE_INFO);
+                final EphemeralResolveInfo ephemeralResolveInfo =
+                        data.getParcelable(EphemeralResolverService.EXTRA_RESOLVE_INFO);
                 callbackHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        callback.onPhaseTwoResolved(ephemeralResolveInfoList, sequence);
+                        callback.onPhaseTwoResolved(ephemeralResolveInfo, sequence);
                     }
                 });
             }
         };
         try {
             getRemoteInstanceLazy()
-                    .getEphemeralIntentFilterList(remoteCallback, digestPrefix, sequence);
+                    .getEphemeralIntentFilterList(remoteCallback, hostName, sequence);
         } catch (RemoteException re) {
         } catch (TimeoutException te) {
         }
@@ -173,8 +173,7 @@
      * Asynchronous callback when results come back from ephemeral resolution phase two.
      */
     public abstract static class PhaseTwoCallback {
-        abstract void onPhaseTwoResolved(List<EphemeralResolveInfo> ephemeralResolveInfoList,
-                int sequence);
+        abstract void onPhaseTwoResolved(EphemeralResolveInfo ephemeralResolveInfo, int sequence);
     }
 
     private final class MyServiceConnection implements ServiceConnection {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 0844d48..5d739d1 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -413,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;
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/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/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/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 883d2d8..c497cb1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -205,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";
@@ -466,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;
@@ -2359,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,
@@ -2515,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);
@@ -5521,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 {
-            ActivityManager.getService().requestBugReport(
+            mInjector.getIActivityManager().requestBugReport(
                     ActivityManager.BUGREPORT_OPTION_REMOTE);
 
             mRemoteBugreportServiceIsActive.set(true);
@@ -6530,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(),
@@ -9171,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);
@@ -9180,6 +9246,8 @@
             return null;
         }
 
+        recordSecurityLogRetrievalTime();
+
         ArrayList<SecurityEvent> output = new ArrayList<SecurityEvent>();
         try {
             SecurityLog.readPreviousEvents(output);
@@ -9195,6 +9263,8 @@
         Preconditions.checkNotNull(admin);
         ensureDeviceOwnerManagingSingleUser(admin);
 
+        recordSecurityLogRetrievalTime();
+
         List<SecurityEvent> logs = mSecurityLogMonitor.retrieveLogs();
         return logs != null ? new ParceledListSlice<SecurityEvent>(logs) : null;
     }
@@ -9670,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);
     }
 
     /**
@@ -9716,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/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/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 71379b8..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;
@@ -2268,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/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/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/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/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/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());
+    }
 }