Merge "Fixes delay when playing first sound in BootAnimation" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index d5f36bd..d3ee682 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19652,6 +19652,7 @@
     field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR;
     field public static final int ENCODING_AC3 = 5; // 0x5
     field public static final int ENCODING_DEFAULT = 1; // 0x1
+    field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe
     field public static final int ENCODING_DTS = 7; // 0x7
     field public static final int ENCODING_DTS_HD = 8; // 0x8
     field public static final int ENCODING_E_AC3 = 6; // 0x6
diff --git a/api/system-current.txt b/api/system-current.txt
index 16c75cc..13ad2d6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -21160,6 +21160,7 @@
     field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR;
     field public static final int ENCODING_AC3 = 5; // 0x5
     field public static final int ENCODING_DEFAULT = 1; // 0x1
+    field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe
     field public static final int ENCODING_DTS = 7; // 0x7
     field public static final int ENCODING_DTS_HD = 8; // 0x8
     field public static final int ENCODING_E_AC3 = 6; // 0x6
diff --git a/api/test-current.txt b/api/test-current.txt
index 7fdbb64..c6359dd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19722,6 +19722,7 @@
     field public static final android.os.Parcelable.Creator<android.media.AudioFormat> CREATOR;
     field public static final int ENCODING_AC3 = 5; // 0x5
     field public static final int ENCODING_DEFAULT = 1; // 0x1
+    field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe
     field public static final int ENCODING_DTS = 7; // 0x7
     field public static final int ENCODING_DTS_HD = 8; // 0x8
     field public static final int ENCODING_E_AC3 = 6; // 0x6
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 23fea71..af981f6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -93,7 +93,8 @@
     @IntDef({
             BUGREPORT_OPTION_FULL,
             BUGREPORT_OPTION_INTERACTIVE,
-            BUGREPORT_OPTION_REMOTE
+            BUGREPORT_OPTION_REMOTE,
+            BUGREPORT_OPTION_WEAR
     })
     public @interface BugreportMode {}
     /**
@@ -114,6 +115,11 @@
      * @hide
      */
     public static final int BUGREPORT_OPTION_REMOTE = 2;
+    /**
+     * Takes a bugreport on a wearable device.
+     * @hide
+     */
+    public static final int BUGREPORT_OPTION_WEAR = 3;
 
     /**
      * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 8692336..9fa8a5d 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -345,7 +345,7 @@
             PrintWriter pw = new FastPrintWriter(sw, false, 256);
             tr.printStackTrace(pw);
             pw.flush();
-            stackTrace = sw.toString();
+            stackTrace = sanitizeString(sw.toString());
             exceptionMessage = tr.getMessage();
 
             // Populate fields with the "root cause" exception
@@ -374,6 +374,29 @@
                 throwMethodName = "unknown";
                 throwLineNumber = 0;
             }
+
+            exceptionMessage = sanitizeString(exceptionMessage);
+        }
+
+        /**
+         * Ensure that the string is of reasonable size, truncating from the middle if needed.
+         */
+        private String sanitizeString(String s) {
+            int prefixLength = 10 * 1024;
+            int suffixLength = 10 * 1024;
+            int acceptableLength = prefixLength + suffixLength;
+
+            if (s != null && s.length() > acceptableLength) {
+                String replacement =
+                        "\n[TRUNCATED " + (s.length() - acceptableLength) + " CHARS]\n";
+
+                StringBuilder sb = new StringBuilder(acceptableLength + replacement.length());
+                sb.append(s.substring(0, prefixLength));
+                sb.append(replacement);
+                sb.append(s.substring(s.length() - suffixLength));
+                return sb.toString();
+            }
+            return s;
         }
 
         /**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fa943f2..2e37db2 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3519,6 +3519,8 @@
             boolean validRemoteInput = false;
 
             int N = mActions.size();
+            boolean emphazisedMode = mN.fullScreenIntent != null;
+            big.setBoolean(R.id.actions, "setEmphasizedMode", emphazisedMode);
             if (N > 0) {
                 big.setViewVisibility(R.id.actions_container, View.VISIBLE);
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
@@ -3529,7 +3531,8 @@
                     Action action = mActions.get(i);
                     validRemoteInput |= hasValidRemoteInput(action);
 
-                    final RemoteViews button = generateActionButton(action);
+                    final RemoteViews button = generateActionButton(action, emphazisedMode,
+                            i % 2 != 0);
                     big.addView(R.id.actions, button);
                 }
             } else {
@@ -3694,11 +3697,13 @@
 
 
 
-        private RemoteViews generateActionButton(Action action) {
+        private RemoteViews generateActionButton(Action action, boolean emphazisedMode,
+                boolean oddAction) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(),
-                    tombstone ? getActionTombstoneLayoutResource()
-                              : getActionLayoutResource());
+                    emphazisedMode ? getEmphasizedActionLayoutResource()
+                            : tombstone ? getActionTombstoneLayoutResource()
+                                    : getActionLayoutResource());
             final Icon ai = action.getIcon();
             button.setTextViewText(R.id.action0, processLegacyText(action.title));
             if (!tombstone) {
@@ -3708,8 +3713,18 @@
             if (action.mRemoteInputs != null) {
                 button.setRemoteInputs(R.id.action0, action.mRemoteInputs);
             }
-            if (mN.color != COLOR_DEFAULT) {
-                button.setTextColor(R.id.action0, resolveContrastColor());
+            if (emphazisedMode) {
+                // change the background color
+                int color = resolveContrastColor();
+                if (oddAction) {
+                    color = NotificationColorUtil.lightenColor(color, 10);
+                }
+                button.setDrawableParameters(R.id.button_holder, true, -1, color,
+                        PorterDuff.Mode.SRC_ATOP, -1);
+            } else {
+                if (mN.color != COLOR_DEFAULT) {
+                    button.setTextColor(R.id.action0, resolveContrastColor());
+                }
             }
             return button;
         }
@@ -3979,6 +3994,10 @@
             return R.layout.notification_material_action;
         }
 
+        private int getEmphasizedActionLayoutResource() {
+            return R.layout.notification_material_action_emphasized;
+        }
+
         private int getActionTombstoneLayoutResource() {
             return R.layout.notification_material_action_tombstone;
         }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index dc33671..2a12ac8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1315,7 +1315,7 @@
 
     /**
      * Retrieve the current minimum password quality for a particular admin or all admins that set
-     * retrictions on this user and its participating profiles. Restrictions on profiles that have
+     * restrictions on this user and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      *
      * <p>This method can be called on the {@link DevicePolicyManager} instance
@@ -1379,7 +1379,7 @@
 
     /**
      * Retrieve the current minimum password length for a particular admin or all admins that set
-     * retrictions on this user and its participating profiles. Restrictions on profiles that have
+     * restrictions on this user and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      *
      * <p>This method can be called on the {@link DevicePolicyManager} instance
@@ -1442,7 +1442,7 @@
 
     /**
      * Retrieve the current number of upper case letters required in the password
-     * for a particular admin or all admins that set retrictions on this user and
+     * for a particular admin or all admins that set restrictions on this user and
      * its participating profiles. Restrictions on profiles that have a separate challenge
      * are not taken into account.
      * This is the same value as set by
@@ -1511,7 +1511,7 @@
 
     /**
      * Retrieve the current number of lower case letters required in the password
-     * for a particular admin or all admins that set retrictions on this user
+     * for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      * This is the same value as set by
@@ -1580,7 +1580,7 @@
 
     /**
      * Retrieve the current number of letters required in the password
-     * for a particular admin or all admins that set retrictions on this user
+     * for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      * This is the same value as set by
@@ -1648,7 +1648,7 @@
 
     /**
      * Retrieve the current number of numerical digits required in the password
-     * for a particular admin or all admins that set retrictions on this user
+     * for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      * This is the same value as set by
@@ -1716,7 +1716,7 @@
 
     /**
      * Retrieve the current number of symbols required in the password
-     * for a particular admin or all admins that set retrictions on this user
+     * for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account. This is the same value as
      * set by {@link #setPasswordMinimumSymbols(ComponentName, int)}
@@ -1783,7 +1783,7 @@
 
     /**
      * Retrieve the current number of non-letter characters required in the password
-     * for a particular admin or all admins that set retrictions on this user
+     * for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      * This is the same value as set by
@@ -1915,7 +1915,7 @@
 
     /**
      * Get the current password expiration time for a particular admin or all admins that set
-     * retrictions on this user and its participating profiles. Restrictions on profiles that have
+     * restrictions on this user and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account. If admin is {@code null}, then a composite
      * of all expiration times is returned - which will be the minimum of all of them.
      *
@@ -1939,7 +1939,7 @@
 
     /**
      * Retrieve the current password history length for a particular admin or all admins that
-     * set retrictions on this user and its participating profiles. Restrictions on profiles that
+     * set restrictions on this user and its participating profiles. Restrictions on profiles that
      * have a separate challenge are not taken into account.
      *
      * <p>This method can be called on the {@link DevicePolicyManager} instance
@@ -2121,7 +2121,7 @@
 
     /**
      * Retrieve the current maximum number of login attempts that are allowed before the device
-     * or profile is wiped, for a particular admin or all admins that set retrictions on this user
+     * or profile is wiped, for a particular admin or all admins that set restrictions on this user
      * and its participating profiles. Restrictions on profiles that have a separate challenge are
      * not taken into account.
      *
@@ -2262,7 +2262,7 @@
 
     /**
      * Retrieve the current maximum time to unlock for a particular admin or all admins that set
-     * retrictions on this user and its participating profiles. Restrictions on profiles that have
+     * restrictions on this user and its participating profiles. Restrictions on profiles that have
      * a separate challenge are not taken into account.
      *
      * <p>This method can be called on the {@link DevicePolicyManager} instance
@@ -3348,7 +3348,7 @@
 
     /**
      * Determine whether or not features have been disabled in keyguard either by the calling
-     * admin, if specified, or all admins that set retrictions on this user and its participating
+     * admin, if specified, or all admins that set restrictions on this user and its participating
      * profiles. Restrictions on profiles that have a separate challenge are not taken into account.
      *
      * <p>This method can be called on the {@link DevicePolicyManager} instance
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index de52f73..3f8bad1 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -73,11 +73,4 @@
      * any locks in this method.
      */
     public abstract void onSystemLocaleChangedNoLock();
-
-    /**
-     * Called by PM before sending package broadcasts to other components.  PM doesn't hold the PM
-     * lock, but do not take any locks in here anyway, and don't do any heavy tasks, as doing so
-     * would slow down all the package broadcasts.
-     */
-    public abstract void onPackageBroadcast(Intent intent);
 }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 92134ee..1e44a5c 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -49,6 +49,10 @@
             attrs.mLength = len;
             attrs.mRecycled = false;
 
+            // Reset the assets, which may have changed due to configuration changes
+            // or further resource loading.
+            attrs.mAssets = res.getAssets();
+
             final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
             if (attrs.mData.length >= fullLen) {
                 return attrs;
@@ -66,7 +70,7 @@
 
     private final Resources mResources;
     private final DisplayMetrics mMetrics;
-    private final AssetManager mAssets;
+    private AssetManager mAssets;
 
     private boolean mRecycled;
 
@@ -1086,6 +1090,7 @@
         // These may have been set by the client.
         mXml = null;
         mTheme = null;
+        mAssets = null;
 
         mResources.mTypedArrayPool.release(this);
     }
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index 43e596f..fcbc962 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -16,6 +16,11 @@
 
 package android.hardware.location;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+
 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -53,10 +58,14 @@
     private static final int PRE_LOADED_APP_MEM_REQ = 0;
 
     private static final int MSG_HEADER_SIZE = 4;
-    private static final int MSG_FIELD_TYPE = 0;
-    private static final int MSG_FIELD_VERSION = 1;
-    private static final int MSG_FIELD_HUB_HANDLE = 2;
-    private static final int MSG_FIELD_APP_INSTANCE = 3;
+    private static final int HEADER_FIELD_MSG_TYPE = 0;
+    private static final int HEADER_FIELD_MSG_VERSION = 1;
+    private static final int HEADER_FIELD_HUB_HANDLE = 2;
+    private static final int HEADER_FIELD_APP_INSTANCE = 3;
+
+    private static final int HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE;
+    private static final int HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1;
+    private static final int MSG_LOAD_APP_HEADER_SIZE = MSG_HEADER_SIZE + 2;
 
     private static final int OS_APP_INSTANCE = -1;
 
@@ -146,11 +155,16 @@
             return -1;
         }
 
-        int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
-        msgHeader[MSG_FIELD_VERSION] = 0;
-        msgHeader[MSG_FIELD_TYPE] = MSG_LOAD_NANO_APP;
+        int[] msgHeader = new int[MSG_LOAD_APP_HEADER_SIZE];
+        msgHeader[HEADER_FIELD_HUB_HANDLE] = contextHubHandle;
+        msgHeader[HEADER_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
+        msgHeader[HEADER_FIELD_MSG_VERSION] = 0;
+        msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_LOAD_NANO_APP;
+
+        long appId = app.getAppId();
+
+        msgHeader[HEADER_FIELD_LOAD_APP_ID_LO] = (int)(appId & 0xFFFFFFFF);
+        msgHeader[HEADER_FIELD_LOAD_APP_ID_HI] = (int)((appId >> 32) & 0xFFFFFFFF);
 
         if (nativeSendMessage(msgHeader, app.getAppBinary()) != 0) {
             return -1;
@@ -169,12 +183,14 @@
 
         // Call Native interface here
         int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
-        msgHeader[MSG_FIELD_VERSION] = 0;
-        msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP;
+        msgHeader[HEADER_FIELD_HUB_HANDLE] = ANY_HUB;
+        msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppInstanceHandle;
+        msgHeader[HEADER_FIELD_MSG_VERSION] = 0;
+        msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_UNLOAD_NANO_APP;
 
-        if (nativeSendMessage(msgHeader, null) != 0) {
+        byte msg[] = new byte[0];
+
+        if (nativeSendMessage(msgHeader, msg) != 0) {
             return -1;
         }
 
@@ -222,10 +238,10 @@
         checkPermissions();
 
         int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_HUB_HANDLE] = hubHandle;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = nanoAppHandle;
-        msgHeader[MSG_FIELD_VERSION] = msg.getVersion();
-        msgHeader[MSG_FIELD_TYPE] = msg.getMsgType();
+        msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle;
+        msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppHandle;
+        msgHeader[HEADER_FIELD_MSG_VERSION] = msg.getVersion();
+        msgHeader[HEADER_FIELD_MSG_TYPE] = msg.getMsgType();
 
         return nativeSendMessage(msgHeader, msg.getData());
     }
@@ -269,15 +285,17 @@
             Log.v(TAG, "No message callbacks registered.");
             return 0;
         }
-        ContextHubMessage message =
-                new ContextHubMessage(header[MSG_FIELD_TYPE], header[MSG_FIELD_VERSION], data);
+
+        ContextHubMessage msg = new ContextHubMessage(header[HEADER_FIELD_MSG_TYPE],
+                                                      header[HEADER_FIELD_MSG_VERSION],
+                                                      data);
         for (int i = 0; i < callbacksCount; ++i) {
             IContextHubCallback callback = mCallbacksList.getBroadcastItem(i);
             try {
                 callback.onMessageReceipt(
-                        header[MSG_FIELD_HUB_HANDLE],
-                        header[MSG_FIELD_APP_INSTANCE],
-                        message);
+                        header[HEADER_FIELD_HUB_HANDLE],
+                        header[HEADER_FIELD_APP_INSTANCE],
+                        msg);
             } catch (RemoteException e) {
                 Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
                 continue;
@@ -308,12 +326,20 @@
         return 0;
     }
 
+    private int deleteAppInstance(int appInstanceHandle) {
+        if (mNanoAppHash.remove(appInstanceHandle) == null) {
+            return -1;
+        }
+
+        return 0;
+    }
+
     private void sendVrStateChangeMessageToApp(NanoAppInstanceInfo app, boolean vrModeEnabled) {
         int[] msgHeader = new int[MSG_HEADER_SIZE];
-        msgHeader[MSG_FIELD_TYPE] = 0;
-        msgHeader[MSG_FIELD_VERSION] = 0;
-        msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
-        msgHeader[MSG_FIELD_APP_INSTANCE] = app.getHandle();
+        msgHeader[HEADER_FIELD_MSG_TYPE] = 0;
+        msgHeader[HEADER_FIELD_MSG_VERSION] = 0;
+        msgHeader[HEADER_FIELD_HUB_HANDLE] = ANY_HUB;
+        msgHeader[HEADER_FIELD_APP_INSTANCE] = app.getHandle();
 
         byte[] data = new byte[1];
         data[0] = (byte) ((vrModeEnabled) ? 1 : 0);
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 80927f3..8d6d9ed 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -286,6 +286,11 @@
     }
 
     /** {@hide} */
+    public static File getReferenceProfile(String packageName) {
+        return buildPath(getDataDirectory(), "misc", "profiles", "ref", packageName);
+    }
+
+    /** {@hide} */
     public static File getDataProfilesDePackageDirectory(int userId, String packageName) {
         return buildPath(getDataProfilesDeDirectory(userId), packageName);
     }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 1158776..d587ba8 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -235,7 +235,6 @@
          * @see #FLAG_DIR_PREFERS_GRID
          * @see #FLAG_DIR_PREFERS_LAST_MODIFIED
          * @see #FLAG_VIRTUAL_DOCUMENT
-         * @see #FLAG_ARCHIVE
          * @see #FLAG_SUPPORTS_COPY
          * @see #FLAG_SUPPORTS_MOVE
          * @see #FLAG_SUPPORTS_REMOVE
@@ -326,7 +325,7 @@
          * Flag indicating that a document can be renamed.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#renameDocument(ContentProviderClient, Uri,
+         * @see DocumentsContract#renameDocument(ContentResolver, Uri,
          *      String)
          * @see DocumentsProvider#renameDocument(String, String)
          */
@@ -337,7 +336,7 @@
          * within the same document provider.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#copyDocument(ContentProviderClient, Uri, Uri)
+         * @see DocumentsContract#copyDocument(ContentResolver, Uri, Uri)
          * @see DocumentsProvider#copyDocument(String, String)
          */
         public static final int FLAG_SUPPORTS_COPY = 1 << 7;
@@ -347,7 +346,7 @@
          * within the same document provider.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#moveDocument(ContentProviderClient, Uri, Uri, Uri)
+         * @see DocumentsContract#moveDocument(ContentResolver, Uri, Uri, Uri)
          * @see DocumentsProvider#moveDocument(String, String, String)
          */
         public static final int FLAG_SUPPORTS_MOVE = 1 << 8;
@@ -368,7 +367,7 @@
          * Flag indicating that a document can be removed from a parent.
          *
          * @see #COLUMN_FLAGS
-         * @see DocumentsContract#removeDocument(ContentProviderClient, Uri, Uri)
+         * @see DocumentsContract#removeDocument(ContentResolver, Uri, Uri)
          * @see DocumentsProvider#removeDocument(String, String)
          */
         public static final int FLAG_SUPPORTS_REMOVE = 1 << 10;
@@ -870,7 +869,7 @@
      * Test if the given URI represents a {@link Document} tree.
      *
      * @see #buildTreeDocumentUri(String, String)
-     * @see #getTreeDocumentId(Uri, String)
+     * @see #getTreeDocumentId(Uri)
      */
     public static boolean isTreeUri(Uri uri) {
         final List<String> paths = uri.getPathSegments();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a64827a..e648114 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4215,25 +4215,25 @@
                     setAlpha(a.getFloat(attr, 1f));
                     break;
                 case com.android.internal.R.styleable.View_transformPivotX:
-                    setPivotX(a.getDimensionPixelOffset(attr, 0));
+                    setPivotX(a.getDimension(attr, 0));
                     break;
                 case com.android.internal.R.styleable.View_transformPivotY:
-                    setPivotY(a.getDimensionPixelOffset(attr, 0));
+                    setPivotY(a.getDimension(attr, 0));
                     break;
                 case com.android.internal.R.styleable.View_translationX:
-                    tx = a.getDimensionPixelOffset(attr, 0);
+                    tx = a.getDimension(attr, 0);
                     transformSet = true;
                     break;
                 case com.android.internal.R.styleable.View_translationY:
-                    ty = a.getDimensionPixelOffset(attr, 0);
+                    ty = a.getDimension(attr, 0);
                     transformSet = true;
                     break;
                 case com.android.internal.R.styleable.View_translationZ:
-                    tz = a.getDimensionPixelOffset(attr, 0);
+                    tz = a.getDimension(attr, 0);
                     transformSet = true;
                     break;
                 case com.android.internal.R.styleable.View_elevation:
-                    elevation = a.getDimensionPixelOffset(attr, 0);
+                    elevation = a.getDimension(attr, 0);
                     transformSet = true;
                     break;
                 case com.android.internal.R.styleable.View_rotation:
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c427522..209886b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1731,7 +1731,7 @@
             }
 
             boolean hwInitialized = false;
-            boolean framesChanged = false;
+            boolean contentInsetsChanged = false;
             boolean hadSurface = mSurface.isValid();
 
             try {
@@ -1771,7 +1771,7 @@
 
                 final boolean overscanInsetsChanged = !mPendingOverscanInsets.equals(
                         mAttachInfo.mOverscanInsets);
-                boolean contentInsetsChanged = !mPendingContentInsets.equals(
+                contentInsetsChanged = !mPendingContentInsets.equals(
                         mAttachInfo.mContentInsets);
                 final boolean visibleInsetsChanged = !mPendingVisibleInsets.equals(
                         mAttachInfo.mVisibleInsets);
@@ -1821,19 +1821,6 @@
                             + mAttachInfo.mVisibleInsets);
                 }
 
-                // If any of the insets changed, do a forceLayout on the view so that the
-                // measure cache is cleared. We might have a pending MSG_RESIZED_REPORT
-                // that is supposed to take care of it, but since pending insets are
-                // already modified here, it won't detect the frame change after this.
-                framesChanged = overscanInsetsChanged
-                        || contentInsetsChanged
-                        || stableInsetsChanged
-                        || visibleInsetsChanged
-                        || outsetsChanged;
-                if (mAdded && mView != null && framesChanged) {
-                    forceLayout(mView);
-                }
-
                 if (!hadSurface) {
                     if (mSurface.isValid()) {
                         // If we are creating a new surface, then we need to
@@ -2017,7 +2004,7 @@
                 boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
                         (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
                 if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
-                        || mHeight != host.getMeasuredHeight() || framesChanged ||
+                        || mHeight != host.getMeasuredHeight() || contentInsetsChanged ||
                         updatedConfiguration) {
                     int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                     int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
@@ -2026,7 +2013,7 @@
                             + mWidth + " measuredWidth=" + host.getMeasuredWidth()
                             + " mHeight=" + mHeight
                             + " measuredHeight=" + host.getMeasuredHeight()
-                            + " framesChanged=" + framesChanged);
+                            + " coveredInsetsChanged=" + contentInsetsChanged);
 
                      // Ask host how big it wants to be
                     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
@@ -3186,7 +3173,7 @@
             }
             focusNode.recycle();
         }
-        if (mAccessibilityFocusedHost != null) {
+        if ((mAccessibilityFocusedHost != null) && (mAccessibilityFocusedHost != view))  {
             // Clear accessibility focus in the view.
             mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks(
                     AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 48bcc09..77452ca 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -341,6 +341,20 @@
     }
 
     /**
+     * Lighten a color by a specified value
+     * @param baseColor the base color to lighten
+     * @param amount the amount to lighten the color from 0 to 100. This corresponds to the L
+     *               increase in the LAB color space.
+     * @return the lightened color
+     */
+    public static int lightenColor(int baseColor, int amount) {
+        final double[] result = ColorUtilsFromCompat.getTempDouble3Array();
+        ColorUtilsFromCompat.colorToLAB(baseColor, result);
+        result[0] = Math.min(100, result[0] + amount);
+        return ColorUtilsFromCompat.LABToColor(result[0], result[1], result[2]);
+    }
+
+    /**
      * Framework copy of functions needed from android.support.v4.graphics.ColorUtils.
      */
     private static class ColorUtilsFromCompat {
@@ -434,7 +448,7 @@
          * Convert RGB components to its CIE Lab representative components.
          *
          * <ul>
-         * <li>outLab[0] is L [0 ...1)</li>
+         * <li>outLab[0] is L [0 ...100)</li>
          * <li>outLab[1] is a [-128...127)</li>
          * <li>outLab[2] is b [-128...127)</li>
          * </ul>
@@ -516,7 +530,7 @@
          * 2° Standard Observer (1931).</p>
          *
          * <ul>
-         * <li>outLab[0] is L [0 ...1)</li>
+         * <li>outLab[0] is L [0 ...100)</li>
          * <li>outLab[1] is a [-128...127)</li>
          * <li>outLab[2] is b [-128...127)</li>
          * </ul>
@@ -634,7 +648,7 @@
                     : (XYZ_KAPPA * component + 16) / 116;
         }
 
-        private static double[] getTempDouble3Array() {
+        public static double[] getTempDouble3Array() {
             double[] result = TEMP_ARRAY.get();
             if (result == null) {
                 result = new double[3];
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java
index 9dd118c..073aac5 100644
--- a/core/java/com/android/internal/widget/NotificationActionListLayout.java
+++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java
@@ -17,11 +17,13 @@
 package com.android.internal.widget;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Pair;
 import android.view.Gravity;
+import android.view.RemotableViewMethod;
 import android.view.View;
-import android.view.ViewGroup;
+import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
@@ -33,11 +35,14 @@
  * the remaining available width, and the last action consumes the remaining space.
  */
 @RemoteViews.RemoteView
-public class NotificationActionListLayout extends ViewGroup {
+public class NotificationActionListLayout extends LinearLayout {
 
     private int mTotalWidth = 0;
     private ArrayList<Pair<Integer, TextView>> mMeasureOrderTextViews = new ArrayList<>();
     private ArrayList<View> mMeasureOrderOther = new ArrayList<>();
+    private boolean mMeasureLinearly;
+    private int mDefaultPaddingEnd;
+    private Drawable mDefaultBackground;
 
     public NotificationActionListLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -45,6 +50,10 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mMeasureLinearly) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            return;
+        }
         final int N = getChildCount();
         int textViews = 0;
         int otherViews = 0;
@@ -186,6 +195,10 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (mMeasureLinearly) {
+            super.onLayout(changed, left, top, right, bottom);
+            return;
+        }
         final boolean isLayoutRtl = isLayoutRtl();
         final int paddingTop = mPaddingTop;
 
@@ -241,26 +254,24 @@
     }
 
     @Override
-    public LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new MarginLayoutParams(getContext(), attrs);
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mDefaultPaddingEnd = getPaddingEnd();
+        mDefaultBackground = getBackground();
     }
 
-    @Override
-    protected LayoutParams generateDefaultLayoutParams() {
-        return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
-    }
-
-    @Override
-    protected LayoutParams generateLayoutParams(LayoutParams p) {
-        if (p instanceof MarginLayoutParams) {
-            return new MarginLayoutParams((MarginLayoutParams)p);
-        }
-        return new MarginLayoutParams(p);
-    }
-
-    @Override
-    protected boolean checkLayoutParams(LayoutParams p) {
-        return p instanceof MarginLayoutParams;
+    /**
+     * Set whether the list is in a mode where some actions are emphasized. This will trigger an
+     * equal measuring where all actions are full height and change a few parameters like
+     * the padding.
+     */
+    @RemotableViewMethod
+    public void setEmphasizedMode(boolean emphasizedMode) {
+        mMeasureLinearly = emphasizedMode;
+        setPaddingRelative(getPaddingStart(), getPaddingTop(),
+                emphasizedMode ? 0 : mDefaultPaddingEnd, getPaddingBottom());
+        setBackground(emphasizedMode ? null : mDefaultBackground);
+        requestLayout();
     }
 
     public static final Comparator<Pair<Integer, TextView>> MEASURE_ORDER_COMPARATOR
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index a56eba6..46f76de 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -21,28 +21,34 @@
 
 #include <inttypes.h>
 #include <jni.h>
-#include <queue>
-#include <unordered_map>
+#include <mutex>
 #include <string.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unordered_map>
+#include <queue>
 
 #include <cutils/log.h>
 
 #include "JNIHelp.h"
 #include "core_jni_helpers.h"
 
-static constexpr int OS_APP_ID=-1;
+static constexpr int OS_APP_ID = -1;
+static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);
 
-static constexpr int MIN_APP_ID=1;
-static constexpr int MAX_APP_ID=128;
+static constexpr int MIN_APP_ID = 1;
+static constexpr int MAX_APP_ID = 128;
 
-static constexpr size_t MSG_HEADER_SIZE=4;
-static constexpr int HEADER_FIELD_MSG_TYPE=0;
-//static constexpr int HEADER_FIELD_MSG_VERSION=1;
-static constexpr int HEADER_FIELD_HUB_HANDLE=2;
-static constexpr int HEADER_FIELD_APP_INSTANCE=3;
+static constexpr size_t MSG_HEADER_SIZE = 4;
+static constexpr size_t HEADER_FIELD_MSG_TYPE = 0;
+static constexpr size_t HEADER_FIELD_MSG_VERSION = 1;
+static constexpr size_t HEADER_FIELD_HUB_HANDLE = 2;
+static constexpr size_t HEADER_FIELD_APP_INSTANCE = 3;
+
+static constexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE;
+static constexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1;
+static constexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2;
 
 namespace android {
 
@@ -83,6 +89,7 @@
 
     jmethodID contextHubServiceMsgReceiptCallback;
     jmethodID contextHubServiceAddAppInstance;
+    jmethodID contextHubServiceDeleteAppInstance;
 };
 
 struct context_hub_info_s {
@@ -93,10 +100,53 @@
 };
 
 struct app_instance_info_s {
-    uint32_t hubHandle; // Id of the hub this app is on
-    int instanceId; // systemwide unique instance id - assigned
+    uint64_t truncName;          // Possibly truncated name for logging
+    uint32_t hubHandle;          // Id of the hub this app is on
+    int instanceId;              // system wide unique instance id - assigned
     struct hub_app_info appInfo; // returned from the HAL
-    uint64_t truncName; // Possibly truncated name - logging
+};
+
+/*
+ * TODO(ashutoshj): From original code review:
+ *
+ * So, I feel like we could possible do a better job of organizing this code,
+ * and being more C++-y.  Consider something like this:
+ * class TxnManager {
+ *  public:
+ *   TxnManager();
+ *   ~TxnManager();
+ *   int add(hub_message_e identifier, void *data);
+ *   int close();
+ *   bool isPending() const;
+ *   int fetchData(hub_message_e *identifier, void **data) const;
+ *
+ *  private:
+ *   bool mPending;
+ *   mutable std::mutex mLock;
+ *   hub_message_e mIdentifier;
+ *   void *mData;
+ * };
+ *
+ * And then, for example, we'd have things like:
+ * TxnManager::TxnManager() : mPending(false), mLock(), mIdentifier(), mData(nullptr) {}
+ * int TxnManager::add(hub_message_e identifier, void *data) {
+ *    std::lock_guard<std::mutex> lock(mLock);
+ *    mPending = true;
+ *    mData = txnData;
+ *    mIdentifier = txnIdentifier;
+ *    return 0;
+ *  }
+ * And then calling code would look like:
+ *    if (!db.txnManager.add(CONTEXT_HUB_LOAD_APP, txnInfo)) {
+ *
+ * This would make it clearer the nothing is manipulating any state within TxnManager
+ * unsafely and outside of these couple of calls.
+ */
+struct txnManager_s {
+    bool txnPending;              // Is a transaction pending
+    std::mutex m;                 // mutex for manager
+    hub_messages_e txnIdentifier; // What are we doing
+    void *txnData;                // Details
 };
 
 struct contextHubServiceDb_s {
@@ -105,12 +155,69 @@
     jniInfo_s jniInfo;
     std::queue<int> freeIds;
     std::unordered_map<int, app_instance_info_s> appInstances;
+    txnManager_s txnManager;
 };
 
 }  // unnamed namespace
 
 static contextHubServiceDb_s db;
 
+static bool initTxnManager() {
+    txnManager_s *mgr = &db.txnManager;
+
+    mgr->txnData = nullptr;
+    mgr->txnPending = false;
+    return true;
+}
+
+static int addTxn(hub_messages_e txnIdentifier, void *txnData) {
+    txnManager_s *mgr = &db.txnManager;
+
+    std::lock_guard<std::mutex>lock(mgr->m);
+
+    mgr->txnPending = true;
+    mgr->txnData = txnData;
+    mgr->txnIdentifier = txnIdentifier;
+
+    return 0;
+}
+
+static int closeTxn() {
+    txnManager_s *mgr = &db.txnManager;
+    std::lock_guard<std::mutex>lock(mgr->m);
+    mgr->txnPending = false;
+    free(mgr->txnData);
+    mgr->txnData = nullptr;
+
+    return 0;
+}
+
+static bool isTxnPending() {
+    txnManager_s *mgr = &db.txnManager;
+    std::lock_guard<std::mutex>lock(mgr->m);
+    return mgr->txnPending;
+}
+
+static int fetchTxnData(hub_messages_e *id, void **data) {
+    txnManager_s *mgr = &db.txnManager;
+
+    if (!id || !data) {
+        ALOGW("Null params id %p, data %p", id, data);
+        return -1;
+    }
+
+    std::lock_guard<std::mutex>lock(mgr->m);
+    if (!mgr->txnPending) {
+        ALOGW("No Transactions pending");
+        return -1;
+    }
+
+    // else
+    *id = mgr->txnIdentifier;
+    *data = mgr->txnData;
+    return 0;
+}
+
 int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
                          void *cookie);
 
@@ -152,13 +259,21 @@
     }
 }
 
-static int get_hub_id_for_app_instance(int id) {
+static int get_hub_handle_for_app_instance(int id) {
     if (!db.appInstances.count(id)) {
         ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
         return -1;
     }
 
-    int hubHandle = db.appInstances[id].hubHandle;
+    return db.appInstances[id].hubHandle;
+}
+
+static int get_hub_id_for_app_instance(int id) {
+    int hubHandle = get_hub_handle_for_app_instance(id);
+
+    if (hubHandle < 0) {
+        return -1;
+    }
 
     return db.hubInfo.hubs[hubHandle].hub_id;
 }
@@ -184,7 +299,7 @@
     return 0;
 }
 
-static void send_query_for_apps() {
+static void query_hub_for_apps(uint64_t appId, uint32_t hubHandle) {
     hub_message_t msg;
     query_apps_request_t queryMsg;
 
@@ -194,23 +309,31 @@
     msg.message_len  = sizeof(queryMsg);
     msg.message = &queryMsg;
 
+    ALOGD("Sending query for apps to hub %" PRIu32, hubHandle);
+    set_os_app_as_destination(&msg, hubHandle);
+    if (send_msg_to_hub(&msg, hubHandle) != 0) {
+        ALOGW("Could not query hub %" PRIu32 " for apps", hubHandle);
+    }
+}
+
+static void sendQueryForApps(uint64_t appId) {
     for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
-        ALOGD("Sending query for apps to hub %d", i);
-        set_os_app_as_destination(&msg, i);
-        if (send_msg_to_hub(&msg, i) != 0) {
-          ALOGW("Could not query hub %i for apps", i);
-        }
+        query_hub_for_apps(appId, i);
     }
 }
 
 static int return_id(int id) {
     // Note : This method is not thread safe.
-    // id returned is guarenteed to be in use
-    db.freeIds.push(id);
-    return 0;
+    // id returned is guaranteed to be in use
+    if (id >= 0) {
+        db.freeIds.push(id);
+        return 0;
+    }
+
+    return -1;
 }
 
-static int generate_id(void) {
+static int generate_id() {
     // Note : This method is not thread safe.
     int retVal = -1;
 
@@ -222,23 +345,31 @@
     return retVal;
 }
 
-int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) {
+
+static int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle,
+        int appInstanceHandle, JNIEnv *env) {
+
+    ALOGI("Loading App");
+
     // Not checking if the apps are indeed distinct
     app_instance_info_s entry;
-    int appInstanceHandle = generate_id();
-
     assert(appInfo);
 
-    if (appInstanceHandle < 0) {
-        ALOGE("Cannot find resources to add app instance %d",
-              appInstanceHandle);
-        return -1;
+    if (db.appInstances.count(appInstanceHandle) == 0) {
+        appInstanceHandle = generate_id();
+        if (appInstanceHandle < 0) {
+            ALOGE("Cannot find resources to add app instance %d",
+                  appInstanceHandle);
+            return -1;
+        }
     }
 
     entry.appInfo = *appInfo;
+
     entry.instanceId = appInstanceHandle;
     entry.truncName = appInfo->app_name.id;
     entry.hubHandle = hubHandle;
+
     db.appInstances[appInstanceHandle] = entry;
 
     // Finally - let the service know of this app instance
@@ -254,17 +385,70 @@
     return appInstanceHandle;
 }
 
-int delete_app_instance(int id) {
+int delete_app_instance(int id, JNIEnv *env) {
     if (!db.appInstances.count(id)) {
+        ALOGW("Cannot find App id : %d", id);
         return -1;
     }
 
     return_id(id);
     db.appInstances.erase(id);
+    if (env->CallIntMethod(db.jniInfo.jContextHubService,
+                       db.jniInfo.contextHubServiceDeleteAppInstance,
+                       id) != 0) {
+        ALOGW("Could not delete App id : %d", id);
+        return -1;
+    }
+
+    ALOGI("Deleted App id : %d", id);
 
     return 0;
 }
 
+static int startLoadAppTxn(uint64_t appId, int hubHandle) {
+    app_instance_info_s *txnInfo = (app_instance_info_s *)malloc(sizeof(app_instance_info_s));
+    int instanceId = generate_id();
+
+    if (!txnInfo || instanceId < 0) {
+        return_id(instanceId);
+        free(txnInfo);
+        return -1;
+    }
+
+    txnInfo->truncName = appId;
+    txnInfo->hubHandle = hubHandle;
+    txnInfo->instanceId = instanceId;
+
+    txnInfo->appInfo.app_name.id = appId;
+    txnInfo->appInfo.num_mem_ranges = 0;
+    txnInfo->appInfo.version = -1; // Awaited
+
+    if (!addTxn(CONTEXT_HUB_LOAD_APP, txnInfo)) {
+        return_id(instanceId);
+        free(txnInfo);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int startUnloadAppTxn(uint32_t appInstanceHandle) {
+    uint32_t *txnData = (uint32_t *) malloc(sizeof(uint32_t));
+    if (!txnData) {
+        ALOGW("Cannot allocate memory to start unload transaction");
+        return -1;
+    }
+
+    *txnData = appInstanceHandle;
+
+    if (addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) {
+        free(txnData);
+        ALOGW("Cannot start transaction to unload app");
+        return -1;
+    }
+
+    return 0;
+}
 
 static void initContextHubService() {
     int err = 0;
@@ -285,6 +469,7 @@
         db.freeIds.push(i);
     }
 
+    initTxnManager();
     if (db.hubInfo.contextHubModule) {
         int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
                                                                  &db.hubInfo.hubs);
@@ -302,6 +487,7 @@
 
             for (i = 0; i < db.hubInfo.numHubs; i++) {
                 db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
+                ALOGI("Subscribing to hubHandle %d with OS App name %" PRIu64, i, db.hubInfo.hubs[i].os_app_name.id);
                 if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
                                                                     context_hub_callback,
                                                                     &db.hubInfo.cookies[i]) == 0) {
@@ -309,7 +495,7 @@
             }
         }
 
-        send_query_for_apps();
+        sendQueryForApps(ALL_APPS);
     } else {
         ALOGW("No Context Hub Module present");
     }
@@ -346,7 +532,8 @@
     return ret;
 }
 
-int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) {
+int handle_query_apps_response(const uint8_t *msg, int msgLen,
+                               uint32_t hubHandle) {
     JNIEnv *env;
     if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
             return -1;
@@ -354,53 +541,201 @@
 
     int numApps = msgLen/sizeof(hub_app_info);
     hub_app_info info;
-    hub_app_info *unalignedInfoAddr = (hub_app_info*)msg;
+    const hub_app_info *unalignedInfoAddr = (const hub_app_info*)msg;
 
     for (int i = 0; i < numApps; i++, unalignedInfoAddr++) {
         memcpy(&info, unalignedInfoAddr, sizeof(info));
-        add_app_instance(&info, hubHandle, env);
+        // We will only have one instance of the app
+        // TODO : Change this logic once we support multiple instances of the same app
+        int appInstance = get_app_instance_for_app_id(info.app_name.id);
+        add_app_instance(&info, hubHandle, appInstance, env);
     }
 
     return 0;
 }
 
+static void passOnOsResponse(uint32_t hubHandle, uint32_t msgType,
+                             status_response_t *rsp, int8_t *additionalData,
+                             size_t additionalDataLen) {
+    JNIEnv *env;
 
-int handle_os_message(uint32_t msgType, uint32_t hubHandle,
-                      char *msg, int msgLen) {
-    int retVal;
+    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
+        ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32, msgType);
+        return;
+    }
 
-    //ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d",
-    //      hubHandle, msgType, msgLen);
+    uint32_t header[MSG_HEADER_SIZE];
+    memset(header, 0, sizeof(header));
+
+    if (!additionalData) {
+        additionalDataLen = 0; // clamp
+    }
+    int msgLen = 1 + additionalDataLen;
+
+    int8_t *msg = new int8_t[msgLen];
+
+    if (!msg) {
+        ALOGW("Unexpected : Ran out of memory, cannot send response");
+        return;
+    }
+
+    header[HEADER_FIELD_MSG_TYPE] = msgType;
+    header[HEADER_FIELD_MSG_VERSION] = 0;
+    header[HEADER_FIELD_HUB_HANDLE] = hubHandle;
+    header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID;
+
+    msg[0] = rsp->result;
+
+    if (additionalData) {
+        memcpy(&msg[1], additionalData, additionalDataLen);
+    }
+
+    jbyteArray jmsg = env->NewByteArray(msgLen);
+    jintArray jheader = env->NewIntArray(sizeof(header));
+
+    env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
+    env->SetIntArrayRegion(jheader, 0, sizeof(header), (jint *)header);
+
+    ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32,
+          header[HEADER_FIELD_MSG_TYPE], header[HEADER_FIELD_APP_INSTANCE],
+          header[HEADER_FIELD_HUB_HANDLE]);
+
+    env->CallIntMethod(db.jniInfo.jContextHubService,
+                       db.jniInfo.contextHubServiceMsgReceiptCallback,
+                       jheader, jmsg);
+
+    delete[] msg;
+}
+
+void closeUnloadTxn(bool success) {
+    void *txnData = nullptr;
+    hub_messages_e txnId;
+
+    if (success && fetchTxnData(&txnId, &txnData) == 0 &&
+        txnId == CONTEXT_HUB_UNLOAD_APP) {
+        db.appInstances.erase(*(uint32_t *)txnData);
+    } else {
+        ALOGW("Could not unload the app successfully ! success %d, txnData %p", success, txnData);
+    }
+
+    closeTxn();
+}
+
+void closeLoadTxn(bool success, int *appInstanceHandle) {
+    void *txnData;
+    hub_messages_e txnId;
+
+    if (success && fetchTxnData(&txnId, &txnData) == 0 &&
+        txnId == CONTEXT_HUB_LOAD_APP) {
+        app_instance_info_s *info = (app_instance_info_s *)txnData;
+        *appInstanceHandle = info->instanceId;
+
+        JNIEnv *env;
+        if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) {
+            add_app_instance(&info->appInfo, info->hubHandle, info->instanceId, env);
+        } else {
+            ALOGW("Could not attach to JVM !");
+        }
+        sendQueryForApps(info->appInfo.app_name.id);
+    } else {
+        ALOGW("Could not load the app successfully ! Unexpected failure");
+    }
+
+    closeTxn();
+}
+
+static bool isValidOsStatus(const uint8_t *msg, size_t msgLen,
+                            status_response_t *rsp) {
+    // Workaround a bug in some HALs
+    if (msgLen == 1) {
+        rsp->result = msg[0];
+        return true;
+    }
+
+    if (!msg || msgLen != sizeof(*rsp)) {
+        ALOGW("Received invalid response %p of size %zu", msg, msgLen);
+        return false;
+    }
+
+    memcpy(rsp, msg, sizeof(*rsp));
+
+    // No sanity checks on return values
+    return true;
+}
+
+static void invalidateNanoApps(uint32_t hubHandle) {
+    JNIEnv *env;
+
+    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
+        ALOGW("Could not attach to JVM !");
+    }
+
+    auto end = db.appInstances.end();
+    for (auto current = db.appInstances.begin(); current != end; ) {
+        app_instance_info_s info = current->second;
+        current++;
+        if (info.hubHandle == hubHandle) {
+             delete_app_instance(info.instanceId, env);
+        }
+    }
+}
+
+static int handle_os_message(uint32_t msgType, uint32_t hubHandle,
+                             const uint8_t *msg, int msgLen) {
+    int retVal = -1;
+
+    ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d",
+          hubHandle, msgType, msgLen);
+
+    struct status_response_t rsp;
 
     switch(msgType) {
-        case CONTEXT_HUB_APPS_ENABLE:
-            retVal = 0;
-            break;
 
-        case CONTEXT_HUB_APPS_DISABLE:
-            retVal = 0;
-            break;
+      case CONTEXT_HUB_APPS_ENABLE:
+      case CONTEXT_HUB_APPS_DISABLE:
+      case CONTEXT_HUB_LOAD_APP:
+      case CONTEXT_HUB_UNLOAD_APP:
+          if (isValidOsStatus(msg, msgLen, &rsp)) {
+              if (msgType == CONTEXT_HUB_LOAD_APP) {
+                  int appInstanceHandle;
+                  closeLoadTxn(rsp.result == 0, &appInstanceHandle);
+                  passOnOsResponse(hubHandle, msgType, &rsp, (int8_t *)(&appInstanceHandle),
+                                   sizeof(appInstanceHandle));
+              } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
+                  closeUnloadTxn(rsp.result == 0);
+                  passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
+              } else {
+                  passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
+              }
+              retVal = 0;
+          }
+          break;
 
-        case CONTEXT_HUB_LOAD_APP:
-            retVal = 0;
-            break;
+      case CONTEXT_HUB_QUERY_APPS:
+          rsp.result = 0;
+          retVal = handle_query_apps_response(msg, msgLen, hubHandle);
+          passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
+          break;
 
-        case CONTEXT_HUB_UNLOAD_APP:
-            retVal = 0;
-            break;
+      case CONTEXT_HUB_QUERY_MEMORY:
+          // Deferring this use
+          retVal = 0;
+          break;
 
-        case CONTEXT_HUB_QUERY_APPS:
-            retVal = handle_query_apps_response(msg, msgLen, hubHandle);
-            break;
+      case CONTEXT_HUB_OS_REBOOT:
+          if (isValidOsStatus(msg, msgLen, &rsp)) {
+              rsp.result = 0;
+              ALOGW("Context Hub handle %d restarted", hubHandle);
+              passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0);
+              invalidateNanoApps(hubHandle);
+              query_hub_for_apps(ALL_APPS, hubHandle);
+              retVal = 0;
+          }
+          break;
 
-        case CONTEXT_HUB_QUERY_MEMORY:
-            retVal = 0;
-            break;
-
-        default:
-            retVal = -1;
-            break;
-
+      default:
+          retVal = -1;
+          break;
     }
 
     return retVal;
@@ -420,10 +755,12 @@
     }
 }
 
+
 int context_hub_callback(uint32_t hubId,
                          const struct hub_message_t *msg,
                          void *cookie) {
     if (!msg) {
+        ALOGW("NULL message");
         return -1;
     }
     if (!sanity_check_cookie(cookie, hubId)) {
@@ -433,11 +770,12 @@
         return -1;
     }
 
+
     uint32_t messageType = msg->message_type;
     uint32_t hubHandle = *(uint32_t*) cookie;
 
     if (messageType < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
-        handle_os_message(messageType, hubHandle, (char*) msg->message, msg->message_len);
+        handle_os_message(messageType, hubHandle, (uint8_t*) msg->message, msg->message_len);
     } else {
         int appHandle = get_app_instance_for_app_id(msg->app_name.id);
         if (appHandle < 0) {
@@ -528,7 +866,9 @@
                  env->GetMethodID(db.jniInfo.contextHubServiceClass,
                                     "addAppInstance", "(IIJI)I");
 
-
+    db.jniInfo.contextHubServiceDeleteAppInstance =
+                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
+                                    "deleteAppInstance", "(I)I");
 
     return 0;
 }
@@ -538,8 +878,6 @@
     jintArray jintBuf;
     jobjectArray jmemBuf;
 
-    int dummyConnectedSensors[] = {1, 2, 3, 4, 5};
-
     jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass,
                                   db.jniInfo.contextHubInfoCtor);
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id);
@@ -569,11 +907,21 @@
                         hub->max_supported_msg_len);
 
 
-    // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
-    // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
-    //                               hub->connected_sensors);
-    jintBuf = env->NewIntArray(array_length(dummyConnectedSensors));
-    env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors);
+    jintBuf = env->NewIntArray(hub->num_connected_sensors);
+    int *connectedSensors = new int[hub->num_connected_sensors];
+
+    if (!connectedSensors) {
+      ALOGW("Cannot allocate memory! Unexpected");
+      assert(false);
+    } else {
+      for (unsigned int i = 0; i < hub->num_connected_sensors; i++) {
+        connectedSensors[i] = hub->connected_sensors[i].sensor_id;
+      }
+    }
+
+    env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
+                           connectedSensors);
+
     env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf);
     env->DeleteLocalRef(jintBuf);
 
@@ -584,6 +932,7 @@
     env->DeleteLocalRef(jmemBuf);
 
 
+    delete[] connectedSensors;
     return jHub;
 }
 
@@ -622,33 +971,96 @@
     jbyte *data = env->GetByteArrayElements(data_, 0);
     int dataBufferLength = env->GetArrayLength(data_);
 
+    if (numHeaderElements < MSG_HEADER_SIZE) {
+        ALOGW("Malformed header len");
+        return -1;
+    }
 
-    if (numHeaderElements >= MSG_HEADER_SIZE) {
-        bool setAddressSuccess;
-        int hubId;
-        hub_message_t msg;
+    uint32_t appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE];
+    uint32_t msgType = header[HEADER_FIELD_MSG_TYPE];
+    int hubHandle = -1;
+    int hubId;
+    uint64_t appId;
+
+    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
+        hubHandle = get_hub_handle_for_app_instance(appInstanceHandle);
+    } else if (msgType == CONTEXT_HUB_LOAD_APP) {
+        if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) {
+            return -1;
+        }
+        uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO];
+        uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI];
+        appId = appIdHi << 32 | appIdLo;
+
+        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
+    } else {
+        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
+    }
+
+    if (hubHandle < 0) {
+        ALOGD("Invalid hub Handle %d", hubHandle);
+        return -1;
+    }
+
+    if (msgType == CONTEXT_HUB_LOAD_APP ||
+        msgType == CONTEXT_HUB_UNLOAD_APP) {
+
+        if (isTxnPending()) {
+            ALOGW("Cannot load or unload app while a transaction is pending !");
+            return -1;
+        }
+
+        if (msgType == CONTEXT_HUB_LOAD_APP) {
+            if (startLoadAppTxn(appId, hubHandle) != 0) {
+                return -1;
+            }
+        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
+            if (startUnloadAppTxn(appInstanceHandle) != 0) {
+                return -1;
+            }
+        }
+    }
+
+    bool setAddressSuccess = false;
+    hub_message_t msg;
+
+    msg.message_type = msgType;
+
+    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
+        msg.message_len = sizeof(db.appInstances[appInstanceHandle].appInfo.app_name);
+        msg.message = &db.appInstances[appInstanceHandle].appInfo.app_name;
+        setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0);
+        hubId = get_hub_id_for_hub_handle(hubHandle);
+    } else {
+        msg.message_len = dataBufferLength;
+        msg.message = data;
 
         if (header[HEADER_FIELD_APP_INSTANCE] == OS_APP_ID) {
-            setAddressSuccess = (set_os_app_as_destination(&msg, header[HEADER_FIELD_HUB_HANDLE]) == 0);
-            hubId = get_hub_id_for_hub_handle(header[HEADER_FIELD_HUB_HANDLE]);
+            setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0);
+            hubId = get_hub_id_for_hub_handle(hubHandle);
         } else {
             setAddressSuccess = (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0);
             hubId = get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]);
         }
+    }
 
-        if (setAddressSuccess && hubId >= 0) {
-            msg.message_type = header[HEADER_FIELD_MSG_TYPE];
-            msg.message_len = dataBufferLength;
-            msg.message = data;
-            retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg);
-        } else {
-          ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d",
-                header[HEADER_FIELD_APP_INSTANCE],
-                header[HEADER_FIELD_HUB_HANDLE],
-                (int)setAddressSuccess);
-        }
+    if (setAddressSuccess && hubId >= 0) {
+        ALOGD("Asking HAL to remove app");
+        retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg);
     } else {
-        ALOGD("Malformed header len");
+      ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d",
+            header[HEADER_FIELD_APP_INSTANCE],
+            header[HEADER_FIELD_HUB_HANDLE],
+            (int)setAddressSuccess);
+    }
+
+    if (retVal != 0) {
+        ALOGD("Send Message failure - %d", retVal);
+        if (msgType == CONTEXT_HUB_LOAD_APP) {
+            closeLoadTxn(false, nullptr);
+        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
+            closeUnloadTxn(false);
+        }
     }
 
     env->ReleaseIntArrayElements(header_, header, 0);
diff --git a/core/res/res/drawable/notification_material_action_background_emphasized.xml b/core/res/res/drawable/notification_material_action_background_emphasized.xml
new file mode 100644
index 0000000..b7153ba
--- /dev/null
+++ b/core/res/res/drawable/notification_material_action_background_emphasized.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="@color/ripple_material_dark">
+    <item android:id="@id/mask">
+        <color android:color="@color/white" />
+    </item>
+</ripple>
+
diff --git a/core/res/res/layout/notification_material_action_emphasized.xml b/core/res/res/layout/notification_material_action_emphasized.xml
new file mode 100644
index 0000000..992e43e
--- /dev/null
+++ b/core/res/res/layout/notification_material_action_emphasized.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2016 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/button_holder"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_weight="1"
+    android:background="#ff000000">
+    <Button
+        style="@android:style/Widget.Material.Light.Button.Borderless.Small"
+        android:id="@+id/action0"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:textColor="#ffffffff"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:background="@drawable/notification_material_action_background_emphasized"
+        />
+</FrameLayout>
diff --git a/core/res/res/values-watch/colors_material.xml b/core/res/res/values-watch/colors_material.xml
index 91eee7d..45eb981 100644
--- a/core/res/res/values-watch/colors_material.xml
+++ b/core/res/res/values-watch/colors_material.xml
@@ -20,5 +20,7 @@
     <color name="accent_material_dark">#ff5e97f6</color>
     <color name="accent_material_light">#ff4285f4</color>
 
+    <color name="primary_material_dark">#4D4D4D</color>
+
     <color name="button_material_dark">#ff999999</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e87bb81..674a0d7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -764,7 +764,7 @@
              1 - AUTO_MODE_CUSTOM
              2 - AUTO_MODE_TWILIGHT
     -->
-    <integer name="config_defaultNightDisplayAutoMode">1</integer>
+    <integer name="config_defaultNightDisplayAutoMode">0</integer>
 
     <!-- Default time when Night display is automatically activated.
          Represented as milliseconds from midnight (e.g. 79200000 == 10pm). -->
@@ -2528,6 +2528,9 @@
     <!-- Package name for the device provisioning package. -->
     <string name="config_deviceProvisioningPackage"></string>
 
+    <!-- Colon separated list of package names that should be granted DND access -->
+    <string name="config_defaultDndAccessPackages" translatable="false">com.android.camera2</string>
+
     <!-- User restrictions set when the first user is created.
          Note: Also update appropriate overlay files. -->
     <string-array translatable="false" name="config_defaultFirstUserRestrictions">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f0cfd2b..473796a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2794,6 +2794,9 @@
     <!-- [CHAR LIMIT=200] Body of notification that is shown when performing a system upgrade. -->
     <string name="android_upgrading_notification_body">Some apps may not work properly until the upgrade finishes</string>
 
+    <!-- [CHAR LIMIT=40] Toast that is shown when an app is still upgrading. -->
+    <string name="app_upgrading_toast"><xliff:g id="application">%1$s</xliff:g> is upgrading\u2026</string>
+
     <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog for each .apk that is optimized. -->
     <string name="android_upgrading_apk">Optimizing app
         <xliff:g id="number" example="123">%1$d</xliff:g> of
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6b064c1..3590ac8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2628,6 +2628,8 @@
   <!-- Used internally for assistant to launch activity transitions -->
   <java-symbol type="id" name="cross_task_transition" />
 
+  <java-symbol type="id" name="button_holder" />
+
   <java-symbol type="bool" name="config_useRoundIcon" />
 
   <!-- For System navigation keys -->
@@ -2636,9 +2638,14 @@
   <java-symbol type="layout" name="unsupported_display_size_dialog_content" />
   <java-symbol type="string" name="unsupported_display_size_message" />
 
+  <java-symbol type="layout" name="notification_material_action_emphasized" />
+
   <!-- Package name for the device provisioning package -->
   <java-symbol type="string" name="config_deviceProvisioningPackage" />
 
+  <!-- Colon separated list of package names that should be granted DND access -->
+  <java-symbol type="string" name="config_defaultDndAccessPackages" />
+
   <!-- Used for MimeIconUtils. -->
   <java-symbol type="drawable" name="ic_doc_apk" />
   <java-symbol type="drawable" name="ic_doc_audio" />
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index d4732f8..48aca28 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -1193,3 +1193,5 @@
   to: http://tools.android.com/tech-docs/new-build-system/gradle-experimental/experimental-to-stable-gradle
 - from: /r/studio-ui/sdk-manager.html
   to: https://developer.android.com/studio/intro/update.html#sdk-manager
+- from: /r/studio-ui/newjclass.html
+  to: /studio/write/index.html
diff --git a/docs/html/distribute/stories/apps.jd b/docs/html/distribute/stories/apps.jd
index 9c2e8e9..76e9f5a 100644
--- a/docs/html/distribute/stories/apps.jd
+++ b/docs/html/distribute/stories/apps.jd
@@ -29,5 +29,5 @@
       data-sortOrder="-timestamp"
       data-cardSizes="6x6"
       data-items-per-page="15"
-      data-initial-results="3"></div>
+      data-initial-results="6"></div>
 </div></section>
\ No newline at end of file
diff --git a/docs/html/distribute/stories/apps/aftenposten.jd b/docs/html/distribute/stories/apps/aftenposten.jd
new file mode 100644
index 0000000..f1f388e
--- /dev/null
+++ b/docs/html/distribute/stories/apps/aftenposten.jd
@@ -0,0 +1,80 @@
+page.title=Aftenposten Improves Retention by Allowing Readers to Customize Notifications
+page.metaDescription=Aftenposten upgraded their app and improved user retention.
+page.tags="developerstory", "apps", "googleplay"
+page.image=images/cards/distribute/stories/aftenposten.png
+page.timestamp=1468270114
+
+@jd:body
+
+<div class="figure" style="width:113px">
+  <img src="{@docRoot}images/distribute/stories/aftenposten-icon.png" height=
+  "106">
+</div>
+
+<h3>
+  Background
+</h3>
+
+<p>
+  Aftenposten is one of the largest newspapers in Norway. Their <a class=
+  "external-link" href=
+  "https://play.google.com/store/apps/details?id=no.cita&amp;e=-EnableAppDetailsPageRedesign">
+  news app</a> was released on Android in 2013.
+</p>
+
+<p>
+  Aftenposten found that sending too many notifications, with no user control
+  over the default <em>on</em> setting or differentiation between general and
+  breaking news, caused many people to uninstall their app. They changed the
+  user controls for notifications and used the native Android share button in
+  the app, <strong>which reduced user uninstalls</strong>.
+</p>
+
+<h3>
+  What they did
+</h3>
+
+<p>
+  Aftenposten created a new onboarding flow that explained what notifications
+  were available, allowing readers to manage their preferences and customize up
+  to three topics. They also changed their custom share icon for the native
+  Android app.
+</p>
+
+<h3>
+  Results
+</h3>
+
+<p>
+  The results showed that with the new notifications management onboarding
+  screen, <strong>uninstalls decreased by 9.2% over 60 days</strong>. And with
+  the option to customize notifications, 51% of readers decided to keep two out
+  of three topics turned on. This led to a <strong>28% decrease over 60 days in
+  the number of users muting notifications completely</strong>. It also
+  provided insight into users’ content preferences, with <em>Sport</em> being
+  the least-favored notification.
+</p>
+
+<p>
+  Aftenposten also increased share interactions by 17% just by replacing their
+  custom share icon with the native Android share icon.
+</p>
+
+<p>
+  Aftenposten commented that: <em>Many of our users who see the onboarding
+  screen interact with it by turning off at least one notification topic. This
+  means that users are accepting push from one or more topics, instead of
+  turning it off completely. Moreover, readers are sharing more articles since
+  we added the standard share Android icon.</em>
+</p>
+
+<h3>
+  Get started
+</h3>
+
+<p>
+  Find out more about best practices for <a href=
+  "{@docRoot}design/patterns/notifications.html">Notifications</a> and <a href=
+  "{@docRoot}training/building-content-sharing.html">Building Apps with Content
+  Sharing</a>.
+</p>
diff --git a/docs/html/distribute/stories/apps/el-mundo.jd b/docs/html/distribute/stories/apps/el-mundo.jd
new file mode 100644
index 0000000..2ee813d
--- /dev/null
+++ b/docs/html/distribute/stories/apps/el-mundo.jd
@@ -0,0 +1,73 @@
+page.title=El Mundo Improves User Ratings and Engagement with Material Design
+page.metaDescription=El Mundo uses Material Design principles to enhance their app's user experience.
+page.tags="developerstory", "apps", "googleplay"
+page.image=images/cards/distribute/stories/el-mundo.png
+page.timestamp=1468270112
+
+@jd:body
+
+<div class="figure" style="width:113px">
+  <img src="{@docRoot}images/distribute/stories/el-mundo-icon.png" height=
+  "113">
+</div>
+
+<h3>
+  Background
+</h3>
+
+<p>
+  <a class="external-link" href=
+  "https://play.google.com/store/apps/details?id=com.gi.elmundo.main">El
+  Mundo</a>, one of Spain’s largest newspapers, integrated material design
+  principles into their app, which helped increase their Google Play Store
+  rating and improve user engagement.
+</p>
+
+<h3>
+  What they did
+</h3>
+
+<p>
+  El Mundo decided to completely redesign their app to provide a higher quality
+  user experience, making it easier for their readers to engage with news
+  content. By implementing material design guidelines, they created a
+  consistent look and feel throughout their app.
+</p>
+
+<p>
+  After analyzing user comments, El Mundo discovered that readers considered
+  their app to be complicated and out-of-date. Therefore, they decided to
+  simplify the app’s functionality by removing features that were redundant.
+  They also removed sections of their app that were less relevant to their
+  readers, such as weather updates and movie trailers. Finally, they applied a
+  brand new internal development framework that they now use consistently
+  across all of their apps.
+</p>
+
+<h3>
+  Results
+</h3>
+
+<p>
+  Following the re-launch of their material design app, El Mundo saw a
+  <strong>45% increase in the weekly install rate</strong>. Readers now spend
+  more time in the app, with the average time spent in-app increasing from one
+  to three minutes.
+</p>
+
+<p>
+  Additionally, this redesign resulted in more readers providing positive
+  feedback around the new experience, increasing the app rating in the Google
+  Play store by 25.8%, from 3.1 to 3.9.
+</p>
+
+<h3>
+  Get started
+</h3>
+
+<p>
+  Learn how to integrate <a class="external-link" href=
+  "https://material.google.com">Material Design</a> guidelines and follow
+  <a class="external-link" href="https://design.google.com">design
+  principles</a> for your app.
+</p>
diff --git a/docs/html/distribute/stories/apps/segundamano.jd b/docs/html/distribute/stories/apps/segundamano.jd
new file mode 100644
index 0000000..4cbf817
--- /dev/null
+++ b/docs/html/distribute/stories/apps/segundamano.jd
@@ -0,0 +1,63 @@
+page.title=Segundamano Develops Android-First as Its Fastest Channel for Growth
+page.metaDescription=Segundamano developed Android app to increase potential for growth.
+page.tags="developerstory", "apps", "googleplay"
+page.image=images/cards/distribute/stories/segundamano.png
+page.timestamp=1468270110
+
+@jd:body
+
+<div class="figure" style="width:113px">
+  <img src="{@docRoot}images/distribute/stories/segundamano-icon.png" height=
+  "113">
+</div>
+
+<h3>
+  Background
+</h3>
+
+<p>
+  <a class="external-link" href=
+  "https://play.google.com/store/apps/details?id=mx.segundamano.android">Segundamano</a>
+  is a leading shopping application in Mexico for second-hand products. They
+  started by placing classified ads in newspapers, progressed to desktop, and
+  over the past year have seen significant growth in mobile, which now accounts
+  for 70% of their business. They have also seen <strong>270% year-over-year
+  growth on the Android platform alone</strong>.
+</p>
+
+<h3>
+  What they did
+</h3>
+
+<p>
+  Segundamano shifted focus to mobile with their Android app because of the
+  high potential for growth. From July 2015 to January 2016, they saw an
+  increase of 55% in the number of classified ads on Android, higher than any
+  other platform. To leverage this momentum, Segundamano implemented two new
+  features on Android: premium offers and push notifications. Segundamano also
+  decided to implement material design in order to improve the in-app
+  experience and streamline the sales process for users.
+</p>
+
+<h3>
+  Results
+</h3>
+
+<p>
+  Following Segundamano’s enhancements to the user experience, they've seen an
+  increase in their star rating, a 4.7% lift in monthly active users, and a 7%
+  increase in sales of premium listings. Additionally, year-to-date, their
+  <strong>installs are over seven times higher on Android than on other
+  platforms</strong>.
+</p>
+
+<h3>
+  Get started
+</h3>
+
+<p>
+  Learn more about simplifying your in-app experience with <a href=
+  "{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a>
+  and the <a href="{@docRoot}design/material/index.html">material design
+  guidelines</a>.
+</p>
\ No newline at end of file
diff --git a/docs/html/distribute/stories/apps/tapps.jd b/docs/html/distribute/stories/apps/tapps.jd
new file mode 100644
index 0000000..1292139
--- /dev/null
+++ b/docs/html/distribute/stories/apps/tapps.jd
@@ -0,0 +1,366 @@
+page.title=Tapps Games Increases Installs by More Than 20% with Store Listing Experiments
+page.metaDescription=Tapps Games increased their use of store listing experiments in the Developer Console, with impressive results.
+page.tags="developerstory", "apps", "googleplay"
+page.image=images/cards/distribute/stories/tapps.png
+page.timestamp=1468270108
+
+@jd:body
+
+<style type="text/css">
+  span.positive{
+    color:green;
+    font-size: 125%;
+    font-weight:bold;">
+  }
+  span.negative{
+    color:red;
+    font-size: 125%;
+    font-weight:bold;">
+  }
+</style>
+
+<div class="figure" style="width:215px">
+  <img src="{@docRoot}images/distribute/stories/tapps-logo.png" height="65">
+</div>
+
+<h3>
+  Background
+</h3>
+
+<p>
+  <a class="external-link" href=
+  "https://play.google.com/store/apps/dev?id=6615809648420562690">Tapps</a> is
+  a mobile game publisher in São Paulo, Brazil. With a mission of <em>creating
+  fun for everyone</em>, Tapps has a portfolio of over 200 titles on the Google
+  Play Store, with roughly 70% of their installs coming from Android. Store
+  listing experiments have provided invaluable metrics to help their growing
+  team understand what makes the most effective product listings.
+</p>
+
+<h3>
+  What they did
+</h3>
+
+<p>
+  Tapps has increased their use of store listing experiments in the Developer
+  Console. They recently expanded their marketing team to allocate greater time
+  and designated resources to the Developer Console tools. <strong>"We can’t
+  stress enough how much value the store listing experiments have brought us
+  over the past months. Right now, our marketing team has a substantial time
+  allocated to these tests every week,"</strong> said Felipe Watanabe, head of
+  marketing at Tapps. With icons and screenshots, Tapps tested variations in
+  color, character positioning, and the overall amount of graphic detail. In
+  the description tests, they found that shorter messages with clear calls to
+  action and appropriate language localizations were most successful.
+</p>
+
+<h3>
+  Results
+</h3>
+
+<p>
+  By frequently conducting store listing experiments, Tapps gained valuable
+  insights that they have applied across their greater portfolio of games.
+  Results showed that shortening messaging, using contrasting colors,
+  reordering screenshots, and simplifying graphics often led to variant results
+  representing an average increase in performance between 5% and 50%. After
+  making changes based on the test results, Tapps saw <strong>install rates
+  increase beyond 20-30%</strong>.
+</p>
+
+<h4>
+  Screen tests
+</h4>
+
+<p>
+  The following table compares the install rates for three apps based on
+  changes to each app's screenshot.
+</p>
+
+<p class="table-caption">
+  <strong>Table 1</strong>. Screen test results
+</p>
+
+<table>
+  <tr>
+    <th>
+      Original
+    </th>
+    <th>
+      Variant
+    </th>
+    <th>
+      Variant results
+    </th>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-3.png"
+      width="240">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-var-3.png"
+      width="240">
+    </td>
+    <td>
+      <span class="positive">+25%</span>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-1.png"
+      width="240">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-var-1.png"
+      width="240">
+    </td>
+    <td>
+      <span class="positive">+17.1%</span>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-orig-2.png"
+      width="240">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-screen-var-2.png"
+      width="240">
+    </td>
+    <td>
+      <span class="positive">+7.4%</span>
+    </td>
+  </tr>
+
+</table>
+
+<h4>
+  Icon tests
+</h4>
+
+<p>
+  The following tables compare install rates for three apps based on changes
+  to each app's icon.
+</p>
+
+<p class="table-caption">
+  <strong>Table 2</strong>. Icon 1 test results
+</p>
+
+<table>
+  <tr>
+    <th>
+      Original
+    </th>
+    <th>
+      Variant 1
+    </th>
+    <th>
+      Variant 2
+    </th>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-1.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-1.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-1-2.png">
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      ---
+    </td>
+    <td>
+      <span class="negative">-29.6%</span>
+    </td>
+    <td>
+      <span class="positive">+20.8%</span>
+    </td>
+  </tr>
+</table>
+
+<p class="table-caption">
+  <strong>Table 3</strong>. Icon 2 test results
+</p>
+
+<table>
+  <tr>
+    <th>
+      Original
+    </th>
+    <th>
+      Variant 1
+    </th>
+    <th>
+      Variant 2
+    </th>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-2.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-2.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-2-2.png">
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      ---
+    </td>
+    <td>
+      <span class="positive">+5.1%</span>
+    </td>
+    <td>
+      <span class="positive">+19.7%</span>
+    </td>
+  </tr>
+</table>
+
+<p class="table-caption">
+  <strong>Table 4</strong>. Icon 3 test results
+</p>
+
+<table>
+  <tr>
+    <th>
+      Original
+    </th>
+    <th>
+      Variant 1
+    </th>
+    <th>
+      Variant 2
+    </th>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-orig-3.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-3.png">
+    </td>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-icon-var-3-2.png">
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      ---
+    </td>
+    <td>
+      <span class="negative">-17.7%</span>
+    </td>
+    <td>
+      <span class="positive">+50.7%</span>
+    </td>
+  </tr>
+</table>
+
+<h4>
+  Description tests
+</h4>
+
+<p>
+  The following table compares install rates for three apps based on changes to
+  each app's description text.
+</p>
+
+<p class="table-caption">
+  <strong>Table 5</strong>. Description test results
+</p>
+
+<table>
+  <tr>
+    <th>
+      Game
+    </th>
+    <th>
+      Original
+    </th>
+    <th>
+      Variant
+    </th>
+    <th>
+      Variant results
+    </th>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-logic-pic.png">
+      <strong>Logic Pic</strong>
+    </td>
+    <td>
+      <em>"Use logic to solve fun puzzles and discover hidden pictures! Logic
+      Pic is free!"</em>
+    </td>
+    <td>
+      <strong><em>"Discover all the hidden pictures in this challenging classic
+      japanese puzzle!"</em></strong>
+    </td>
+    <td>
+      <span class="positive">+10.7%</span>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-candy-hills.png"
+      width="96"> <strong>Candy Hills</strong>
+    </td>
+    <td>
+      <em>"What will your candy park look like? Build it now in Candy
+      Hills!"</em>
+    </td>
+    <td>
+      <strong><em>"Build your own sweet candy park in Candy
+      Hills!"</em></strong>
+    </td>
+    <td>
+      <span class="positive">+8.2%</span>
+    </td>
+  </tr>
+
+  <tr>
+    <td>
+      <img src="{@docRoot}images/distribute/stories/tapps-villains-corp.png"
+      width="96"> <strong>Villains Corp.</strong>
+    </td>
+    <td>
+      <em>"Be a real villain and CONQUER THE WORLD!"</em>
+    </td>
+    <td>
+      <strong><em>"Mwahahaha! Be a real villain and CONQUER THE
+      WORLD!"</em></strong>
+    </td>
+    <td>
+      <span class="positive">+6.8%</span>
+    </td>
+  </tr>
+</table>
+
+<h3>
+  Get started
+</h3>
+
+<p>
+  Find out more about <a href=
+  "{@docRoot}distribute/users/experiments.html">store listing experiments</a>.
+</p>
diff --git a/docs/html/distribute/stories/apps/upbeat-games.jd b/docs/html/distribute/stories/apps/upbeat-games.jd
new file mode 100644
index 0000000..02222d3
--- /dev/null
+++ b/docs/html/distribute/stories/apps/upbeat-games.jd
@@ -0,0 +1,69 @@
+page.title=Witch Puzzle Achieves 98% of International Installs on Android
+page.metaDescription=Witch Puzzle localized their app into 12 languages.
+page.tags="developerstory", "apps", "googleplay"
+page.image=images/cards/distribute/stories/witch-puzzle.png
+page.timestamp=1468270106
+
+@jd:body
+
+
+<div class="figure">
+  <img src="{@docRoot}images/distribute/stories/witch-puzzle-icon.png"
+  width="113">
+</div>
+
+<h3>
+  Background
+</h3>
+
+<p>
+  Located in São Paulo, Brazil, <a class="external-link" href=
+  "https://play.google.com/store/apps/dev?id=8995071809141037139">Upbeat
+  Games</a> is an indie game developer with a mission to build fun and easy
+  games that anyone can play. As a small team, the Upbeat crew reacted quickly
+  to their game’s growing installs in Asian countries, and is now seeing strong
+  international growth with their game <a class="external-link" href=
+  "https://play.google.com/store/apps/details?id=com.upbeatgames.witchpuzzle">Witch
+  Puzzle</a>.
+</p>
+
+<h3>
+  What they did
+</h3>
+
+<p>
+  After noticing that Witch Puzzle was gaining traction throughout Asia, Upbeat
+  localized their game into 12 languages, prioritizing countries with an
+  existing user base and high gross national income (GNI). This led to a direct
+  increase in installs.
+</p>
+
+<div class="figure">
+  <img src="{@docRoot}images/distribute/stories/japanese-witch-puzzle.png"
+  width="214">
+  <p class="img-caption">
+    Japanese version of Witch Puzzle
+  </p>
+</div>
+
+<h3>
+  Results
+</h3>
+
+<p>
+  “In the last three months, 98% of our international installs for Witch Puzzle
+  came from Android,” said Vinicius Sormani Heimbeck, Upbeat’s founder. Upbeat
+  applied these learnings across their portfolio of games. Now, <strong>75% of
+  their portfolio’s revenue is driven by Android</strong>.
+</p>
+
+<h3>
+  Get started
+</h3>
+
+<p>
+  Use the <a href=
+  "{@docRoot}distribute/tools/localization-checklist.html">Localization
+  Checklist</a> to learn more about tailoring your app for different markets to
+  drive installs and revenue, and to create a better overall user experience.
+</p>
diff --git a/docs/html/images/cards/distribute/stories/aftenposten.png b/docs/html/images/cards/distribute/stories/aftenposten.png
new file mode 100644
index 0000000..60cb851
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/aftenposten.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/el-mundo.png b/docs/html/images/cards/distribute/stories/el-mundo.png
new file mode 100644
index 0000000..23db783
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/el-mundo.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/segundamano.png b/docs/html/images/cards/distribute/stories/segundamano.png
new file mode 100644
index 0000000..60e873c
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/segundamano.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/tapps.png b/docs/html/images/cards/distribute/stories/tapps.png
new file mode 100644
index 0000000..e01e3ad
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/tapps.png
Binary files differ
diff --git a/docs/html/images/cards/distribute/stories/witch-puzzle.png b/docs/html/images/cards/distribute/stories/witch-puzzle.png
new file mode 100644
index 0000000..c336f1b
--- /dev/null
+++ b/docs/html/images/cards/distribute/stories/witch-puzzle.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/aftenposten-icon.png b/docs/html/images/distribute/stories/aftenposten-icon.png
new file mode 100644
index 0000000..60cb851
--- /dev/null
+++ b/docs/html/images/distribute/stories/aftenposten-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/el-mundo-icon.png b/docs/html/images/distribute/stories/el-mundo-icon.png
new file mode 100644
index 0000000..23db783
--- /dev/null
+++ b/docs/html/images/distribute/stories/el-mundo-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/japanese-witch-puzzle.png b/docs/html/images/distribute/stories/japanese-witch-puzzle.png
new file mode 100644
index 0000000..6a7ef13
--- /dev/null
+++ b/docs/html/images/distribute/stories/japanese-witch-puzzle.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/segundamano-icon.png b/docs/html/images/distribute/stories/segundamano-icon.png
new file mode 100644
index 0000000..60e873c
--- /dev/null
+++ b/docs/html/images/distribute/stories/segundamano-icon.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-candy-hills.png b/docs/html/images/distribute/stories/tapps-candy-hills.png
new file mode 100644
index 0000000..14dcb94
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-candy-hills.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-1.png b/docs/html/images/distribute/stories/tapps-icon-orig-1.png
new file mode 100644
index 0000000..44af423
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-2.png b/docs/html/images/distribute/stories/tapps-icon-orig-2.png
new file mode 100644
index 0000000..1b36255
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-orig-3.png b/docs/html/images/distribute/stories/tapps-icon-orig-3.png
new file mode 100644
index 0000000..2f393f8
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-orig-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-1-2.png b/docs/html/images/distribute/stories/tapps-icon-var-1-2.png
new file mode 100644
index 0000000..fecab6e
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-1-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-1.png b/docs/html/images/distribute/stories/tapps-icon-var-1.png
new file mode 100644
index 0000000..77bd02a
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-2-2.png b/docs/html/images/distribute/stories/tapps-icon-var-2-2.png
new file mode 100644
index 0000000..84166c4
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-2-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-2.png b/docs/html/images/distribute/stories/tapps-icon-var-2.png
new file mode 100644
index 0000000..939c2fd
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-3-2.png b/docs/html/images/distribute/stories/tapps-icon-var-3-2.png
new file mode 100644
index 0000000..4aa782d
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-3-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-icon-var-3.png b/docs/html/images/distribute/stories/tapps-icon-var-3.png
new file mode 100644
index 0000000..1e44fdf
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-icon-var-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-logic-pic.png b/docs/html/images/distribute/stories/tapps-logic-pic.png
new file mode 100644
index 0000000..5029f79
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-logic-pic.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-logo.png b/docs/html/images/distribute/stories/tapps-logo.png
new file mode 100644
index 0000000..e01e3ad
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-logo.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-1.png b/docs/html/images/distribute/stories/tapps-screen-orig-1.png
new file mode 100644
index 0000000..d54e75c
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-2.png b/docs/html/images/distribute/stories/tapps-screen-orig-2.png
new file mode 100644
index 0000000..a2d18e3
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-orig-3.png b/docs/html/images/distribute/stories/tapps-screen-orig-3.png
new file mode 100644
index 0000000..e01fe20
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-orig-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-1.png b/docs/html/images/distribute/stories/tapps-screen-var-1.png
new file mode 100644
index 0000000..b930350
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-1.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-2.png b/docs/html/images/distribute/stories/tapps-screen-var-2.png
new file mode 100644
index 0000000..9ccb8a6
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-2.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-screen-var-3.png b/docs/html/images/distribute/stories/tapps-screen-var-3.png
new file mode 100644
index 0000000..8eb58e1
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-screen-var-3.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/tapps-villains-corp.png b/docs/html/images/distribute/stories/tapps-villains-corp.png
new file mode 100644
index 0000000..6e037da
--- /dev/null
+++ b/docs/html/images/distribute/stories/tapps-villains-corp.png
Binary files differ
diff --git a/docs/html/images/distribute/stories/witch-puzzle-icon.png b/docs/html/images/distribute/stories/witch-puzzle-icon.png
new file mode 100644
index 0000000..c336f1b
--- /dev/null
+++ b/docs/html/images/distribute/stories/witch-puzzle-icon.png
Binary files differ
diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd
index 3e95f3e..ff11e8e 100644
--- a/docs/html/preview/setup-sdk.jd
+++ b/docs/html/preview/setup-sdk.jd
@@ -77,32 +77,10 @@
 <h3 id="docs-dl">Get the N Preview reference documentation</h3>
 
 <p>Beginning with the Preview 4 release, the API reference for the
-N platform (API level 24) is now available online at <a href=
-  "{@docRoot}reference/">developer.android.com/reference/</a>.
-</p>
-
-<p>If you'd like an offline copy of the API reference, you can download it
-from the following table. The download also includes an incremental diff report
-for API changes between the Preview 3 and Preview 4 release, which is not
-available online.</p>
-
-<table>
-  <tr>
-    <th scope="col">Documentation</th>
-    <th scope="col">Checksums</th>
-  </tr>
-  <tr>
-    <td style="white-space: nowrap">
-    <a href="{@docRoot}shareables/preview/n-preview-4-docs.zip"
-      >n-preview-4-docs.zip</a></td>
-    <td width="100%">
-      MD5: f853e3ba0707083336dfa780b8fed9a7<br>
-      SHA-1: 36fcbc497cc2e63b1bc1d629c304b0ba43a88946
-    </td>
-  </tr>
-</table>
-
-
+  N platform (API level 24) is now available online at <a href=
+  "{@docRoot}reference/">developer.android.com/reference/</a>. There is also
+  an incremental diff report for <a href="{@docRoot}sdk/api_diff/24/changes.html"
+  >API changes between API levels 23 and 24</a>.</p>
 
 <h2 id="java8">Get the Java 8 JDK</h2>
 
diff --git a/docs/html/topic/performance/index.jd b/docs/html/topic/performance/index.jd
index 08c610f..e08db15 100644
--- a/docs/html/topic/performance/index.jd
+++ b/docs/html/topic/performance/index.jd
@@ -1,6 +1,6 @@
 page.title=Performance
 page.article=true
-page.metaDescription=Android Performance does nice things. Details to come.
+page.metaDescription=Improve your app's performance by learning how to optimize power consumption, launch times, and other important areas of performance.
 
 meta.tags="performance"
 page.tags="performance"
diff --git a/docs/html/topic/performance/launch-time.jd b/docs/html/topic/performance/launch-time.jd
index c9ce1d5..84d5fab 100644
--- a/docs/html/topic/performance/launch-time.jd
+++ b/docs/html/topic/performance/launch-time.jd
@@ -112,7 +112,7 @@
 </p>
 <br/>
 
-  <img src="{@docRoot}performance/images/cold-launch.png">
+  <img src="{@docRoot}topic/performance/images/cold-launch.png">
   <p class="img-caption">
     <strong>Figure 1.</strong> A visual representation of the important parts of
     a cold application launch.
@@ -262,7 +262,7 @@
 </p>
 <br/>
 
-  <img src="{@docRoot}performance/images/displayed-logcat.png">
+  <img src="{@docRoot}topic/performance/images/displayed-logcat.png">
   <p class="img-caption">
     <strong>Figure 2.</strong> Disabling filters, and
     finding the {@code Displayed} value in logcat.
diff --git a/libs/hwui/PropertyValuesAnimatorSet.h b/libs/hwui/PropertyValuesAnimatorSet.h
index 49021bc..f9274e1 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.h
+++ b/libs/hwui/PropertyValuesAnimatorSet.h
@@ -60,7 +60,7 @@
     virtual uint32_t dirtyMask();
     bool isInfinite() { return mIsInfinite; }
     void setVectorDrawable(VectorDrawableRoot* vd) { mVectorDrawable = vd; }
-    VectorDrawableRoot* getVectorDrawable() const { return mVectorDrawable; }
+    VectorDrawableRoot* getVectorDrawable() const { return mVectorDrawable.get(); }
     AnimationListener* getOneShotListener() { return mOneShotListener.get(); }
     void clearOneShotListener() { mOneShotListener = nullptr; }
     uint32_t getRequestId() const { return mRequestId; }
@@ -78,7 +78,7 @@
     std::vector< std::unique_ptr<PropertyAnimator> > mAnimators;
     float mLastFraction = 0.0f;
     bool mInitialized = false;
-    VectorDrawableRoot* mVectorDrawable = nullptr;
+    sp<VectorDrawableRoot> mVectorDrawable;
     bool mIsInfinite = false;
     // This request id gets incremented (on UI thread only) when a new request to modfiy the
     // lifecycle of an animation happens, namely when start/end/reset/reverse is called.
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 7d5939c..81cc93d 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -264,7 +264,6 @@
      */
     public static final int ENCODING_IEC61937 = 13;
     /** Audio data format: DOLBY TRUEHD compressed
-     * @hide
      **/
     public static final int ENCODING_DOLBY_TRUEHD = 14;
 
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 8d4a151..31c7a32 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -3498,7 +3498,7 @@
          * @param extra an extra code, specific to the info. Typically
          * implementation dependent.
          * @return True if the method handled the info, false if it didn't.
-         * Returning false, or not having an OnErrorListener at all, will
+         * Returning false, or not having an OnInfoListener at all, will
          * cause the info to be discarded.
          */
         boolean onInfo(MediaPlayer mp, int what, int extra);
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index 0f7dc9a..b262d97 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -181,10 +181,15 @@
      * @return
      */
     boolean isRestricted_sync() {
+        // check app ops
+        if (mHasAppOpsPlayAudio) {
+            return false;
+        }
+        // check bypass flag
         if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
             return false;
         }
-        return !mHasAppOpsPlayAudio;
+        return true;
     }
 
     // Abstract methods a subclass needs to implement
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 5ede1d5..9fafda4 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -505,27 +505,31 @@
     }
 
     private boolean isRestricted() {
-        IAudioService service = getService();
-        boolean cameraSoundForced = false;
-
-        try {
-            cameraSoundForced = service.isCameraSoundForced();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Cannot access AudioService in isRestricted()");
-        }
-
-        if (cameraSoundForced &&
-                ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0)
-// FIXME: should also check usage when set properly by camera app
-//                && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-                ) {
+        // check app ops
+        if (mHasAppOpsPlayAudio) {
             return false;
         }
-
+        // check bypass flag
         if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
             return false;
         }
-        return !mHasAppOpsPlayAudio;
+        // check force audibility flag and camera restriction
+        if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) != 0) {
+// FIXME: should also check usage when set properly by camera app
+//          && (mAttributes.getUsage() == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+            boolean cameraSoundForced = false;
+            try {
+                cameraSoundForced = getService().isCameraSoundForced();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Cannot access AudioService in isRestricted()");
+            } catch (NullPointerException e) {
+                Log.e(TAG, "Null AudioService in isRestricted()");
+            }
+            if (cameraSoundForced) {
+                return false;
+            }
+        }
+        return true;
     }
 
     private void updateAppOpsPlayAudio() {
diff --git a/packages/PrintSpooler/res/drawable/print_button.xml b/packages/PrintSpooler/res/drawable/print_button.xml
index b59afba..0114103 100644
--- a/packages/PrintSpooler/res/drawable/print_button.xml
+++ b/packages/PrintSpooler/res/drawable/print_button.xml
@@ -16,7 +16,7 @@
 -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/print_button_tint_color">
+    android:color="?android:attr/colorControlHighlight">
     <item
         android:drawable="@drawable/print_button_background">
     </item>
diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml
index 47e616e..9464c67 100644
--- a/packages/PrintSpooler/res/values/colors.xml
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -16,8 +16,6 @@
 
 <resources>
 
-    <color name="print_button_tint_color">#EEFF41</color>
-
     <color name="print_preview_scrim_color">#99000000</color>
 
     <color name="print_preview_background_color">#F2F1F2</color>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 28e9a45..1928f92 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -799,7 +799,8 @@
 
         // If this is a setting that is currently restricted for this user, do not allow
         // unrestricting changes.
-        if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value)) {
+        if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
+                Binder.getCallingUid())) {
             return false;
         }
 
@@ -930,7 +931,8 @@
 
         // If this is a setting that is currently restricted for this user, do not allow
         // unrestricting changes.
-        if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value)) {
+        if (isGlobalOrSecureSettingRestrictedForUser(name, callingUserId, value,
+                Binder.getCallingUid())) {
             return false;
         }
 
@@ -1153,7 +1155,7 @@
      * @return true if the change is prohibited, false if the change is allowed.
      */
     private boolean isGlobalOrSecureSettingRestrictedForUser(String setting, int userId,
-            String value) {
+            String value, int callingUid) {
         String restriction;
         switch (setting) {
             case Settings.Secure.LOCATION_MODE:
@@ -1191,6 +1193,15 @@
                 restriction = UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS;
                 break;
 
+            case Settings.Secure.ALWAYS_ON_VPN_APP:
+            case Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN:
+                // Whitelist system uid (ConnectivityService) and root uid to change always-on vpn
+                if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
+                    return false;
+                }
+                restriction = UserManager.DISALLOW_CONFIG_VPN;
+                break;
+
             default:
                 if (setting != null && setting.startsWith(Settings.Global.DATA_ROAMING)) {
                     if ("0".equals(value)) return false;
@@ -2074,7 +2085,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 128;
+            private static final int SETTINGS_VERSION = 129;
 
             private final int mUserId;
 
@@ -2334,6 +2345,37 @@
                     currentVersion = 128;
                 }
 
+                if (currentVersion == 128) {
+                    // Version 128: Allow OEMs to grant DND access to default apps. Note that
+                    // the new apps are appended to the list of already approved apps.
+                    final SettingsState systemSecureSettings =
+                            getSecureSettingsLocked(userId);
+
+                    final Setting policyAccess = systemSecureSettings.getSettingLocked(
+                            Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
+                    String defaultPolicyAccess = getContext().getResources().getString(
+                            com.android.internal.R.string.config_defaultDndAccessPackages);
+                    if (!TextUtils.isEmpty(defaultPolicyAccess)) {
+                        if (policyAccess.isNull()) {
+                            systemSecureSettings.insertSettingLocked(
+                                    Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
+                                    defaultPolicyAccess,
+                                    SettingsState.SYSTEM_PACKAGE_NAME);
+                        } else {
+                            StringBuilder currentSetting =
+                                    new StringBuilder(policyAccess.getValue());
+                            currentSetting.append(":");
+                            currentSetting.append(defaultPolicyAccess);
+                            systemSecureSettings.updateSettingLocked(
+                                    Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
+                                    currentSetting.toString(),
+                                    SettingsState.SYSTEM_PACKAGE_NAME);
+                        }
+                    }
+
+                    currentVersion = 129;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 // Return the current version.
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
new file mode 100644
index 0000000..778ccbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
@@ -0,0 +1,27 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:alpha="0.3">
+
+    <path
+        android:fillColor="#FFF"
+        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
new file mode 100644
index 0000000..aaca663
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
@@ -0,0 +1,26 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="64dp"
+    android:height="64dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFF"
+        android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
+
+</vector>
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
index 1f24ab0..8abfcf6 100644
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ b/packages/SystemUI/res/layout/battery_detail.xml
@@ -25,7 +25,7 @@
         android:id="@+id/charge_and_estimation"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingStart="72dp"
+        android:paddingStart="16dp"
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:textColor="?android:attr/colorAccent" />
 
diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index c062b6d..f6ca862 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -22,19 +22,9 @@
     android:background="@drawable/btn_borderless_rect"
     android:gravity="center">
 
-    <ImageView
-        android:id="@*android:id/up"
-        android:layout_width="56dp"
-        android:layout_height="56dp"
-        android:layout_marginEnd="16dp"
-        android:padding="16dp"
-        android:clickable="true"
-        android:background="?android:attr/selectableItemBackground"
-        android:contentDescription="@*android:string/action_bar_up_description"
-        android:src="?android:attr/homeAsUpIndicator" />
-
     <TextView
         android:id="@android:id/title"
+        android:paddingStart="16dp"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 3b8b909..6673d6e 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -111,7 +111,7 @@
         android:layout_alignParentTop="true"
         android:paddingStart="16dp"
         android:paddingEnd="16dp"
-        android:paddingTop="2dp"
+        android:paddingTop="6dp"
         android:visibility="gone"
         android:textAppearance="@style/TextAppearance.StatusBar.Expanded.EmergencyCallsOnly"
         android:text="@*android:string/emergency_calls_only"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e1cbbc5..ae4f3cf 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -375,6 +375,8 @@
 
     <!-- The font size of the date in QS -->
     <dimen name="qs_date_collapsed_size">14sp</dimen>
+    <!-- Amount the date/time move when emergency calls only is present -->
+    <dimen name="qs_date_time_translation">8dp</dimen>
 
     <!-- Battery level text padding end when in expanded QS and on Keyguard -->
     <dimen name="battery_level_padding_end">2dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3ed0711..5324968 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -752,6 +752,12 @@
     <string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string>
     <!-- QuickSettings: Work mode [CHAR LIMIT=NONE] -->
     <string name="quick_settings_work_mode_label">Work mode</string>
+    <!-- QuickSettings: Label for the toggle to activate Night display (renamed "Night Light" with title caps). [CHAR LIMIT=20] -->
+    <string name="quick_settings_night_display_label">Night Light</string>
+    <!-- QuickSettings: Summary for the toggle to deactivate Night display when it's on (renamed "Night Light" with title caps). [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_night_display_summary_on">Night Light on, tap to turn off</string>
+    <!-- QuickSettings: Label for the toggle to activate Night display when it's off (renamed "Night Light" with title caps). [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_night_display_summary_off">Night Light off, tap to turn on</string>
 
     <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
     <string name="recents_empty_message">No recent items</string>
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index af2a286..9eceeac 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -47,7 +47,7 @@
     private static final long TIMEOUT_SERVICE = 2500;
     private static final long TIMEOUT_ACTIVITY = 1000;
 
-    private final Context mContext;
+    protected final Context mContext;
     private final WindowManager mWindowManager;
     private final AssistDisclosure mAssistDisclosure;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index a40e5b7..c63be9c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -63,7 +63,6 @@
     private boolean mScanState;
     private boolean mClosingDetail;
     private boolean mFullyExpanded;
-    private View mQsDetailHeaderBack;
     private BaseStatusBarHeader mHeader;
     private boolean mTriggeredExpand;
     private int mOpenX;
@@ -92,7 +91,6 @@
         mDetailDoneButton = (TextView) findViewById(android.R.id.button1);
 
         mQsDetailHeader = findViewById(R.id.qs_detail_header);
-        mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
         mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
         mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
         mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
@@ -109,7 +107,6 @@
                 mQsPanel.closeDetail();
             }
         };
-        mQsDetailHeaderBack.setOnClickListener(doneListener);
         mDetailDoneButton.setOnClickListener(doneListener);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
new file mode 100644
index 0000000..9a3549e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import android.content.Intent;
+import android.provider.Settings;
+import android.widget.Switch;
+
+import com.android.internal.app.NightDisplayController;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+
+public class NightDisplayTile extends QSTile<QSTile.BooleanState>
+        implements NightDisplayController.Callback {
+
+    private final NightDisplayController mController;
+
+    public NightDisplayTile(Host host) {
+        super(host);
+        mController = new NightDisplayController(mContext);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return NightDisplayController.isAvailable(mContext);
+    }
+
+    @Override
+    public BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+    @Override
+    protected void handleClick() {
+        final boolean activated = !mState.value;
+        MetricsLogger.action(mContext, getMetricsCategory(), activated);
+        mController.setActivated(activated);
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+        final boolean isActivated = mController.isActivated();
+        state.value = isActivated;
+        state.label = mContext.getString(R.string.quick_settings_night_display_label);
+        state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_night_display_on
+                : R.drawable.ic_qs_night_display_off);
+        state.contentDescription = mContext.getString(isActivated
+                ? R.string.quick_settings_night_display_summary_on
+                : R.string.quick_settings_night_display_summary_off);
+        state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+                = Switch.class.getName();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.QS_NIGHT_DISPLAY;
+    }
+
+    @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_DISPLAY_SETTINGS);
+    }
+
+    @Override
+    protected void setListening(boolean listening) {
+        if (listening) {
+            mController.setListener(this);
+            refreshState();
+        } else {
+            mController.setListener(null);
+        }
+    }
+
+    @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_night_display_label);
+    }
+
+    @Override
+    public void onActivated(boolean activated) {
+        refreshState();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index b53a999..63f726b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -49,6 +49,13 @@
         mViews.clear();
     }
 
+    void addView(View view, boolean landscape) {
+        addView(view);
+        if (view instanceof ButtonInterface) {
+            ((ButtonInterface) view).setLandscape(landscape);
+        }
+    }
+
     void addView(View view) {
         mViews.add(view);
         view.setOnClickListener(mClickListener);
@@ -178,5 +185,7 @@
         void setImageDrawable(@Nullable Drawable drawable);
 
         void abortCurrentGesture();
+
+        void setLandscape(boolean landscape);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 67699737..06c8b68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -280,7 +280,7 @@
             params.width = (int) (params.width * size);
         }
         parent.addView(v);
-        addToDispatchers(v);
+        addToDispatchers(v, landscape);
         View lastView = landscape ? mLastRot90 : mLastRot0;
         if (lastView != null) {
             v.setAccessibilityTraversalAfter(lastView.getId());
@@ -327,16 +327,16 @@
         return buttonSpec.substring(0, buttonSpec.indexOf(SIZE_MOD_START));
     }
 
-    private void addToDispatchers(View v) {
+    private void addToDispatchers(View v, boolean landscape) {
         if (mButtonDispatchers != null) {
             final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
             if (indexOfKey >= 0) {
-                mButtonDispatchers.valueAt(indexOfKey).addView(v);
+                mButtonDispatchers.valueAt(indexOfKey).addView(v, landscape);
             } else if (v instanceof ViewGroup) {
                 final ViewGroup viewGroup = (ViewGroup)v;
                 final int N = viewGroup.getChildCount();
                 for (int i = 0; i < N; i++) {
-                    addToDispatchers(viewGroup.getChildAt(i));
+                    addToDispatchers(viewGroup.getChildAt(i), landscape);
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 9bc5426..fb7afc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -883,9 +883,9 @@
         mLightStatusBarController = new LightStatusBarController(mIconController,
                 mBatteryController);
         mKeyguardMonitor = new KeyguardMonitor(mContext);
+        mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
+                mHandler, this);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
-            mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
-                    mHandler, this);
             createUserSwitcher();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index ca7f905..15e235d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -52,6 +52,7 @@
 import com.android.systemui.qs.tiles.HotspotTile;
 import com.android.systemui.qs.tiles.IntentTile;
 import com.android.systemui.qs.tiles.LocationTile;
+import com.android.systemui.qs.tiles.NightDisplayTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.qs.tiles.UserTile;
 import com.android.systemui.qs.tiles.WifiTile;
@@ -440,6 +441,7 @@
         else if (tileSpec.equals("user")) return new UserTile(this);
         else if (tileSpec.equals("battery")) return new BatteryTile(this);
         else if (tileSpec.equals("saver")) return new DataSaverTile(this);
+        else if (tileSpec.equals("night")) return new NightDisplayTile(this);
         // Intent tiles.
         else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
         else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index 85303f4..21db64f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -37,11 +37,11 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSAnimator;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSPanel.Callback;
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.TouchAnimator;
+import com.android.systemui.qs.TouchAnimator.Builder;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.NextAlarmController.NextAlarmChangeCallback;
@@ -84,13 +84,13 @@
     private ImageView mMultiUserAvatar;
 
 
-    private TouchAnimator mSecondHalfAnimator;
-    private TouchAnimator mFirstHalfAnimator;
+    private TouchAnimator mAnimator;
     protected TouchAnimator mSettingsAlpha;
     private float mExpansionAmount;
     private QSTileHost mHost;
     private View mEdit;
     private boolean mShowFullAlarm;
+    private float mDateTimeTranslation;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -111,6 +111,7 @@
         mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group);
         mDateTimeGroup.setPivotX(0);
         mDateTimeGroup.setPivotY(0);
+        mDateTimeTranslation = getResources().getDimension(R.dimen.qs_date_time_translation);
         mShowFullAlarm = getResources().getBoolean(R.bool.quick_settings_show_full_alarm);
 
         mExpandIndicator = (ExpandableIndicator) findViewById(R.id.expand_indicator);
@@ -152,15 +153,13 @@
         FontSizeUtils.updateFontSize(mAlarmStatus, R.dimen.qs_date_collapsed_size);
         FontSizeUtils.updateFontSize(mEmergencyOnly, R.dimen.qs_emergency_calls_only_text_size);
 
-        mSecondHalfAnimator = new TouchAnimator.Builder()
+        Builder builder = new Builder()
                 .addFloat(mShowFullAlarm ? mAlarmStatus : findViewById(R.id.date), "alpha", 0, 1)
-                .addFloat(mEmergencyOnly, "alpha", 0, 1)
-                .build();
+                .addFloat(mEmergencyOnly, "alpha", 0, 1);
         if (mShowFullAlarm) {
-            mFirstHalfAnimator = new TouchAnimator.Builder()
-                    .addFloat(mAlarmStatusCollapsed, "alpha", 1, 0)
-                    .build();
+            builder.addFloat(mAlarmStatusCollapsed, "alpha", 1, 0);
         }
+        mAnimator = builder.build();
 
         updateSettingsAnimator();
     }
@@ -223,10 +222,8 @@
     @Override
     public void setExpansion(float headerExpansionFraction) {
         mExpansionAmount = headerExpansionFraction;
-        mSecondHalfAnimator.setPosition(headerExpansionFraction);
-        if (mShowFullAlarm) {
-            mFirstHalfAnimator.setPosition(headerExpansionFraction);
-        }
+        updateDateTimePosition();
+        mAnimator.setPosition(headerExpansionFraction);
         mSettingsAlpha.setPosition(headerExpansionFraction);
 
         updateAlarmVisibilities();
@@ -264,6 +261,7 @@
 
     protected void updateVisibilities() {
         updateAlarmVisibilities();
+        updateDateTimePosition();
         mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
                 ? View.VISIBLE : View.INVISIBLE);
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
@@ -274,6 +272,11 @@
         mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
     }
 
+    private void updateDateTimePosition() {
+        mDateTimeAlarmGroup.setTranslationY(mShowEmergencyCallsOnly
+                ? mExpansionAmount * mDateTimeTranslation : 0);
+    }
+
     private void updateListeners() {
         if (mListening) {
             mNextAlarmController.addStateChangedCallback(this);
@@ -315,7 +318,8 @@
     public void onClick(View v) {
         if (v == mSettingsButton) {
             MetricsLogger.action(mContext,
-                    MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH);
+                    mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
+                            : MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
             if (mSettingsButton.isTunerClick()) {
                 if (TunerService.isTunerEnabled(mContext)) {
                     TunerService.showResetRequest(mContext, new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index d8b1a62..3df7590 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -265,6 +265,11 @@
     public void setImageDrawable(@Nullable Drawable drawable) {
         super.setImageDrawable(drawable);
     }
+
+    @Override
+    public void setLandscape(boolean landscape) {
+        //no op
+    }
 }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 7de3879..e00674a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2347,6 +2347,7 @@
         if (hasAddEvent) {
             // This child was just added lets remove all events.
             mHeadsUpChangeAnimations.removeAll(mTmpList);
+            ((ExpandableNotificationRow ) child).setHeadsupDisappearRunning(false);
         }
         mTmpList.clear();
         return hasAddEvent;
@@ -3093,6 +3094,16 @@
         requestChildrenUpdate();
         runAnimationFinishedRunnables();
         clearViewOverlays();
+        clearHeadsUpDisappearRunning();
+    }
+
+    private void clearHeadsUpDisappearRunning() {
+        for (int i = 0; i < getChildCount(); i++) {
+            View view = getChildAt(i);
+            if (view instanceof ExpandableNotificationRow) {
+                ((ExpandableNotificationRow) view).setHeadsupDisappearRunning(false);
+            }
+        }
     }
 
     private void clearViewOverlays() {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
index cc0ffb0..1ea23bb 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerZenModePanel.java
@@ -54,7 +54,6 @@
         mHeaderSwitch = findViewById(R.id.tuner_zen_switch);
         mHeaderSwitch.setVisibility(View.VISIBLE);
         mHeaderSwitch.setOnClickListener(this);
-        mHeaderSwitch.findViewById(com.android.internal.R.id.up).setVisibility(View.GONE);
         ((TextView) mHeaderSwitch.findViewById(android.R.id.title)).setText(
                 R.string.quick_settings_dnd_label);
         mZenModePanel = (ZenModePanel) findViewById(R.id.zen_mode_panel);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 45e3e7e..ba59c2f0 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -33,73 +33,61 @@
     // OPEN: Settings > Accessibility
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY = 2;
 
     // OPEN: Settings > Accessibility > Captions
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY_CAPTION_PROPERTIES = 3;
 
     // OPEN: Settings > Accessibility > [Service]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY_SERVICE = 4;
 
     // OPEN: Settings > Accessibility > Color correction
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY_TOGGLE_DALTONIZER = 5;
 
     // OPEN: Settings > Accessibility > Accessibility shortcut
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE = 6;
 
     // OPEN: Settings > Accessibility > Magnification gestures
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION = 7;
 
     // OPEN: Settings > Accounts
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCOUNT = 8;
 
     // OPEN: Settings > Accounts > [Single Account Sync Settings]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCOUNTS_ACCOUNT_SYNC = 9;
 
     // OPEN: Settings > Accounts > Add an account
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
 
     // OPEN: Settings > Accounts > [List of accounts when more than one]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACCOUNTS_MANAGE_ACCOUNTS = 11;
 
     // OPEN: Settings > Cellular network settings > APNs
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APN = 12;
 
     // OPEN: Settings > More > Cellular network settings > APNs > [Edit APN]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APN_EDITOR = 13;
 
     // OBSOLETE
@@ -114,7 +102,6 @@
     // OPEN: Settings > Apps > Configure apps > App links > [App]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_APP_LAUNCH = 17;
 
     // OBSOLETE
@@ -123,19 +110,16 @@
     // OPEN: Settings > Internal storage > Apps storage > [App]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_APP_STORAGE = 19;
 
     // OPEN: Settings > Apps > [App info]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_INSTALLED_APP_DETAILS = 20;
 
     // OPEN: Settings > Memory > App usage > [App Memory usage]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_PROCESS_STATS_DETAIL = 21;
 
     // OBSOLETE
@@ -144,19 +128,16 @@
     // OPEN: Settings > Memory > App usage
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_PROCESS_STATS_UI = 23;
 
     // OPEN: Settings > Bluetooth
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     BLUETOOTH = 24;
 
     // OPEN: Choose Bluetooth device (ex: when sharing)
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     BLUETOOTH_DEVICE_PICKER = 25;
 
     // OBSOLETE
@@ -165,55 +146,46 @@
     // OPEN: Settings > Security > Choose screen lock
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CHOOSE_LOCK_GENERIC = 27;
 
     // OPEN: Settings > Security > Choose screen lock > Choose your password
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CHOOSE_LOCK_PASSWORD = 28;
 
     // OPEN: Settings > Security > Choose screen lock > Choose your pattern
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CHOOSE_LOCK_PATTERN = 29;
 
     // OPEN: Settings > Security > Choose screen lock > Confirm your password
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CONFIRM_LOCK_PASSWORD = 30;
 
     // OPEN: Settings > Security > Choose screen lock > Confirm your pattern
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CONFIRM_LOCK_PATTERN = 31;
 
     // OPEN: Settings > Security > Encrypt phone
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CRYPT_KEEPER = 32;
 
     // OPEN: Settings > Security > Encrypt phone > Confirm
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     CRYPT_KEEPER_CONFIRM = 33;
 
     // OPEN: Settings > Search results
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DASHBOARD_SEARCH_RESULTS = 34;
 
     // OPEN: Settings (Root page)
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DASHBOARD_SUMMARY = 35;
 
     // OBSOLETE
@@ -222,49 +194,41 @@
     // OPEN: Settings > Data usage
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DATA_USAGE_SUMMARY = 37;
 
     // OPEN: Settings > Date & time
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DATE_TIME = 38;
 
     // OPEN: Settings > Developer options
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVELOPMENT = 39;
 
     // OPEN: Settings > About phone
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVICEINFO = 40;
 
     // OPEN: Settings > About phone > Status > IMEI information
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVICEINFO_IMEI_INFORMATION = 41;
 
     // OPEN: Settings > Internal storage
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVICEINFO_STORAGE = 42;
 
     // OPEN: Settings > About phone > Status > SIM status
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVICEINFO_SIM_STATUS = 43;
 
     // OPEN: Settings > About phone > Status
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DEVICEINFO_STATUS = 44;
 
     // OBSOLETE
@@ -273,25 +237,21 @@
     // OPEN: Settings > Display
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DISPLAY = 46;
 
     // OPEN: Settings > Display > Daydream
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     DREAM = 47;
 
     // OPEN: Settings > Security > Screen lock > Secure start-up
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ENCRYPTION = 48;
 
     // OPEN: Settings > Security > Nexus Imprint
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FINGERPRINT = 49;
 
     // OBSOLETE
@@ -300,55 +260,46 @@
     // OPEN: Settings > Battery > History details
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FUELGAUGE_BATTERY_HISTORY_DETAIL = 51;
 
     // OPEN: Settings > Battery > Battery saver
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FUELGAUGE_BATTERY_SAVER = 52;
 
     // OPEN: Settings > Battery > [App Use details]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FUELGAUGE_POWER_USAGE_DETAIL = 53;
 
     // OPEN: Settings > Battery
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FUELGAUGE_POWER_USAGE_SUMMARY = 54;
 
     // OPEN: Settings > Home
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     HOME = 55;
 
     // OPEN: Settings > Security > SIM card lock settings
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ICC_LOCK = 56;
 
     // OPEN: Settings > Language & input
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     INPUTMETHOD_LANGUAGE = 57;
 
     // OPEN: Settings > Language & input > Physical keyboard
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     INPUTMETHOD_KEYBOARD = 58;
 
     // OPEN: Settings > Language & input > Spell checker
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     INPUTMETHOD_SPELL_CHECKERS = 59;
 
     // OBSOLETE
@@ -357,79 +308,66 @@
     // OPEN: Settings > Language & input > Personal dictionary
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     INPUTMETHOD_USER_DICTIONARY = 61;
 
     // OPEN: Settings > Language & input > Add word
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
 
     // OPEN: Settings > Location
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     LOCATION = 63;
 
     // OPEN: Settings > Location > Location mode
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     LOCATION_MODE = 64;
 
     // OPEN: Settings > Apps
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     MANAGE_APPLICATIONS = 65;
 
     // OPEN: Settings > Backup & reset > Factory data reset
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     MASTER_CLEAR = 66;
 
     // OPEN: Settings > Backup & reset > Factory data reset > Confirm
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     MASTER_CLEAR_CONFIRM = 67;
 
     // OPEN: Settings > Data usage > Network restrictions
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NET_DATA_USAGE_METERED = 68;
 
     // OPEN: Settings > More > Android Beam
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NFC_BEAM = 69;
 
     // OPEN: Settings > Tap & pay
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NFC_PAYMENT = 70;
 
     // OPEN: Settings > Sound & notification
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION = 71;
 
     // OPEN: Settings > Sound & notification > App notifications > [App]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_APP_NOTIFICATION = 72;
 
     // OPEN: Settings > Sound & notification > Other sounds
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_OTHER_SOUND = 73;
 
     // OBSOLETE
@@ -438,13 +376,11 @@
     // OPEN: Settings Widget > Notification log
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_STATION = 75;
 
     // OPEN: Settings > Sound & notification > Do not disturb
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE = 76;
 
     // OPEN: OBSOLETE
@@ -453,25 +389,21 @@
     // OPEN: Print job notification > Print job settings
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     PRINT_JOB_SETTINGS = 78;
 
     // OPEN: Settings > Printing > [Print Service]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     PRINT_SERVICE_SETTINGS = 79;
 
     // OPEN: Settings > Printing
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     PRINT_SETTINGS = 80;
 
     // OPEN: Settings > Backup & reset
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     PRIVACY = 81;
 
     //OBSOLETE
@@ -480,37 +412,31 @@
     // OPEN: Settings > Backup & reset > Network settings reset
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     RESET_NETWORK = 83;
 
     // OPEN: Settings > Backup & reset > Network settings reset > Confirm
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     RESET_NETWORK_CONFIRM = 84;
 
     // OPEN: Settings > Developer Options > Running Services
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     RUNNING_SERVICE_DETAILS = 85;
 
     // OPEN: Settings > Security > Screen pinning
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     SCREEN_PINNING = 86;
 
     // OPEN: Settings > Security
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     SECURITY = 87;
 
     // OPEN: Settings > SIM cards
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     SIM = 88;
 
     // OBSOLETE
@@ -519,55 +445,46 @@
     // OPEN: Settings > More > Tethering & portable hotspot
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TETHER = 90;
 
     // OPEN: Settings > Security > Trust agents
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TRUST_AGENT = 91;
 
     // OPEN: Settings > Security > Trusted credentials
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TRUSTED_CREDENTIALS = 92;
 
     // OPEN: Settings > Language & input > TTS output > [Engine] > Settings
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TTS_ENGINE_SETTINGS = 93;
 
     // OPEN: Settings > Language & input > Text-to-speech output
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TTS_TEXT_TO_SPEECH = 94;
 
     // OPEN: Settings > Security > Apps with usage access
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     USAGE_ACCESS = 95;
 
     // OPEN: Settings > Users
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     USER = 96;
 
     // OPEN: Settings > Users > [Restricted profile app & content access]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     USERS_APP_RESTRICTIONS = 97;
 
     // OPEN: Settings > Users > [User settings]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     USER_DETAILS = 98;
 
     // OBSOLETE
@@ -576,43 +493,36 @@
     // OPEN: Settings > More > VPN
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     VPN = 100;
 
     // OPEN: Settings > Display > Choose wallpaper from
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WALLPAPER_TYPE = 101;
 
     // OPEN: Settings > Display > Cast
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WFD_WIFI_DISPLAY = 102;
 
     // OPEN: Settings > Wi-Fi
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIFI = 103;
 
     // OPEN: Settings > Wi-Fi > Advanced Wi-Fi
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIFI_ADVANCED = 104;
 
     // OPEN: Settings > More > Wi-Fi Calling
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIFI_CALLING = 105;
 
     // OPEN: Settings > Wi-Fi > Saved networks
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIFI_SAVED_ACCESS_POINTS = 106;
 
     // OBSOLETE
@@ -624,19 +534,16 @@
     // OPEN: Settings > Wi-Fi > Advanced Wi-Fi > Wi-Fi Direct
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIFI_P2P = 109;
 
     // OPEN: Settings > More
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     WIRELESS = 110;
 
     // OPEN: Quick Settings Panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_PANEL = 111;
 
     // OPEN: QS Airplane mode tile shown
@@ -644,7 +551,6 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_AIRPLANEMODE = 112;
 
     // OPEN: QS Bluetooth tile shown
@@ -652,21 +558,18 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_BLUETOOTH = 113;
 
     // OPEN: QS Cast tile shown
     // ACTION: QS Cast tile tapped
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_CAST = 114;
 
     // OPEN: QS Cellular tile shown
     // ACTION: QS Cellular tile tapped
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_CELLULAR = 115;
 
     // OPEN: QS Color inversion tile shown
@@ -674,13 +577,11 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_COLORINVERSION = 116;
 
     // OPEN: QS Cellular tile > Cellular detail panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_DATAUSAGEDETAIL = 117;
 
     // OPEN: QS Do not disturb tile shown
@@ -688,7 +589,6 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_DND = 118;
 
     // OPEN: QS Flashlight tile shown
@@ -696,7 +596,6 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_FLASHLIGHT = 119;
 
     // OPEN: QS Hotspot tile shown
@@ -704,14 +603,12 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_HOTSPOT = 120;
 
     // OPEN: QS 3P tile shown
     // ACTION: QS 3P tile tapped
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_INTENT = 121;
 
     // OPEN: QS Location tile shown
@@ -719,7 +616,6 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_LOCATION = 122;
 
     // OPEN: QS Rotation tile shown
@@ -727,7 +623,6 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_ROTATIONLOCK = 123;
 
     // OBSOLETE
@@ -736,7 +631,6 @@
     // OPEN: QS User list panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_USERDETAIL = 125;
 
     // OPEN: QS WiFi tile shown
@@ -744,13 +638,11 @@
     //  SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.46
     QS_WIFI = 126;
 
     // OPEN: Notification Panel (including lockscreen)
     // CATEGORY: NOTIFICATION
     // OS: 5.1.1
-    // GMS: 7.5.26
     NOTIFICATION_PANEL = 127;
 
     // OPEN: Notification in panel became visible.
@@ -764,7 +656,6 @@
     //   SUBTYPE: Dismiss reason from NotificationManagerService.java
     // CATEGORY: NOTIFICATION
     // OS: 5.1.1
-    // GMS: 7.5.26
     NOTIFICATION_ITEM = 128;
 
     // ACTION: User tapped notification action
@@ -772,19 +663,16 @@
     //   SUBTYPE: Index of action on notification
     // CATEGORY: NOTIFICATION
     // OS: 5.0
-    // GMS: 7.5.26
     NOTIFICATION_ITEM_ACTION = 129;
 
     // OPEN: Settings > Apps > Configure apps > App permissions
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_ADVANCED = 130;
 
     // OPEN: Settings > Location > Scanning
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     LOCATION_SCANNING = 131;
 
     // OBSOLETE
@@ -793,43 +681,36 @@
     // OPEN: Settings > Sound & notification > App notifications
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
 
     // ACTION: Settings > Wi-Fi > Overflow > Add Network
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_ADD_NETWORK = 134;
 
     // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_CONNECT = 135;
 
     // ACTION: Settings > Wi-Fi > Overflow > Refresh
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_FORCE_SCAN = 136;
 
     // ACTION: Settings > Wi-Fi > [Long press network] > Forget network
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_FORGET = 137;
 
     // ACTION: Settings > Wi-Fi > Toggle off
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_OFF = 138;
 
     // ACTION: Settings > Wi-Fi > Toggle on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_WIFI_ON = 139;
 
     // OBSOLETE
@@ -838,280 +719,236 @@
     // OPEN: Settings > Sound & notification > DND > Priority only allows
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_PRIORITY = 141;
 
     // OPEN: Settings > Sound & notification > DND > Automatic rules
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
 
     // OPEN: Settings > Apps > Configure apps > App links
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     MANAGE_DOMAIN_URLS = 143;
 
     // OPEN: Settings > Sound & notification > DND > [Time based rule]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
 
     // OPEN: Settings > Sound & notification > DND > [External rule]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
 
     // OPEN: Settings > Sound & notification > DND > [Event rule]
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
 
     // ACTION: App notification settings > Block Notifications
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BAN_APP_NOTES = 147;
 
     // ACTION: Notification shade > Dismiss all button
     // CATEGORY: NOTIFICATION
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_DISMISS_ALL_NOTES = 148;
 
     // OPEN: QS Do Not Disturb detail panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_DND_DETAILS = 149;
 
     // OPEN: QS Bluetooth detail panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_BLUETOOTH_DETAILS = 150;
 
     // OPEN: QS Cast detail panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_CAST_DETAILS = 151;
 
     // OPEN: QS Wi-Fi detail panel
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_WIFI_DETAILS = 152;
 
     // ACTION: QS Wi-Fi detail panel > Wi-Fi toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_WIFI_TOGGLE = 153;
 
     // ACTION: QS Bluetooth detail panel > Bluetooth toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_BLUETOOTH_TOGGLE = 154;
 
     // ACTION: QS Cellular detail panel > Cellular toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_CELLULAR_TOGGLE = 155;
 
     // ACTION: QS User list panel > Select different user
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_SWITCH_USER = 156;
 
     // ACTION: QS Cast detail panel > Select cast device
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_CAST_SELECT = 157;
 
     // ACTION: QS Cast detail panel > Disconnect cast device
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_CAST_DISCONNECT = 158;
 
     // ACTION: Settings > Bluetooth > Toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BLUETOOTH_TOGGLE = 159;
 
     // ACTION: Settings > Bluetooth > Overflow > Refresh
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BLUETOOTH_SCAN = 160;
 
     // ACTION: Settings > Bluetooth > Overflow > Rename this device
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BLUETOOTH_RENAME = 161;
 
     // ACTION: Settings > Bluetooth > Overflow > Show received files
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BLUETOOTH_FILES = 162;
 
     // ACTION: QS DND details panel > Increase / Decrease exit time
     //   SUBTYPE: true is increase, false is decrease
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_DND_TIME = 163;
 
     // ACTION: QS DND details panel > [Exit condition]
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_DND_CONDITION_SELECT = 164;
 
     // ACTION: QS DND details panel > [DND mode]
     //  SUBTYPE: 1 is priority, 2 is silence, 3 is alarms only
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_DND_ZEN_SELECT = 165;
 
     // ACTION: QS DND detail panel > DND toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     QS_DND_TOGGLE = 166;
 
     // ACTION: DND Settings > Priority only allows > Reminder toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ALLOW_REMINDERS = 167;
 
     // ACTION: DND Settings > Priority only allows > Event toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ALLOW_EVENTS = 168;
 
     // ACTION: DND Settings > Priority only allows > Messages
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ALLOW_MESSAGES = 169;
 
     // ACTION: DND Settings > Priority only allows > Calls
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ALLOW_CALLS = 170;
 
     // ACTION: DND Settings > Priority only allows > Repeat callers toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
 
     // ACTION: DND Settings > Automatic rules > Add rule
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ADD_RULE = 172;
 
     // ACTION: DND Settings > Automatic rules > Add rule > OK
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ADD_RULE_OK = 173;
 
     // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_DELETE_RULE = 174;
 
     // ACTION: DND Settings > Automatic rules > [Rule] > Delete rule > Delete
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_DELETE_RULE_OK = 175;
 
     // ACTION: DND Settings > Automatic rules > [Rule] > Toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ZEN_ENABLE_RULE = 176;
 
     // ACTION: Settings > More > Airplane mode toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_AIRPLANE_TOGGLE = 177;
 
     // ACTION: Settings > Data usage > Cellular data toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_CELL_DATA_TOGGLE = 178;
 
     // OPEN: Settings > Sound & notification > Notification access
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ACCESS = 179;
 
     // OPEN: Settings > Sound & notification > Do Not Disturb access
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     NOTIFICATION_ZEN_MODE_ACCESS = 180;
 
     // OPEN: Settings > Apps > Configure apps > Default Apps
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_DEFAULT_APPS = 181;
 
     // OPEN: Settings > Internal storage > Apps storage
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_STORAGE_APPS = 182;
 
     // OPEN: Settings > Security > Usage access
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
 
     // OPEN: Settings > Battery > Battery optimization
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_HIGH_POWER_APPS = 184;
 
     // OBSOLETE
@@ -1120,448 +957,377 @@
     // ACTION: Lockscreen > Unlock gesture
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_UNLOCK = 186;
 
     // ACTION: Lockscreen > Pull shade open
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_SHADE = 187;
 
     // ACTION: Lockscreen > Tap on lock, shows hint
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_HINT = 188;
 
     // ACTION: Lockscreen > Camera
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_CAMERA = 189;
 
     // ACTION: Lockscreen > Dialer
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_DIALER = 190;
 
     // ACTION: Lockscreen > Tap on lock, locks phone
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_LOCK = 191;
 
     // ACTION: Lockscreen > Tap on notification, false touch rejection
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     ACTION_LS_NOTE = 192;
 
     // ACTION: Lockscreen > Swipe down to open quick settings
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.8.22
     ACTION_LS_QS = 193;
 
     // ACTION: Swipe down to open quick settings when unlocked
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.8.22
     ACTION_SHADE_QS_PULL = 194;
 
     // ACTION: Notification shade > Tap to open quick settings
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.8.22
     ACTION_SHADE_QS_TAP = 195;
 
     // OPEN: Lockscreen
     //   SUBTYPE: 0 is unsecure, 1 is secured by password / pattern / PIN
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     LOCKSCREEN = 196;
 
     // OPEN: Lockscreen > Screen to enter password / pattern / PIN
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     BOUNCER = 197;
 
     // OPEN: Screen turned on
     //   SUBTYPE: 2 is user action
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.8.22
     SCREEN = 198;
 
     // OPEN: Notification caused sound, vibration, and/or LED blink
     //   SUBTYPE: 1 is buzz, 2 is beep, blink is 4, or'd together
     // CATEGORY: NOTIFICATION
     // OS: 5.1.1
-    // GMS: 7.8.53
     NOTIFICATION_ALERT = 199;
 
     // ACTION: Lockscreen > Emergency Call button
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 5.1.1
-    // GMS: 7.5.26
     ACTION_EMERGENCY_CALL = 200;
 
     // OPEN: Settings > Apps > Configure > Default apps > Assist & voice input
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     APPLICATIONS_MANAGE_ASSIST = 201;
 
     // OPEN: Settings > Memory
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     PROCESS_STATS_SUMMARY = 202;
 
     // ACTION: Settings > Display > When device is rotated
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ROTATION_LOCK = 203;
 
     // ACTION: Long press on notification to view controls
     // CATEGORY: NOTIFICATION
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_NOTE_CONTROLS = 204;
 
     // ACTION: Notificatoin controls > Info button
     // CATEGORY: NOTIFICATION
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_NOTE_INFO = 205;
 
     // ACTION: Notification controls > Settings button
     // CATEGORY: NOTIFICATION
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_APP_NOTE_SETTINGS = 206;
 
     // OPEN: Volume Dialog (with hardware buttons)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     VOLUME_DIALOG = 207;
 
     // OPEN: Volume dialog > Expanded volume dialog (multiple sliders)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     VOLUME_DIALOG_DETAILS = 208;
 
     // ACTION: Volume dialog > Adjust volume slider
     //   SUBTYPE: volume level (0-7)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_VOLUME_SLIDER = 209;
 
     // ACTION: Volume dialog > Select non-active stream
     //   SUBTYPE: stream (defined in AudioSystem.java)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_VOLUME_STREAM = 210;
 
     // ACTION: Adjust volume with hardware key
     //   SUBTYPE: volume level (0-7)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_VOLUME_KEY = 211;
 
     // ACTION: Volume dialog > Mute a stream by tapping icon
     //   SUBTYPE: mute is 1, audible is 2
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_VOLUME_ICON = 212;
 
     // ACTION: Volume dialog > Change ringer mode by tapping icon
     //   SUBTYPE: 2 is audible, 3 is vibrate
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_RINGER_MODE = 213;
 
     // ACTION: Chooser shown (share target, file open, etc.)
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ACTIVITY_CHOOSER_SHOWN = 214;
 
     // ACTION: Chooser > User taps an app target
     //   SUBTYPE: Index of target
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215;
 
     // ACTION: Chooser > User taps a service target
     //   SUBTYPE: Index of target
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216;
 
     // ACTION: Chooser > User taps a standard target
     //   SUBTYPE: Index of target
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217;
 
     // ACTION: QS Brightness Slider (with auto brightness disabled)
     //   SUBTYPE: slider value
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BRIGHTNESS = 218;
 
     // ACTION: QS Brightness Slider (with auto brightness enabled)
     //   SUBTYPE: slider value
     // CATEGORY: QUICK_SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_BRIGHTNESS_AUTO = 219;
 
     // OPEN: Settings > Display > Brightness Slider
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     BRIGHTNESS_DIALOG = 220;
 
     // OPEN: Settings > Apps > Configure Apps > Draw over other apps
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     SYSTEM_ALERT_WINDOW_APPS = 221;
 
     // OPEN: Display has entered dream mode
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     DREAMING = 222;
 
     // OPEN: Display has entered ambient notification mode
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     DOZING = 223;
 
     // OPEN: Overview
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     OVERVIEW_ACTIVITY = 224;
 
     // OPEN: Settings > About phone > Legal information
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ABOUT_LEGAL_SETTINGS = 225;
 
     // OPEN: Settings > Search > Perform search
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_SEARCH_RESULTS = 226;
 
     // OPEN: Settings > System UI Tuner
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER = 227;
 
     // OPEN: Settings > System UI Tuner > Quick Settings
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_QS = 228;
 
     // OPEN: Settings > System UI Tuner > Demo mode
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_DEMO_MODE = 229;
 
     // ACTION: Settings > System UI Tuner > Quick Settings > Move tile
     //   PACKAGE: Tile
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_QS_REORDER = 230;
 
     // ACTION: Settings > System UI Tuner > Quick Settings > Add tile
     //   PACKAGE: Tile
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_QS_ADD = 231;
 
     // ACTION: Settings > System UI Tuner > Quick Settings > Remove tile
     //   PACKAGE: Tile
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_QS_REMOVE = 232;
 
     // ACTION: Settings > System UI Tuner > Status bar > Enable icon
     //   PACKAGE: Icon
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_STATUS_BAR_ENABLE = 233;
 
     // ACTION: Settings > System UI Tuner > Status bar > Disable icon
     //   PACKAGE: Icon
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_STATUS_BAR_DISABLE = 234;
 
     // ACTION: Settings > System UI Tuner > Demo mode > Enable demo mode
     //   SUBTYPE: false is disabled, true is enabled
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_DEMO_MODE_ENABLED = 235;
 
     // ACTION: Settings > System UI Tuner > Demo mode > Show demo mode
     //   SUBTYPE: false is disabled, true is enabled
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_DEMO_MODE_ON = 236;
 
     // ACTION: Settings > System UI Tuner > Show embedded battery percentage
     //   SUBTYPE: 0 is disabled, 1 is enabled
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     TUNER_BATTERY_PERCENTAGE = 237;
 
     // OPEN: Settings > Developer options > Inactive apps
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.5.26
     FUELGAUGE_INACTIVE_APPS = 238;
 
     // ACTION: Long press home to bring up assistant
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.5.26
     ACTION_ASSIST_LONG_PRESS = 239;
 
     // OPEN: Settings > Security > Nexus Imprint > Add Fingerprint
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLLING = 240;
 
     // OPEN: Fingerprint Enroll > Find Sensor
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_FIND_SENSOR = 241;
 
     // OPEN: Fingerprint Enroll > Fingerprint Enrolled!
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_FINISH = 242;
 
     // OPEN: Fingerprint Enroll introduction
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_INTRO = 243;
 
     // OPEN: Fingerprint Enroll onboarding
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_ONBOARD = 244;
 
     // OPEN: Fingerprint Enroll > Let's Start!
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_SIDECAR = 245;
 
     // OPEN: Fingerprint Enroll SUW > Let's Start!
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLLING_SETUP = 246;
 
     // OPEN: Fingerprint Enroll SUW > Find Sensor
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_FIND_SENSOR_SETUP = 247;
 
     // OPEN: Fingerprint Enroll SUW > Fingerprint Enrolled!
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_FINISH_SETUP = 248;
 
     // OPEN: Fingerprint Enroll SUW introduction
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_INTRO_SETUP = 249;
 
     // OPEN: Fingerprint Enroll SUW onboarding
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     FINGERPRINT_ENROLL_ONBOARD_SETUP = 250;
 
     // ACTION: Add fingerprint > Enroll fingerprint
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_FINGERPRINT_ENROLL = 251;
 
     // ACTION: Authenticate using fingerprint
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_FINGERPRINT_AUTH = 252;
 
     // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_FINGERPRINT_DELETE = 253;
 
     // ACTION: Settings > Security > Nexus Imprint > [Fingerprint] > Rename
     // CATEGORY: SETTINGS
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_FINGERPRINT_RENAME = 254;
 
     // ACTION: Double tap camera shortcut
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
 
     // ACTION: Double twist camera shortcut
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: 6.0
-    // GMS: 7.8.99
     ACTION_WIGGLE_CAMERA_GESTURE = 256;
 
     // OPEN: QS Work Mode tile shown
@@ -1569,13 +1335,11 @@
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_WORKMODE = 257;
 
     // OPEN: Settings > Developer Options > Background Check
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     BACKGROUND_CHECK_SUMMARY = 258;
 
     // OPEN: QS Lock tile shown
@@ -1583,52 +1347,44 @@
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_LOCK_TILE = 259;
 
     // OPEN: QS User Tile shown
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_USER_TILE = 260;
 
     // OPEN: QS Battery tile shown
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_BATTERY_TILE = 261;
 
     // OPEN: Settings > Sound > Do not disturb > Visual interruptions
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 262;
 
     // ACTION: Visual interruptions > No screen interuptions toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF = 263;
 
     // ACTION: Visual interruptions > No notification light toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_ZEN_ALLOW_LIGHTS = 264;
 
     // OPEN: Settings > Notifications > [App] > Topic Notifications
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     NOTIFICATION_TOPIC_NOTIFICATION = 265;
 
     // ACTION: Settings > Apps > Default Apps > Select different SMS app
     //   PACKAGE: Selected SMS app
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_DEFAULT_SMS_APP_CHANGED = 266;
 
     // OPEN: QS Color modification tile shown
@@ -1636,105 +1392,88 @@
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_COLOR_MATRIX = 267;
 
     // OPEN: QS Custom tile shown
     // ACTION: QS Work Mode tile tapped
     // CATEGORY: QUICK_SETTINGS
     // OS: N
-    // GMS: 7.8.99
     QS_CUSTOM = 268;
 
     // ACTION: Visual interruptions > Never turn off the screen toggle
     //   SUBTYPE: 0 is off, 1 is on
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_ZEN_ALLOW_WHEN_SCREEN_ON = 269;
 
     // ACTION: Overview > Long-press task, drag to enter split-screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_WINDOW_DOCK_DRAG_DROP = 270;
 
     // ACTION: In App > Long-press Overview button to enter split-screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_WINDOW_DOCK_LONGPRESS = 271;
 
     // ACTION: In App > Swipe Overview button to enter split-screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_WINDOW_DOCK_SWIPE = 272;
 
     // ACTION: Launch profile-specific app > Confirm credentials
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     PROFILE_CHALLENGE = 273;
 
     // OPEN: QS Battery detail panel
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     QS_BATTERY_DETAIL = 274;
 
     // OPEN: Overview > History
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     OVERVIEW_HISTORY = 275;
 
     // ACTION: Overview > Page by tapping Overview button
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_OVERVIEW_PAGE = 276;
 
     // ACTION: Overview > Select app
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_OVERVIEW_SELECT = 277;
 
     // ACTION: View emergency info
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_VIEW_EMERGENCY_INFO = 278;
 
     // ACTION: Edit emergency info activity
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_EDIT_EMERGENCY_INFO = 279;
 
     // ACTION: Edit emergency info field
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_EDIT_EMERGENCY_INFO_FIELD = 280;
 
     // ACTION: Add emergency contact
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_ADD_EMERGENCY_CONTACT = 281;
 
     // ACTION: Delete emergency contact
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_DELETE_EMERGENCY_CONTACT = 282;
 
     // ACTION: Call emergency contact
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     ACTION_CALL_EMERGENCY_CONTACT = 283;
 
     // OPEN: QS Data Saver tile shown
@@ -1745,13 +1484,11 @@
     // OPEN: Settings > Security > User credentials
     // CATEGORY: Settings
     // OS: N
-    // GMS: 7.8.99
     USER_CREDENTIALS = 285;
 
     // ACTION: In App (splitscreen) > Long-press Overview to exit split-screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_WINDOW_UNDOCK_LONGPRESS = 286;
 
     // Logged when the user scrolls through overview manually
@@ -1773,81 +1510,68 @@
     // ACTION: Long-press power button, then tap "Take bug report" option.
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE = 292;
 
     // ACTION: Long-press power button, then long-press "Take bug report" option.
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_FROM_POWER_MENU_FULL = 293;
 
     // ACTION: Settings -> Developer Options -> Take bug report -> Interactive report
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     // Interactive bug report initiated from Settings.
     ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE = 294;
 
     // ACTION: Settings -> Developer Options -> Take bug report -> Full report
     // CATEGORY: SETTINGS
     // OS: N
-    // GMS: 7.8.99
     // Interactive bug report initiated from Settings.
     ACTION_BUGREPORT_FROM_SETTINGS_FULL = 295;
 
     // ACTION: User tapped notification action to cancel a bug report
     // CATEGORY: NOTIFICATION
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_NOTIFICATION_ACTION_CANCEL = 296;
 
     // ACTION: User tapped notification action to launch bug report details screen
     // CATEGORY: NOTIFICATION
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_NOTIFICATION_ACTION_DETAILS = 297;
 
     // ACTION: User tapped notification action to take adition screenshot on bug report
     // CATEGORY: NOTIFICATION
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT = 298;
 
     // ACTION: User tapped notification to share bug report
     // CATEGORY: NOTIFICATION
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE = 299;
 
     // ACTION: User changed bug report name using the details screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_DETAILS_NAME_CHANGED = 300;
 
     // ACTION: User changed bug report title using the details screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_DETAILS_TITLE_CHANGED = 301;
 
     // ACTION: User changed bug report description using the details screen
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_DETAILS_DESCRIPTION_CHANGED = 302;
 
     // ACTION: User tapped Save in the bug report details screen.
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_DETAILS_SAVED = 303;
 
     // ACTION: User tapped Cancel in the bug report details screen.
     // CATEGORY: GLOBAL_SYSTEM_UI
     // OS: N
-    // GMS: 7.8.99
     ACTION_BUGREPORT_DETAILS_CANCELED = 304;
 
     // Tuner: Open/close calibrate dialog.
@@ -1920,79 +1644,140 @@
     // the transition was executed.
     APP_TRANSITION_DEVICE_UPTIME_SECONDS = 325;
 
-    // User granted access to the request folder; action takes an integer
-    // representing the folder's index on Environment.STANDARD_DIRECTORIES
-    // (or -2 for root access, or -1 or unknown directory).
+    // ACTION: app requested access to a scoped directory, user granted it.
+    //   SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_FOLDER = 326;
 
-    // User denied access to the request folder; action takes an integer
-    // representing the folder's index on Environment.STANDARD_DIRECTORIES
-    // (or -2 for root access, or -1 or unknown directory).
+    // ACTION: app requested access to a scoped directory, user denied it.
+    //   SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_FOLDER = 327;
 
-    // User granted access to the request folder; action pass package name
-    // of calling package.
+    // ACTION: app requested access to a scoped directory, user granted it.
+    //   PACKAGE: app that requested access
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_GRANTED_BY_PACKAGE = 328;
 
-    // User denied access to the request folder; action pass package name
-    // of calling package.
+    // ACTION: app requested access to a scoped directory, user denied it.
+    //   PACKAGE: app that requested access.
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_BY_PACKAGE = 329;
 
-    // App requested access to a directory it has already been granted
-    // access before; action takes an integer representing the folder's
-    // index on Environment.STANDARD_DIRECTORIES
-    // (or -2 for root access, or -1 or unknown directory).
+    // ACTION: app requested access to a directory user has already been granted
+    // access before.
+    //   SUBTYPE: directory's index on Environment.STANDARD_DIRECTORIES.
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_FOLDER = 330;
 
-    // App requested access to a directory it has already been granted
-    // access before; action pass package name of calling package.
+    // ACTION: app requested access to a directory user has already been granted
+    // access before.
+    //   PACKAGE: app that requested access.
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: N
     ACTION_SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED_BY_PACKAGE = 331;
 
-    // Logged when the user slides a notification and
-    // reveals the gear beneath it.
+    // ACTION: Logged when the user slides a notification and reveals the gear
+    // beneath it.
+    // CATEGORY: NOTIFICATION
+    // OS: N
     ACTION_REVEAL_GEAR = 332;
 
-    // Logged when the user taps on the gear beneath
-    // a notification.
+    // ACTION: Logged when the user taps on the gear beneath a notification.
+    // CATEGORY: NOTIFICATION
+    // OS: N
     ACTION_TOUCH_GEAR = 333;
 
     // Logs that the user has edited the enabled VR listeners.
+    // CATEGORY: SETTINGS
+    // OS: N
     VR_MANAGE_LISTENERS = 334;
 
     // Settings -> Accessibility -> Click after pointer stops moving
+    // CATEGORY: SETTINGS
+    // OS: N
     ACCESSIBILITY_TOGGLE_AUTOCLICK = 335;
+
     // Settings -> Sound
+    // CATEGORY: SETTINGS
+    // OS: N
     SOUND = 336;
+
     // Settings -> Notifications -> Gear
+    // CATEGORY: SETTINGS
+    // OS: N
     CONFIGURE_NOTIFICATION = 337;
+
     // Settings -> Wi-Fi -> Gear
+    // CATEGORY: SETTINGS
+    // OS: N
     CONFIGURE_WIFI = 338;
+
     // Settings -> Display -> Display size
+    // OS: N
     DISPLAY_SCREEN_ZOOM = 339;
+
     // Settings -> Display -> Font size
+    // CATEGORY: SETTINGS
+    // OS: N
     ACCESSIBILITY_FONT_SIZE = 340;
+
     // Settings -> Data usage -> Cellular/Wi-Fi data usage
+    // CATEGORY: SETTINGS
+    // OS: N
     DATA_USAGE_LIST = 341;
+
     // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear
+    // CATEGORY: SETTINGS
+    // OS: N
     BILLING_CYCLE = 342;
+
     // DATA_USAGE_LIST -> Any item or App info -> Data usage
+    // CATEGORY: SETTINGS
+    // OS: N
     APP_DATA_USAGE = 343;
+
     // Settings -> Language & input -> Language
+    // CATEGORY: SETTINGS
+    // OS: N
     USER_LOCALE_LIST = 344;
+
     // Settings -> Language & input -> Virtual keyboard
+    // CATEGORY: SETTINGS
+    // OS: N
     VIRTUAL_KEYBOARDS = 345;
+
     // Settings -> Language & input -> Physical keyboard
+    // CATEGORY: SETTINGS
+    // OS: N
     PHYSICAL_KEYBOARDS = 346;
+
     // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard
+    // CATEGORY: SETTINGS
+    // OS: N
     ENABLE_VIRTUAL_KEYBOARDS = 347;
+
     // Settings -> Data usage -> Data Saver
+    // CATEGORY: SETTINGS
+    // OS: N
     DATA_SAVER_SUMMARY = 348;
+
     // Settings -> Data usage -> Data Saver -> Unrestricted data access
+    // CATEGORY: SETTINGS
+    // OS: N
     DATA_USAGE_UNRESTRICTED_ACCESS = 349;
 
     // Used for generic logging of Settings Preference Persistence, should not be used
     // outside SharedPreferencesLogger.
+    // CATEGORY: SETTINGS
+    // OS: N
     ACTION_GENERIC_PACKAGE = 350;
+
     // Settings -> Apps -> Gear -> Special access
     SPECIAL_ACCESS = 351;
 
@@ -2158,15 +1943,28 @@
     // System UI Tuner > Other > Power notification controls > Toggle on/off
     ACTION_TUNER_POWER_NOTIFICATION_CONTROLS = 393;
 
-    // Action: user enable / disabled data saver using Settings. Arguments:
-    // 0: Data Saver mode is disabled.
-    // 1: Data Saver mode is enabled.
+    // Action: user enable / disabled data saver using Settings
+    // OPEN: Settings -> Data Usage -> Data saver -> On/off toggle
+    // VALUE: 1 for enabled, 0 for disabled
+    // CATEGORY: SETTINGS
+    // OS: N
     ACTION_DATA_SAVER_MODE = 394;
 
-    // User whitelisted an app for Data Saver mode; action pass package name of app.
+    // User whitelisted an app for Data Saver mode; action pass package name of app
+    // Action: user enable / disabled data saver using Settings
+    // OPEN: Settings -> Data Usage -> Data saver -> Unrestricted data access > APP toggle turned on
+    //       or
+    //       Settings -> Apps -> APP -> Data usage -> Unrestricted data usage toggle turned on
+    // VALUE: package name of APP
+    // CATEGORY: SETTINGS
+    // OS: N
     ACTION_DATA_SAVER_WHITELIST = 395;
 
-    // User blacklisted an app for Data Saver mode; action pass package name of app.
+    // User blacklisted an app for Data Saver mode; action pass package name of app
+    // OPEN: Settings -> Apps -> APP -> Data usage -> Background data toggle turned off
+    // VALUE: package name of APP
+    // CATEGORY: SETTINGS
+    // OS: N
     ACTION_DATA_SAVER_BLACKLIST = 396;
 
     // User opened a remote input view associated with a notification. Passes package name of app
@@ -2332,45 +2130,70 @@
     SUPPORT_FRAGMENT = 475;
 
     // ACTION: Settings -> Select summary tab.
+    // CATEGORY: SETTINGS
     ACTION_SELECT_SUMMARY=476;
 
     // ACTION: Settings -> Select support tab.
+    // CATEGORY: SETTINGS
     ACTION_SELECT_SUPPORT_FRAGMENT = 477;
 
     // ACTION: Settings -> Support -> Tips & tricks
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_TIPS_AND_TRICKS = 478;
 
     // ACTION: Settings -> Support -> Help & feedback
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_HELP_AND_FEEDBACK = 479;
 
     // ACTION: Settings -> Support -> Sign in
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_SIGN_IN = 480;
 
     // ACTION: Settings -> Support -> Phone
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_PHONE = 481;
 
     // ACTION: Settings -> Support -> Chat
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_CHAT = 482;
 
     // ACTION: Settings -> Support -> Phone/Chat -> Disclaimer Cancel
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_DISCLAIMER_CANCEL = 483;
 
     // ACTION: Settings -> Support -> Phone/Chat -> Disclaimer OK
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_DISCLAIMER_OK = 484;
 
     // ACTION: Settings -> Support -> Toll-Free Phone
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_DAIL_TOLLFREE = 485;
 
     // ACTION: Settings -> Support -> "Travel Abroad" Button
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_VIEW_TRAVEL_ABROAD_DIALOG = 486;
 
     // ACTION: Settings -> Support -> "Travel Abroad" Button -> Tolled Phone
+    // CATEGORY: SETTINGS
     ACTION_SUPPORT_DIAL_TOLLED = 487;
 
     // OPEN: Settings > Display > Night display
     // CATEGORY: SETTINGS
     NIGHT_DISPLAY_SETTINGS = 488;
 
+    // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager
+        //   SUBTYPE: false is off, true is on
+    ACTION_TOGGLE_STORAGE_MANAGER = 489;
+
+    // Settings launched from collapsed quick settings.
+    ACTION_QS_COLLAPSED_SETTINGS_LAUNCH = 490;
+
+    // OPEN: QS Night mode tile shown
+    // ACTION: QS Night mode tile tapped
+    //   SUBTYPE: 0 is off, 1 is on
+    // CATEGORY: QUICK_SETTINGS
+    QS_NIGHT_DISPLAY = 491;
+
     // ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4762a67..1f0dbfe 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12042,6 +12042,9 @@
             case ActivityManager.BUGREPORT_OPTION_REMOTE:
                 service = "bugreportremote";
                 break;
+            case ActivityManager.BUGREPORT_OPTION_WEAR:
+                service = "bugreportwear";
+                break;
         }
         if (service == null) {
             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 03843d1..5807502 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -743,6 +743,12 @@
             mService.updateCpuStatsNow();
         }
 
+        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
+        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+
+        boolean isSilentANR;
+
         synchronized (mService) {
             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
             if (mService.mShuttingDown) {
@@ -767,25 +773,29 @@
             // Dump thread traces as quickly as we can, starting with "interesting" processes.
             firstPids.add(app.pid);
 
-            int parentPid = app.pid;
-            if (parent != null && parent.app != null && parent.app.pid > 0) {
-                parentPid = parent.app.pid;
-            }
-            if (parentPid != app.pid) firstPids.add(parentPid);
+            // Don't dump other PIDs if it's a background ANR
+            isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID;
+            if (!isSilentANR) {
+                int parentPid = app.pid;
+                if (parent != null && parent.app != null && parent.app.pid > 0) {
+                    parentPid = parent.app.pid;
+                }
+                if (parentPid != app.pid) firstPids.add(parentPid);
 
-            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
+                if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
 
-            for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
-                ProcessRecord r = mService.mLruProcesses.get(i);
-                if (r != null && r.thread != null) {
-                    int pid = r.pid;
-                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
-                        if (r.persistent) {
-                            firstPids.add(pid);
-                            if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
-                        } else {
-                            lastPids.put(pid, Boolean.TRUE);
-                            if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
+                for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
+                    ProcessRecord r = mService.mLruProcesses.get(i);
+                    if (r != null && r.thread != null) {
+                        int pid = r.pid;
+                        if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
+                            if (r.persistent) {
+                                firstPids.add(pid);
+                                if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
+                            } else {
+                                lastPids.put(pid, Boolean.TRUE);
+                                if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
+                            }
                         }
                     }
                 }
@@ -808,10 +818,18 @@
             info.append("Parent: ").append(parent.shortComponentName).append("\n");
         }
 
-        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
+        ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
 
-        File tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
-                NATIVE_STACKS_OF_INTEREST);
+        String[] nativeProcs = NATIVE_STACKS_OF_INTEREST;
+        // don't dump native PIDs for background ANRs
+        File tracesFile = null;
+        if (isSilentANR) {
+            tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids,
+                null);
+        } else {
+            tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
+                nativeProcs);
+        }
 
         String cpuInfo = null;
         if (ActivityManagerService.MONITOR_CPU_USAGE) {
@@ -855,14 +873,10 @@
             }
         }
 
-        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
-        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
-
         synchronized (mService) {
             mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
 
-            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
+            if (isSilentANR) {
                 app.kill("bg anr", true);
                 return;
             }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 92b55db..12310e3 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -591,13 +591,13 @@
         synchronized (mPublicSync) {
             TetherState tetherState = mTetherStates.get(iface);
             if (tetherState == null) {
-                Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring");
+                Log.e(TAG, "Tried to Tether an unknown iface: " + iface + ", ignoring");
                 return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
             }
             // Ignore the error status of the interface.  If the interface is available,
             // the errors are referring to past tethering attempts anyway.
             if (tetherState.mLastState != IControlsTethering.STATE_AVAILABLE) {
-                Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
+                Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
                 return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
             }
             tetherState.mStateMachine.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
@@ -1018,15 +1018,29 @@
      */
     class UpstreamNetworkCallback extends NetworkCallback {
         @Override
+        public void onAvailable(Network network) {
+            mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+                    UpstreamNetworkMonitor.EVENT_ON_AVAILABLE, 0, network);
+        }
+
+        @Override
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
+            mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+                    UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES, 0,
+                    new NetworkState(null, null, newNc, network, null, null));
+        }
+
+        @Override
         public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
-            mTetherMasterSM.sendMessage(
-                    TetherMasterSM.EVENT_UPSTREAM_LINKPROPERTIES_CHANGED,
+            mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+                    UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, 0,
                     new NetworkState(null, newLp, null, network, null, null));
         }
 
         @Override
         public void onLost(Network network) {
-            mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_LOST, network);
+            mTetherMasterSM.sendMessage(TetherMasterSM.EVENT_UPSTREAM_CALLBACK,
+                    UpstreamNetworkMonitor.EVENT_ON_LOST, 0, network);
         }
     }
 
@@ -1045,6 +1059,11 @@
      * could/should be moved here.
      */
     class UpstreamNetworkMonitor {
+        static final int EVENT_ON_AVAILABLE      = 1;
+        static final int EVENT_ON_CAPABILITIES   = 2;
+        static final int EVENT_ON_LINKPROPERTIES = 3;
+        static final int EVENT_ON_LOST           = 4;
+
         final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
         NetworkCallback mDefaultNetworkCallback;
         NetworkCallback mDunTetheringCallback;
@@ -1079,33 +1098,107 @@
             mNetworkMap.clear();
         }
 
-        // Returns true if these updated LinkProperties pertain to the current
-        // upstream network interface, false otherwise (or if there is not
-        // currently any upstream tethering interface).
-        boolean processLinkPropertiesChanged(NetworkState networkState) {
-            if (networkState == null ||
-                    networkState.network == null ||
-                    networkState.linkProperties == null) {
-                return false;
-            }
+        NetworkState lookup(Network network) {
+            return (network != null) ? mNetworkMap.get(network) : null;
+        }
 
-            mNetworkMap.put(networkState.network, networkState);
-
-            if (mCurrentUpstreamIface != null) {
-                for (String ifname : networkState.linkProperties.getAllInterfaceNames()) {
-                    if (mCurrentUpstreamIface.equals(ifname)) {
-                        return true;
+        NetworkState processCallback(int arg1, Object obj) {
+            switch (arg1) {
+                case EVENT_ON_AVAILABLE: {
+                    final Network network = (Network) obj;
+                    if (VDBG) {
+                        Log.d(TAG, "EVENT_ON_AVAILABLE for " + network);
                     }
+                    if (!mNetworkMap.containsKey(network)) {
+                        mNetworkMap.put(network,
+                                new NetworkState(null, null, null, network, null, null));
+                    }
+
+                    final ConnectivityManager cm = getConnectivityManager();
+
+                    if (mDefaultNetworkCallback != null) {
+                        cm.requestNetworkCapabilities(mDefaultNetworkCallback);
+                        cm.requestLinkProperties(mDefaultNetworkCallback);
+                    }
+
+                    // Requesting updates for mDunTetheringCallback is not
+                    // necessary. Because it's a listen, it will already have
+                    // heard all NetworkCapabilities and LinkProperties updates
+                    // since UpstreamNetworkMonitor was started. Because we
+                    // start UpstreamNetworkMonitor before chooseUpstreamType()
+                    // is ever invoked (it can register a DUN request) this is
+                    // mostly safe. However, if a DUN network is already up for
+                    // some reason (unlikely, because DUN is restricted and,
+                    // unless the DUN network is shared with another APN, only
+                    // the system can request it and this is the only part of
+                    // the system that requests it) we won't know its
+                    // LinkProperties or NetworkCapabilities.
+
+                    return mNetworkMap.get(network);
+                }
+                case EVENT_ON_CAPABILITIES: {
+                    final NetworkState ns = (NetworkState) obj;
+                    if (!mNetworkMap.containsKey(ns.network)) {
+                        // Ignore updates for networks for which we have not yet
+                        // received onAvailable() - which should never happen -
+                        // or for which we have already received onLost().
+                        return null;
+                    }
+                    if (VDBG) {
+                        Log.d(TAG, String.format("EVENT_ON_CAPABILITIES for %s: %s",
+                                ns.network, ns.networkCapabilities));
+                    }
+
+                    final NetworkState prev = mNetworkMap.get(ns.network);
+                    mNetworkMap.put(ns.network,
+                            new NetworkState(null, prev.linkProperties, ns.networkCapabilities,
+                                             ns.network, null, null));
+                    return mNetworkMap.get(ns.network);
+                }
+                case EVENT_ON_LINKPROPERTIES: {
+                    final NetworkState ns = (NetworkState) obj;
+                    if (!mNetworkMap.containsKey(ns.network)) {
+                        // Ignore updates for networks for which we have not yet
+                        // received onAvailable() - which should never happen -
+                        // or for which we have already received onLost().
+                        return null;
+                    }
+                    if (VDBG) {
+                        Log.d(TAG, String.format("EVENT_ON_LINKPROPERTIES for %s: %s",
+                                ns.network, ns.linkProperties));
+                    }
+
+                    final NetworkState prev = mNetworkMap.get(ns.network);
+                    mNetworkMap.put(ns.network,
+                            new NetworkState(null, ns.linkProperties, prev.networkCapabilities,
+                                             ns.network, null, null));
+                    return mNetworkMap.get(ns.network);
+                }
+                case EVENT_ON_LOST: {
+                    final Network network = (Network) obj;
+                    if (VDBG) {
+                        Log.d(TAG, "EVENT_ON_LOST for " + network);
+                    }
+                    return mNetworkMap.remove(network);
+                }
+                default:
+                    return null;
+            }
+        }
+    }
+
+    // Needed because the canonical source of upstream truth is just the
+    // upstream interface name, |mCurrentUpstreamIface|.  This is ripe for
+    // future simplification, once the upstream Network is canonical.
+    boolean pertainsToCurrentUpstream(NetworkState ns) {
+        if (ns != null && ns.linkProperties != null && mCurrentUpstreamIface != null) {
+            for (String ifname : ns.linkProperties.getAllInterfaceNames()) {
+                if (mCurrentUpstreamIface.equals(ifname)) {
+                    return true;
                 }
             }
-            return false;
         }
-
-        void processNetworkLost(Network network) {
-            if (network != null) {
-                mNetworkMap.remove(network);
-            }
-        }
+        return false;
     }
 
     class TetherMasterSM extends StateMachine {
@@ -1120,8 +1213,7 @@
         static final int CMD_RETRY_UPSTREAM                     = BASE_MASTER + 4;
         // Events from NetworkCallbacks that we process on the master state
         // machine thread on behalf of the UpstreamNetworkMonitor.
-        static final int EVENT_UPSTREAM_LINKPROPERTIES_CHANGED  = BASE_MASTER + 5;
-        static final int EVENT_UPSTREAM_LOST                    = BASE_MASTER + 6;
+        static final int EVENT_UPSTREAM_CALLBACK                = BASE_MASTER + 5;
 
         private State mInitialState;
         private State mTetherModeAliveState;
@@ -1278,6 +1370,7 @@
             }
 
             protected void chooseUpstreamType(boolean tryCell) {
+                final ConnectivityManager cm = getConnectivityManager();
                 int upType = ConnectivityManager.TYPE_NONE;
                 String iface = null;
 
@@ -1292,8 +1385,7 @@
                     }
 
                     for (Integer netType : mUpstreamIfaceTypes) {
-                        NetworkInfo info =
-                                getConnectivityManager().getNetworkInfo(netType.intValue());
+                        NetworkInfo info = cm.getNetworkInfo(netType.intValue());
                         if ((info != null) && info.isConnected()) {
                             upType = netType.intValue();
                             break;
@@ -1334,9 +1426,9 @@
                         break;
                 }
 
+                Network network = null;
                 if (upType != ConnectivityManager.TYPE_NONE) {
-                    LinkProperties linkProperties =
-                            getConnectivityManager().getLinkProperties(upType);
+                    LinkProperties linkProperties = cm.getLinkProperties(upType);
                     if (linkProperties != null) {
                         // Find the interface with the default IPv4 route. It may be the
                         // interface described by linkProperties, or one of the interfaces
@@ -1353,7 +1445,7 @@
                     }
 
                     if (iface != null) {
-                        Network network = getConnectivityManager().getNetworkForType(upType);
+                        network = cm.getNetworkForType(upType);
                         if (network == null) {
                             Log.e(TAG, "No Network for upstream type " + upType + "!");
                         }
@@ -1361,6 +1453,13 @@
                     }
                 }
                 notifyTetheredOfNewUpstreamIface(iface);
+                NetworkState ns = mUpstreamNetworkMonitor.lookup(network);
+                if (ns != null && pertainsToCurrentUpstream(ns)) {
+                    // If we already have NetworkState for this network examine
+                    // it immediately, because there likely will be no second
+                    // EVENT_ON_AVAILABLE (it was already received).
+                    handleNewUpstreamNetworkState(ns);
+                }
             }
 
             protected void setDnsForwarders(final Network network, final LinkProperties lp) {
@@ -1393,6 +1492,10 @@
                             ifaceName);
                 }
             }
+
+            protected void handleNewUpstreamNetworkState(NetworkState ns) {
+                mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
+            }
         }
 
         private final AtomicInteger mSimBcastGenerationNumber = new AtomicInteger(0);
@@ -1582,24 +1685,55 @@
                         chooseUpstreamType(mTryCell);
                         mTryCell = !mTryCell;
                         break;
-                    case EVENT_UPSTREAM_LINKPROPERTIES_CHANGED:
-                        NetworkState state = (NetworkState) message.obj;
-                        if (mUpstreamNetworkMonitor.processLinkPropertiesChanged(state)) {
-                            setDnsForwarders(state.network, state.linkProperties);
-                        } else if (mCurrentUpstreamIface == null) {
-                            // If we have no upstream interface, try to run through upstream
-                            // selection again.  If, for example, IPv4 connectivity has shown up
-                            // after IPv6 (e.g., 464xlat became available) we want the chance to
-                            // notice and act accordingly.
-                            chooseUpstreamType(false);
+                    case EVENT_UPSTREAM_CALLBACK: {
+                        // First: always update local state about every network.
+                        final NetworkState ns = mUpstreamNetworkMonitor.processCallback(
+                                message.arg1, message.obj);
+
+                        if (ns == null || !pertainsToCurrentUpstream(ns)) {
+                            // TODO: In future, this is where upstream evaluation and selection
+                            // could be handled for notifications which include sufficient data.
+                            // For example, after CONNECTIVITY_ACTION listening is removed, here
+                            // is where we could observe a Wi-Fi network becoming available and
+                            // passing validation.
+                            if (mCurrentUpstreamIface == null) {
+                                // If we have no upstream interface, try to run through upstream
+                                // selection again.  If, for example, IPv4 connectivity has shown up
+                                // after IPv6 (e.g., 464xlat became available) we want the chance to
+                                // notice and act accordingly.
+                                chooseUpstreamType(false);
+                            }
+                            break;
+                        }
+
+                        switch (message.arg1) {
+                            case UpstreamNetworkMonitor.EVENT_ON_AVAILABLE:
+                                // The default network changed, or DUN connected
+                                // before this callback was processed. Updates
+                                // for the current NetworkCapabilities and
+                                // LinkProperties have been requested (default
+                                // request) or are being sent shortly (DUN). Do
+                                // nothing until they arrive; if no updates
+                                // arrive there's nothing to do.
+                                break;
+                            case UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES:
+                                handleNewUpstreamNetworkState(ns);
+                                break;
+                            case UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES:
+                                setDnsForwarders(ns.network, ns.linkProperties);
+                                handleNewUpstreamNetworkState(ns);
+                                break;
+                            case UpstreamNetworkMonitor.EVENT_ON_LOST:
+                                // TODO: Re-evaluate possible upstreams. Currently upstream
+                                // reevaluation is triggered via received CONNECTIVITY_ACTION
+                                // broadcasts that result in being passed a
+                                // TetherMasterSM.CMD_UPSTREAM_CHANGED.
+                                break;
+                            default:
+                                break;
                         }
                         break;
-                    case EVENT_UPSTREAM_LOST:
-                        // TODO: Re-evaluate possible upstreams. Currently upstream reevaluation
-                        // is triggered via received CONNECTIVITY_ACTION broadcasts that result
-                        // in being passed a TetherMasterSM.CMD_UPSTREAM_CHANGED.
-                        mUpstreamNetworkMonitor.processNetworkLost((Network) message.obj);
-                        break;
+                    }
                     default:
                         retValue = false;
                         break;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f15fdd5..b22a084 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1241,6 +1241,24 @@
     private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
         // TODO: reach into ConnectivityManager to proactively disable bringing
         // up this network, since we know that traffic will be blocked.
+
+        if (template.getMatchRule() == MATCH_MOBILE_ALL) {
+            // If mobile data usage hits the limit or if the user resumes the data, we need to
+            // notify telephony.
+            final SubscriptionManager sm = SubscriptionManager.from(mContext);
+            final TelephonyManager tm = TelephonyManager.from(mContext);
+
+            final int[] subIds = sm.getActiveSubscriptionIdList();
+            for (int subId : subIds) {
+                final String subscriberId = tm.getSubscriberId(subId);
+                final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
+                        TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true);
+                // Template is matched when subscriber id matches.
+                if (template.matches(probeIdent)) {
+                    tm.setPolicyDataEnabled(enabled, subId);
+                }
+            }
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 098b39e..1cff926 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -31,6 +31,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.print.PrintManager;
 import android.provider.CalendarContract;
 import android.provider.ContactsContract;
@@ -605,6 +606,15 @@
                 grantRuntimePermissionsLPw(nfcTagPkg, CONTACTS_PERMISSIONS, false, userId);
                 grantRuntimePermissionsLPw(nfcTagPkg, PHONE_PERMISSIONS, false, userId);
             }
+
+            // Storage Manager
+            Intent storageManagerIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
+            PackageParser.Package storageManagerPckg = getDefaultSystemHandlerActivityPackageLPr(
+                    storageManagerIntent, userId);
+            if (storageManagerPckg != null
+                    && doesPackageSupportRuntimePermissions(storageManagerPckg)) {
+                grantRuntimePermissionsLPw(storageManagerPckg, STORAGE_PERMISSIONS, true, userId);
+            }
             mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
         }
     }
@@ -619,6 +629,7 @@
             grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
             grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, userId);
             grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, userId);
+            grantRuntimePermissionsLPw(dialerPackage, CAMERA_PERMISSIONS, userId);
         }
     }
 
@@ -656,6 +667,7 @@
             grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId);
             grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, false, true, userId);
             grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId);
+            grantRuntimePermissionsLPw(dialerPackage, CAMERA_PERMISSIONS, false, true, userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 01b3dc2..02c6472 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -213,9 +213,19 @@
         // Use the package manager install and install lock here for the OTA dex optimizer.
         PackageDexOptimizer optimizer = new OTADexoptPackageDexOptimizer(
                 collectingInstaller, mPackageManagerService.mInstallLock, mContext);
+        // Make sure that core apps are optimized according to their own "reason".
+        // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed
+        // (by default is speed-profile) they will be interepreted/JITed. This in itself is not a
+        // problem as we will end up doing profile guided compilation. However, some core apps may
+        // be loaded by system server which doesn't JIT and we need to make sure we don't
+        // interpret-only
+        int compilationReason = nextPackage.coreApp
+                ? PackageManagerService.REASON_CORE_APP
+                : PackageManagerService.REASON_AB_OTA;
+
         optimizer.performDexOpt(nextPackage, nextPackage.usesLibraryFiles,
                 null /* ISAs */, false /* checkProfiles */,
-                getCompilerFilterForReason(PackageManagerService.REASON_AB_OTA));
+                getCompilerFilterForReason(compilationReason));
 
         mCommandsForCurrentPackage = collectingConnection.commands;
         if (mCommandsForCurrentPackage.isEmpty()) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a3cf9c8..6a56fa6 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -182,6 +182,10 @@
      */
     private final Random mRandom = new SecureRandom();
 
+    /** All sessions allocated */
+    @GuardedBy("mSessions")
+    private final SparseBooleanArray mAllocatedSessions = new SparseBooleanArray();
+
     @GuardedBy("mSessions")
     private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>();
 
@@ -365,6 +369,7 @@
                             // keep details around for dumpsys.
                             mHistoricalSessions.put(session.sessionId, session);
                         }
+                        mAllocatedSessions.put(session.sessionId, true);
                     }
                 }
             }
@@ -768,8 +773,8 @@
         int sessionId;
         do {
             sessionId = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
-            if (mSessions.get(sessionId) == null && mHistoricalSessions.get(sessionId) == null
-                    && !mLegacySessions.get(sessionId, false)) {
+            if (!mAllocatedSessions.get(sessionId, false)) {
+                mAllocatedSessions.put(sessionId, true);
                 return sessionId;
             }
         } while (n++ < 32);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1ca6148..78fa3a3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -95,6 +95,7 @@
 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
@@ -159,7 +160,6 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.Signature;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
@@ -2801,7 +2801,7 @@
                     }
                 }
 
-                int[] stats = performDexOpt(coreApps, false,
+                int[] stats = performDexOptUpgrade(coreApps, false,
                         getCompilerFilterForReason(REASON_CORE_APP));
 
                 final int elapsedTimeSeconds =
@@ -7325,7 +7325,7 @@
         }
 
         final long startTime = System.nanoTime();
-        final int[] stats = performDexOpt(pkgs, mIsPreNUpgrade /* showDialog */,
+        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
                     getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
 
         final int elapsedTimeSeconds =
@@ -7344,7 +7344,7 @@
      * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
      * and {@code numberOfPackagesFailed}.
      */
-    private int[] performDexOpt(List<PackageParser.Package> pkgs, boolean showDialog,
+    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
             String compilerFilter) {
 
         int numberOfPackagesVisited = 0;
@@ -7378,6 +7378,19 @@
                 }
             }
 
+            // If the OTA updates a system app which was previously preopted to a non-preopted state
+            // the app might end up being verified at runtime. That's because by default the apps
+            // are verify-profile but for preopted apps there's no profile.
+            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
+            // that before the OTA the app was preopted) the app gets compiled with a non-profile
+            // filter (by default interpret-only).
+            // Note that at this stage unused apps are already filtered.
+            if (isSystemApp(pkg) &&
+                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
+                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
+                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
+            }
+
             // checkProfiles is false to avoid merging profiles during boot which
             // might interfere with background compilation (b/28612421).
             // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
@@ -11439,9 +11452,6 @@
                     } else {
                         resolvedUserIds = userIds;
                     }
-                    final ShortcutServiceInternal shortcutService =
-                            LocalServices.getService(ShortcutServiceInternal.class);
-
                     for (int id : resolvedUserIds) {
                         final Intent intent = new Intent(action,
                                 pkg != null ? Uri.fromParts("package", pkg, null) : null);
@@ -11466,10 +11476,6 @@
                                     + intent.toShortString(false, true, false, false)
                                     + " " + intent.getExtras(), here);
                         }
-                        // TODO b/29385425 Consider making lifecycle callbacks for this.
-                        if (shortcutService != null) {
-                            shortcutService.onPackageBroadcast(intent);
-                        }
                         am.broadcastIntent(null, intent, null, finishedReceiver,
                                 0, null, null, null, android.app.AppOpsManager.OP_NONE,
                                 null, finishedReceiver != null, false, id);
diff --git a/services/core/java/com/android/server/pm/ShortcutPendingTasks.java b/services/core/java/com/android/server/pm/ShortcutPendingTasks.java
deleted file mode 100644
index a5ace56..0000000
--- a/services/core/java/com/android/server/pm/ShortcutPendingTasks.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.pm;
-
-import android.annotation.NonNull;
-import android.util.Slog;
-
-import java.io.PrintWriter;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BooleanSupplier;
-import java.util.function.Consumer;
-import java.util.logging.Handler;
-
-/**
- * Used by {@link ShortcutService} to register tasks to be executed on Handler and also wait for
- * all pending tasks.
- *
- * Tasks can be registered with {@link #addTask(Runnable)}.  Call {@link #waitOnAllTasks()} to wait
- * on all tasks that have been registered.
- *
- * In order to avoid deadlocks, {@link #waitOnAllTasks} MUST NOT be called with any lock held, nor
- * on the handler thread.  These conditions are checked by {@link #mWaitThreadChecker} and wtf'ed.
- *
- * During unit tests, we can't run tasks asynchronously, so we just run Runnables synchronously,
- * which also means the "is lock held" check doesn't work properly during unit tests (e.g. normally
- * when a Runnable is executed on a Handler, the thread doesn't hold any lock, but during the tests
- * we just run a Runnable on the thread that registers it, so the thread may or may not hold locks.)
- * So unfortunately we have to disable {@link #mWaitThreadChecker} during unit tests.
- *
- * Because of the complications like those, this class should be used only for specific purposes:
- * - {@link #addTask(Runnable)} should only be used to register tasks on callbacks from lower level
- * services like the package manager or the activity manager.
- *
- * - {@link #waitOnAllTasks} should only be called at the entry point of RPC calls (or the test only
- * accessors}.
- */
-public class ShortcutPendingTasks {
-    private static final String TAG = "ShortcutPendingTasks";
-
-    private static final boolean DEBUG = false || ShortcutService.DEBUG; // DO NOT SUBMIT WITH TRUE.
-
-    private final Consumer<Runnable> mRunner;
-
-    private final BooleanSupplier mWaitThreadChecker;
-
-    private final Consumer<Throwable> mExceptionHandler;
-
-    /** # of tasks in the queue, including the running one. */
-    private final AtomicInteger mRunningTaskCount = new AtomicInteger();
-
-    /** For dumpsys */
-    private final AtomicLong mLastTaskStartTime = new AtomicLong();
-
-    /**
-     * Constructor.  In order to allow injection during unit tests, it doesn't take a
-     * {@link Handler} directly, and instead takes {@code runner} which will post an argument
-     * to a handler.
-     */
-    public ShortcutPendingTasks(Consumer<Runnable> runner, BooleanSupplier waitThreadChecker,
-            Consumer<Throwable> exceptionHandler) {
-        mRunner = runner;
-        mWaitThreadChecker = waitThreadChecker;
-        mExceptionHandler = exceptionHandler;
-    }
-
-    private static void dlog(String message) {
-        if (DEBUG) {
-            Slog.d(TAG, message);
-        }
-    }
-
-    /**
-     * Block until all tasks that are already queued finish.  DO NOT call it while holding any lock
-     * or on the handler thread.
-     */
-    public boolean waitOnAllTasks() {
-        dlog("waitOnAllTasks: enter");
-        try {
-            // Make sure it's not holding the lock.
-            if (!mWaitThreadChecker.getAsBoolean()) {
-                return false;
-            }
-
-            // Optimize for the no-task case.
-            if (mRunningTaskCount.get() == 0) {
-                return true;
-            }
-
-            final CountDownLatch latch = new CountDownLatch(1);
-
-            addTask(latch::countDown);
-
-            for (; ; ) {
-                try {
-                    if (latch.await(1, TimeUnit.SECONDS)) {
-                        return true;
-                    }
-                    dlog("waitOnAllTasks: Task(s) still running...");
-                } catch (InterruptedException ignore) {
-                }
-            }
-        } finally {
-            dlog("waitOnAllTasks: exit");
-        }
-    }
-
-    /**
-     * Add a new task.  This operation is lock-free.
-     */
-    public void addTask(Runnable task) {
-        mRunningTaskCount.incrementAndGet();
-        mLastTaskStartTime.set(System.currentTimeMillis());
-
-        dlog("Task registered");
-
-        mRunner.accept(() -> {
-            try {
-                dlog("Task started");
-
-                task.run();
-            } catch (Throwable th) {
-                mExceptionHandler.accept(th);
-            } finally {
-                dlog("Task finished");
-                mRunningTaskCount.decrementAndGet();
-            }
-        });
-    }
-
-    public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
-        pw.print(prefix);
-        pw.print("Pending tasks:  # running tasks: ");
-        pw.println(mRunningTaskCount.get());
-
-        pw.print(prefix);
-        pw.print("  Last task started time: ");
-        final long lastStarted = mLastTaskStartTime.get();
-        pw.print(" [");
-        pw.print(lastStarted);
-        pw.print("] ");
-        pw.println(ShortcutService.formatTime(lastStarted));
-    }
-}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index a9018b3..5f8cbbf 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -49,7 +49,6 @@
 import android.graphics.Canvas;
 import android.graphics.RectF;
 import android.graphics.drawable.Icon;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -82,6 +81,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.Preconditions;
@@ -122,6 +122,9 @@
 
 /**
  * TODO:
+ * - Deal with the async nature of PACKAGE_ADD.  Basically when a publisher does anything after
+ *   it's upgraded, the manager should make sure the upgrade process has been executed.
+ *
  * - getIconMaxWidth()/getIconMaxHeight() should use xdpi and ydpi.
  *   -> But TypedValue.applyDimension() doesn't differentiate x and y..?
  *
@@ -301,8 +304,6 @@
 
     private final AtomicBoolean mBootCompleted = new AtomicBoolean();
 
-    private final ShortcutPendingTasks mPendingTasks;
-
     private static final int PACKAGE_MATCH_FLAGS =
             PackageManager.MATCH_DIRECT_BOOT_AWARE
                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
@@ -376,41 +377,16 @@
         mUsageStatsManagerInternal = Preconditions.checkNotNull(
                 LocalServices.getService(UsageStatsManagerInternal.class));
 
-        mPendingTasks = new ShortcutPendingTasks(
-                this::injectPostToHandler,
-                this::injectCheckPendingTaskWaitThread,
-                throwable -> wtf(throwable.getMessage(), throwable));
-
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
         }
 
+        mPackageMonitor.register(context, looper, UserHandle.ALL, /* externalStorage= */ false);
+
         injectRegisterUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE
                 | ActivityManager.UID_OBSERVER_GONE);
     }
 
-    /**
-     * Check whether {@link ShortcutPendingTasks#waitOnAllTasks()} can be called on the current
-     * thread.
-     *
-     * During unit tests, all tasks are executed synchronously which makes the lock held check would
-     * misfire, so we override this method to always return true.
-     */
-    @VisibleForTesting
-    boolean injectCheckPendingTaskWaitThread() {
-        // We shouldn't wait while holding mLock.  We should never do this so wtf().
-        if (Thread.holdsLock(mLock)) {
-            wtf("waitOnAllTasks() called while holding the lock");
-            return false;
-        }
-        // This shouldn't be called on the handler thread either.
-        if (Thread.currentThread() == mHandler.getLooper().getThread()) {
-            wtf("waitOnAllTasks() called on handler thread");
-            return false;
-        }
-        return true;
-    }
-
     void logDurationStat(int statId, long start) {
         synchronized (mStatLock) {
             mCountStats[statId]++;
@@ -1516,8 +1492,6 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
@@ -1567,8 +1541,6 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
@@ -1647,8 +1619,6 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
@@ -1699,8 +1669,6 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
@@ -1728,8 +1696,6 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
@@ -1750,8 +1716,6 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
 
@@ -1774,8 +1738,6 @@
     public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts();
         }
@@ -1788,9 +1750,6 @@
     public ParceledListSlice<ShortcutInfo> getDynamicShortcuts(String packageName,
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
-
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
@@ -1802,9 +1761,6 @@
     public ParceledListSlice<ShortcutInfo> getManifestShortcuts(String packageName,
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
-
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
@@ -1816,9 +1772,6 @@
     public ParceledListSlice<ShortcutInfo> getPinnedShortcuts(String packageName,
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
-
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return getShortcutsWithQueryLocked(
                     packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
@@ -1848,8 +1801,6 @@
     public int getRemainingCallCount(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return mMaxUpdatesPerInterval
                     - getPackageShortcutsLocked(packageName, userId).getApiCallCount();
@@ -1860,8 +1811,6 @@
     public long getRateLimitResetTime(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return getNextResetTimeLocked();
         }
@@ -1880,8 +1829,6 @@
     public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         Preconditions.checkNotNull(shortcutId);
 
         if (DEBUG) {
@@ -1914,8 +1861,6 @@
     public void resetThrottling() {
         enforceSystemOrShell();
 
-        mPendingTasks.waitOnAllTasks();
-
         resetThrottlingInner(getCallingUserId());
     }
 
@@ -1948,9 +1893,6 @@
         if (DEBUG) {
             Slog.d(TAG, "onApplicationActive: package=" + packageName + "  userid=" + userId);
         }
-
-        mPendingTasks.waitOnAllTasks();
-
         enforceResetThrottlingPermission();
         resetPackageThrottling(packageName, userId);
     }
@@ -2113,14 +2055,6 @@
                 @Nullable String packageName, @Nullable List<String> shortcutIds,
                 @Nullable ComponentName componentName,
                 int queryFlags, int userId) {
-
-            // When this method is called from onShortcutChangedInner() in LauncherApps,
-            // we're on the handler thread.  Do not try to wait on tasks.  Not waiting for pending
-            // tasks on this specific case should be fine.
-            if (Thread.currentThread() != mHandler.getLooper().getThread()) {
-                mPendingTasks.waitOnAllTasks();
-            }
-
             final ArrayList<ShortcutInfo> ret = new ArrayList<>();
             final boolean cloneKeyFieldOnly =
                     ((queryFlags & ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) != 0);
@@ -2199,8 +2133,6 @@
             Preconditions.checkStringNotEmpty(packageName, "packageName");
             Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2238,8 +2170,6 @@
             Preconditions.checkStringNotEmpty(packageName, "packageName");
             Preconditions.checkNotNull(shortcutIds, "shortcutIds");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 final ShortcutLauncher launcher =
                         getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
@@ -2260,8 +2190,6 @@
             Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
             Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2292,8 +2220,6 @@
             Preconditions.checkNotNull(packageName, "packageName");
             Preconditions.checkNotNull(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2318,8 +2244,6 @@
             Preconditions.checkNotNull(packageName, "packageName");
             Preconditions.checkNotNull(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2380,18 +2304,9 @@
                 if (DEBUG) {
                     Slog.d(TAG, "onSystemLocaleChangedNoLock: " + mLocaleChangeSequenceNumber.get());
                 }
-                mPendingTasks.addTask(() -> handleLocaleChanged());
+                injectPostToHandler(() -> handleLocaleChanged());
             }
         }
-
-        @Override
-        public void onPackageBroadcast(Intent intent) {
-            if (DEBUG) {
-                Slog.d(TAG, "onPackageBroadcast");
-            }
-            mPendingTasks.addTask(() -> ShortcutService.this.onPackageBroadcast(
-                    new Intent(intent)));
-        }
     }
 
     void handleLocaleChanged() {
@@ -2408,49 +2323,58 @@
         }
     }
 
-    private void onPackageBroadcast(Intent intent) {
-        final int userId  = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-        if (userId == UserHandle.USER_NULL) {
-            Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
-            return;
+    /**
+     * Package event callbacks.
+     */
+    @VisibleForTesting
+    final PackageMonitor mPackageMonitor = new PackageMonitor() {
+
+        private boolean isUserUnlocked() {
+            return mUserManager.isUserUnlocked(getChangingUserId());
         }
 
-        final String action = intent.getAction();
-
-        if (!mUserManager.isUserUnlocked(userId)) {
-            if (DEBUG) {
-                Slog.d(TAG, "Ignoring package broadcast " + action + " for locked/stopped user "
-                        + userId);
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // clearCallingIdentity is not needed normally, but need to do it for the unit test.
+            final long token = injectClearCallingIdentity();
+            try {
+                super.onReceive(context, intent);
+            } finally {
+                injectRestoreCallingIdentity(token);
             }
-            return;
         }
 
-        final Uri intentUri = intent.getData();
-        final String packageName = (intentUri != null) ? intentUri.getSchemeSpecificPart() : null;
-        if (packageName == null) {
-            Slog.w(TAG, "Intent broadcast does not contain package name: " + intent);
-            return;
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            if (!isUserUnlocked()) return;
+            handlePackageAdded(packageName, getChangingUserId());
         }
 
-        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
-
-        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
-            if (replacing) {
-                handlePackageUpdateFinished(packageName, userId);
-            } else {
-                handlePackageAdded(packageName, userId);
-            }
-        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
-            if (!replacing) {
-                handlePackageRemoved(packageName, userId);
-            }
-        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
-            handlePackageChanged(packageName, userId);
-
-        } else if (Intent.ACTION_PACKAGE_DATA_CLEARED.equals(action)) {
-            handlePackageDataCleared(packageName, userId);
+        @Override
+        public void onPackageUpdateFinished(String packageName, int uid) {
+            if (!isUserUnlocked()) return;
+            handlePackageUpdateFinished(packageName, getChangingUserId());
         }
-    }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            if (!isUserUnlocked()) return;
+            handlePackageRemoved(packageName, getChangingUserId());
+        }
+
+        @Override
+        public void onPackageDataCleared(String packageName, int uid) {
+            if (!isUserUnlocked()) return;
+            handlePackageDataCleared(packageName, getChangingUserId());
+        }
+
+        @Override
+        public boolean onPackageChanged(String packageName, int uid, String[] components) {
+            if (!isUserUnlocked()) return false;
+            handlePackageChanged(packageName, getChangingUserId());
+            return false; // We don't need to receive onSomePackagesChanged(), so just false.
+        }
+    };
 
     /**
      * Called when a user is unlocked.
@@ -3097,9 +3021,6 @@
                 pw.println(Log.getStackTraceString(mLastWtfStacktrace));
             }
 
-            pw.println();
-            mPendingTasks.dump(pw, "  ");
-
             for (int i = 0; i < mUsers.size(); i++) {
                 pw.println();
                 mUsers.valueAt(i).dump(pw, "  ");
@@ -3148,8 +3069,6 @@
 
         enforceShell();
 
-        mPendingTasks.waitOnAllTasks();
-
         final int status = (new MyShellCommand()).exec(this, in, out, err, args, resultReceiver);
 
         resultReceiver.send(status, null);
@@ -3176,6 +3095,10 @@
                     case "--user":
                         if (takeUser) {
                             mUserId = UserHandle.parseUserArg(getNextArgRequired());
+                            if (!mUserManager.isUserUnlocked(mUserId)) {
+                                throw new CommandException(
+                                        "User " + mUserId + " is not running or locked");
+                            }
                             break;
                         }
                         // fallthrough
@@ -3501,7 +3424,6 @@
 
     @VisibleForTesting
     ShortcutPackage getPackageShortcutForTest(String packageName, int userId) {
-        mPendingTasks.waitOnAllTasks();
         synchronized (mLock) {
             final ShortcutUser user = mUsers.get(userId);
             if (user == null) return null;
@@ -3512,12 +3434,8 @@
 
     @VisibleForTesting
     ShortcutInfo getPackageShortcutForTest(String packageName, String shortcutId, int userId) {
-        mPendingTasks.waitOnAllTasks();
         synchronized (mLock) {
-            final ShortcutUser user = mUsers.get(userId);
-            if (user == null) return null;
-
-            final ShortcutPackage pkg = user.getAllPackagesForTest().get(packageName);
+            final ShortcutPackage pkg = getPackageShortcutForTest(packageName, userId);
             if (pkg == null) return null;
 
             return pkg.findShortcutById(shortcutId);
@@ -3552,12 +3470,4 @@
             forEachLoadedUserLocked(u -> u.forAllPackageItems(ShortcutPackageItem::verifyStates));
         }
     }
-
-    ShortcutPendingTasks getPendingTasksForTest() {
-        return mPendingTasks;
-    }
-
-    Object getLockForTest() {
-        return mLock;
-    }
 }
diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
index 2e32fe3..c764833 100644
--- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
@@ -134,7 +134,7 @@
     }
 
     public void immersiveModeChangedLw(String pkg, boolean isImmersiveMode,
-            boolean userSetupComplete) {
+            boolean userSetupComplete, boolean navBarEmpty) {
         mHandler.removeMessages(H.SHOW);
         if (isImmersiveMode) {
             final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg);
@@ -144,6 +144,7 @@
                     && (DEBUG_SHOW_EVERY_TIME || !mConfirmed)
                     && userSetupComplete
                     && !mVrModeEnabled
+                    && !navBarEmpty
                     && !UserManager.isDeviceInDemoMode(mContext)) {
                 mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
             }
@@ -152,12 +153,13 @@
         }
     }
 
-    public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
+    public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode,
+            boolean navBarEmpty) {
         if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
             // turning the screen back on within the panic threshold
             return mClingWindow == null;
         }
-        if (isScreenOn && inImmersiveMode) {
+        if (isScreenOn && inImmersiveMode && !navBarEmpty) {
             // turning the screen off, remember if we were in immersive mode
             mPanicTime = time;
         } else {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3f71ba4..fbc727d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1024,7 +1024,8 @@
         // Detect user pressing the power button in panic when an application has
         // taken over the whole screen.
         boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
-                SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags));
+                SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags),
+                isNavBarEmpty(mLastSystemUiFlags));
         if (panic) {
             mHandler.post(mHiddenNavPanic);
         }
@@ -7590,7 +7591,7 @@
         if (win != null && oldImmersiveMode != newImmersiveMode) {
             final String pkg = win.getOwningPackage();
             mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode,
-                    isUserSetupComplete());
+                    isUserSetupComplete(), isNavBarEmpty(win.getSystemUiVisibility()));
         }
 
         vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis);
@@ -7649,6 +7650,14 @@
                 && canHideNavigationBar();
     }
 
+    private static boolean isNavBarEmpty(int systemUiFlags) {
+        final int disableNavigationBar = (View.STATUS_BAR_DISABLE_HOME
+                | View.STATUS_BAR_DISABLE_BACK
+                | View.STATUS_BAR_DISABLE_RECENT);
+
+        return (systemUiFlags & disableNavigationBar) == disableNavigationBar;
+    }
+
     /**
      * @return whether the navigation or status bar can be made translucent
      *
diff --git a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
index 77e8b1f..40ee5d8 100644
--- a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
+++ b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
@@ -246,7 +246,9 @@
         Intent queryIntent = new Intent(serviceName);
         List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
                 queryIntent,
-                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA |
+                                    PackageManager.MATCH_DIRECT_BOOT_AWARE |
+                                    PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                 userId);
         if (installedServices != null) {
             for (int i = 0, count = installedServices.size(); i < count; i++) {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 2b58156..3aefc08 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -604,7 +604,7 @@
             float scaleH = mTmpRect.height() / (float) appHeight;
             Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
                     computePivot(mTmpRect.left, scaleW),
-                    computePivot(mTmpRect.right, scaleH));
+                    computePivot(mTmpRect.top, scaleH));
             scale.setInterpolator(mDecelerateInterpolator);
 
             Animation alpha = new AlphaAnimation(0, 1);
@@ -1615,8 +1615,7 @@
         if (isTransitionSet()) {
             clear();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
-            putDefaultNextAppTransitionCoordinates(startX, startY, startX + startWidth,
-                    startY + startHeight, null);
+            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
             postAnimationCallback();
         }
     }
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index 855a2b6..c351e73 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -321,13 +321,15 @@
     private void setupDemoUser(UserInfo userInfo) {
         UserManager um = getUserManager();
         UserHandle user = UserHandle.of(userInfo.id);
-        LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext());
-        lockPatternUtils.setLockScreenDisabled(true, userInfo.id);
         um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
         um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
         um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
         um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
         um.setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user);
+        um.setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, true, user);
+        // Disallow rebooting in safe mode - controlled by user 0
+        getUserManager().setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, true,
+                UserHandle.SYSTEM);
         Settings.Secure.putIntForUser(getContext().getContentResolver(),
                 Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
         Settings.Secure.putIntForUser(getContext().getContentResolver(),
@@ -496,6 +498,9 @@
         mAmi.updatePersistentConfigurationForUser(getSystemUsersConfiguration(), userId);
         turnOffAllFlashLights();
         muteVolumeStreams();
+        // Disable lock screen for demo users.
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext());
+        lockPatternUtils.setLockScreenDisabled(true, userId);
         mNm.notifyAsUser(TAG, 1, createResetNotification(), UserHandle.of(userId));
 
         synchronized (mActivityLock) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 01c19d0..1be57bc 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -404,11 +404,6 @@
             // During tests, WTF is fatal.
             fail(message + "  exception: " + th + "\n" + Log.getStackTraceString(th));
         }
-
-        @Override
-        boolean injectCheckPendingTaskWaitThread() {
-            return true;
-        }
     }
 
     /** ShortcutManager with injection override methods. */
@@ -853,8 +848,6 @@
 
     protected void shutdownServices() {
         if (mService != null) {
-            mService.getPendingTasksForTest().waitOnAllTasks();
-
             // Flush all the unsaved data from the previous instance.
             mService.saveDirtyInfo();
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index c7673d1..bf6c2ff 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -62,7 +62,6 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.Manifest.permission;
 import android.app.ActivityManager;
@@ -1298,7 +1297,8 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_3);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -1316,7 +1316,8 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertTrue(mManager.setDynamicShortcuts(list(
@@ -2814,7 +2815,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                     R.xml.shortcut_2);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+            mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
                 .areAllManifest()
@@ -2851,7 +2852,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_0);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         assertForLauncherCallback(mLauncherApps, () -> {
@@ -3471,7 +3472,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -3488,7 +3489,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -3850,7 +3851,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertWith(getCallerShortcuts())
@@ -3890,7 +3891,7 @@
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
 
         uninstallPackage(USER_0, CALLING_PACKAGE_1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -3910,7 +3911,7 @@
         mRunningUsers.put(USER_10, true);
 
         uninstallPackage(USER_10, CALLING_PACKAGE_2);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4001,7 +4002,7 @@
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
         assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
 
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDataClear(CALLING_PACKAGE_1, USER_0));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4020,7 +4021,7 @@
 
         mRunningUsers.put(USER_10, true);
 
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDataClear(CALLING_PACKAGE_2, USER_10));
 
         assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
@@ -4047,7 +4048,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4068,7 +4069,7 @@
         });
 
         // Clear data
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageDataClear(CALLING_PACKAGE_1, USER_10));
 
         // Only manifest shortcuts will remain, and are no longer pinned.
@@ -4133,9 +4134,9 @@
         reset(c0);
         reset(c10);
 
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
 
         waitOnMainThread();
@@ -4156,7 +4157,7 @@
         updatePackageVersion(CALLING_PACKAGE_1, 1);
 
         // Then send the broadcast, to only user-0.
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
 
         waitOnMainThread();
@@ -4221,7 +4222,7 @@
         updatePackageVersion(CALLING_PACKAGE_2, 10);
 
         // Then send the broadcast, to only user-0.
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0));
         mService.handleUnlockUser(USER_10);
 
@@ -4245,7 +4246,7 @@
         updatePackageVersion(CALLING_PACKAGE_3, 100);
 
         // Then send the broadcast, to only user-0.
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0));
         mService.handleUnlockUser(USER_10);
 
@@ -4327,7 +4328,7 @@
 
         // Update the package.
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -4356,7 +4357,7 @@
         mRunningUsers.put(USER_10, true);
 
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4388,7 +4389,7 @@
         });
 
         // First, no changes.
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4411,7 +4412,7 @@
 
         // Disable activity 1
         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4431,7 +4432,7 @@
         // Re-enable activity 1.
         // Manifest shortcuts will be re-published, but dynamic ones are not.
         mEnabledActivityChecker = (activity, userId) -> true;
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4455,7 +4456,7 @@
         // Disable activity 2
         // Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled.
         mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
 
         runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
@@ -4518,7 +4519,7 @@
         setCaller(LAUNCHER_1, USER_0);
         assertForLauncherCallback(mLauncherApps, () -> {
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
         }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
                 // Make sure the launcher gets callbacks.
@@ -5160,7 +5161,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+        mService.mPackageMonitor.onReceive(mServiceContext,
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Pin from launcher 1.
@@ -5173,7 +5174,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+        mService.mPackageMonitor.onReceive(mServiceContext,
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Make sure the manifest shortcuts have been published.
@@ -5634,7 +5635,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -5655,7 +5656,7 @@
                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_2, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -5692,7 +5693,7 @@
                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -5729,7 +5730,7 @@
         mRunningUsers.put(USER_10, false);
         mUnlockedUsers.put(USER_10, false);
 
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
             assertEmpty(mManager.getManifestShortcuts());
@@ -5739,7 +5740,7 @@
         // Try again, but the user is locked, so still ignored.
         mRunningUsers.put(USER_10, true);
 
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
             assertEmpty(mManager.getManifestShortcuts());
@@ -5750,7 +5751,7 @@
         mUnlockedUsers.put(USER_10, true);
 
         // Send PACKAGE_ADD broadcast to have Package 2 on user-10 publish manifest shortcuts.
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
 
         runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
@@ -5791,7 +5792,7 @@
                 R.xml.shortcut_5_reverse);
 
         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
 
         runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
@@ -5819,7 +5820,7 @@
                 new ComponentName(CALLING_PACKAGE_2, ShortcutActivity2.class.getName()),
                 R.xml.shortcut_0);
         updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
 
         // No manifest shortcuts, and pinned ones are disabled.
@@ -5850,7 +5851,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -5865,7 +5866,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -5880,7 +5881,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_3);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -5896,7 +5897,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_4);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -5924,7 +5925,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -5962,7 +5963,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_error_4);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Make sure 3, 4 and 5 still exist but disabled.
@@ -6010,7 +6011,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -6115,7 +6116,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6212,7 +6213,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -6231,7 +6232,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1_disable);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Because shortcut 1 wasn't pinned, it'll just go away.
@@ -6252,7 +6253,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Only the valid one is published.
@@ -6275,7 +6276,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1_disable);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         // Because shortcut 1 was pinned, it'll still exist as pinned, but disabled.
@@ -6308,7 +6309,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2_duplicate);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6338,7 +6339,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6410,7 +6411,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6460,7 +6461,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_2);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(LAUNCHER_1, USER_0, () -> {
@@ -6471,7 +6472,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_1);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6553,7 +6554,7 @@
                 new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                 R.xml.shortcut_5);
         updatePackageVersion(CALLING_PACKAGE_1, 1);
-        mInternal.onPackageBroadcast(
+                mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
@@ -6623,7 +6624,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                     R.xml.shortcut_2);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
             assertEquals(2, mManager.getManifestShortcuts().size());
 
@@ -6749,7 +6750,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                     R.xml.shortcut_2);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
 
             assertEquals(2, mManager.getManifestShortcuts().size());
@@ -6898,7 +6899,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
                     R.xml.shortcut_1);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
             assertEquals(1, mManager.getManifestShortcuts().size());
 
@@ -6918,7 +6919,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
                     R.xml.shortcut_1_alt);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
             assertEquals(3, mManager.getManifestShortcuts().size());
 
@@ -6938,7 +6939,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
                     R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3.
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
             assertEquals(5, mManager.getManifestShortcuts().size());
 
@@ -6957,7 +6958,7 @@
                     new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
                     R.xml.shortcut_0);
             updatePackageVersion(CALLING_PACKAGE_1, 1);
-            mInternal.onPackageBroadcast(
+                    mService.mPackageMonitor.onReceive(getTestContext(),
                     genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
             assertEquals(0, mManager.getManifestShortcuts().size());
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
index fcf7ea2..eb4db7a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
@@ -66,7 +66,7 @@
     private void publishManifestShortcuts(ComponentName activity, int resId) {
         addManifestShortcutResource(activity, resId);
         updatePackageVersion(CALLING_PACKAGE, 1);
-        mInternal.onPackageBroadcast(
+        mService.mPackageMonitor.onReceive(getTestContext(),
                 genPackageAddIntent(CALLING_PACKAGE, USER_0));
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java
deleted file mode 100644
index bf1ed98..0000000
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutPendingTasksTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.pm;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Run with:
- adb install \
-   -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.pm.ShortcutPendingTasksTest \
-   -w com.android.frameworks.servicestests
- */
-@LargeTest
-public class ShortcutPendingTasksTest extends BaseShortcutManagerTest {
-    public void testAll() {
-        final AtomicReference<Throwable> thrown = new AtomicReference<>();
-
-        final AtomicBoolean threadCheckerResult = new AtomicBoolean(true);
-
-        final Handler handler = new Handler(Looper.getMainLooper());
-
-        final ShortcutPendingTasks tasks = new ShortcutPendingTasks(
-                handler::post,
-                threadCheckerResult::get,
-                thrown::set);
-
-        // No pending tasks, shouldn't block.
-        assertTrue(tasks.waitOnAllTasks());
-
-        final AtomicInteger counter = new AtomicInteger();
-
-        // Run one task.
-        tasks.addTask(() -> {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ignore) {
-            }
-            counter.incrementAndGet();
-        });
-
-        assertTrue(tasks.waitOnAllTasks());
-        assertNull(thrown.get());
-
-        assertEquals(1, counter.get());
-
-        // Run 3 tasks.
-
-        // We use this ID to make sure only one task can run at the same time.
-        final AtomicInteger currentTaskId = new AtomicInteger();
-
-        tasks.addTask(() -> {
-            currentTaskId.set(1);
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException ignore) {
-            }
-            counter.incrementAndGet();
-            assertEquals(1, currentTaskId.get());
-        });
-        tasks.addTask(() -> {
-            currentTaskId.set(2);
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException ignore) {
-            }
-            counter.incrementAndGet();
-            assertEquals(2, currentTaskId.get());
-        });
-        tasks.addTask(() -> {
-            currentTaskId.set(3);
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException ignore) {
-            }
-            counter.incrementAndGet();
-            assertEquals(3, currentTaskId.get());
-        });
-
-        assertTrue(tasks.waitOnAllTasks());
-        assertNull(thrown.get());
-        assertEquals(4, counter.get());
-
-        // No tasks running, shouldn't block.
-        assertTrue(tasks.waitOnAllTasks());
-        assertNull(thrown.get());
-        assertEquals(4, counter.get());
-
-        // Now the thread checker returns false, so waitOnAllTasks() returns false.
-        threadCheckerResult.set(false);
-        assertFalse(tasks.waitOnAllTasks());
-
-        threadCheckerResult.set(true);
-
-        // Make sure the exception handler is called.
-        tasks.addTask(() -> {
-            throw new RuntimeException("XXX");
-        });
-        assertTrue(tasks.waitOnAllTasks());
-        assertNotNull(thrown.get());
-        MoreAsserts.assertContainsRegex("XXX", thrown.get().getMessage());
-    }
-}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 26ef0cb..df81d7f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5538,5 +5538,22 @@
         }
         return 0;
     }
+
+    /**
+     * Policy control of data connection. Usually used when data limit is passed.
+     * @param enabled True if enabling the data, otherwise disabling.
+     * @param subId sub id
+     * @hide
+     */
+    public void setPolicyDataEnabled(boolean enabled, int subId) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                service.setPolicyDataEnabled(enabled, subId);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#setPolicyDataEnabled", e);
+        }
+    }
 }
 
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 8166e00..f01e4c0 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -105,6 +105,7 @@
     public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 43;
     public static final int EVENT_REDIRECTION_DETECTED = BASE + 44;
     public static final int EVENT_PCO_DATA_RECEIVED = BASE + 45;
+    public static final int EVENT_SET_CARRIER_DATA_ENABLED = BASE + 46;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 2168b0e..167e1a7 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1158,4 +1158,12 @@
      * @hide
      */
     long getVtDataUsage();
+
+    /**
+     * Policy control of data connection. Usually used when data limit is passed.
+     * @param enabled True if enabling the data, otherwise disabling.
+     * @param subId Subscription index
+     * @hide
+     */
+    void setPolicyDataEnabled(boolean enabled, int subId);
 }
diff --git a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
index d32f071..88847ee 100644
--- a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
@@ -23,19 +23,22 @@
 import android.widget.ArrayAdapter;
 
 public class ShadowGridActivity extends AppCompatActivity {
+    public static class NoDividerListFragment extends ListFragment {
+        @Override
+        public void onViewCreated(View view, Bundle savedInstanceState) {
+            super.onViewCreated(view, savedInstanceState);
+            getListView().setDivider(null);
+        }
+    };
+
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         FragmentManager fm = getSupportFragmentManager();
         if (fm.findFragmentById(android.R.id.content) == null) {
-            ListFragment listFragment = new ListFragment() {
-                @Override
-                public void onViewCreated(View view, Bundle savedInstanceState) {
-                    super.onViewCreated(view, savedInstanceState);
-                    getListView().setDivider(null);
-                }
-            };
+            ListFragment listFragment = new NoDividerListFragment();
 
             listFragment.setListAdapter(new ArrayAdapter<>(this,
                     R.layout.card_row, R.id.card_text, TextUtils.buildSimpleStringList()));