Merge "Add alternative EXTRA_CALL_RAT_TYPE definition for noncompliant modems." 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/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 3cf13d9..3a92b9e 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -36,8 +36,4 @@
 LOCAL_32_BIT_ONLY := true
 endif
 
-# get asserts to work
-APP_OPTIM := debug
-LOCAL_CFLAGS += -UNDEBUG
-
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 4098772..ebcc9ff 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -588,7 +588,7 @@
         return false;
     }
 
-    bool hasAudio = false;
+    Animation::Part* partWithAudio = NULL;
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
     while ((entry = zip->nextEntry(cookie)) != NULL) {
@@ -612,10 +612,10 @@
                             if (map) {
                                 Animation::Part& part(animation.parts.editItemAt(j));
                                 if (leaf == "audio.wav") {
-                                    hasAudio = true;
                                     // a part may have at most one audio file
                                     part.audioData = (uint8_t *)map->getDataPtr();
                                     part.audioLength = map->getDataLength();
+                                    partWithAudio = &part;
                                 } else if (leaf == "trim.txt") {
                                     part.trimData.setTo((char const*)map->getDataPtr(),
                                                         map->getDataLength());
@@ -666,9 +666,11 @@
     }
 
     // Create and initialize audioplay if there is a wav file in any of the animations.
-    if (hasAudio) {
+    if (partWithAudio != NULL) {
         ALOGD("found audio.wav, creating playback engine");
-        audioplay::create();
+        if (!audioplay::create(partWithAudio->audioData, partWithAudio->audioLength)) {
+            return false;
+        }
     }
 
     zip->endIteration(cookie);
@@ -904,7 +906,10 @@
     mLoadedFiles.add(animation->fileName);
 
     parseAnimationDesc(*animation);
-    preloadZip(*animation);
+    if (!preloadZip(*animation)) {
+        return NULL;
+    }
+
 
     mLoadedFiles.remove(fn);
     return animation;
diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp
index e20ef0c..8a5c2c6 100644
--- a/cmds/bootanimation/audioplay.cpp
+++ b/cmds/bootanimation/audioplay.cpp
@@ -21,7 +21,6 @@
 
 #define CHATTY ALOGD
 
-#include <assert.h>
 #include <string.h>
 
 #include <utils/Log.h>
@@ -80,8 +79,6 @@
 void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
     (void)bq;
     (void)context;
-    assert(bq == bqPlayerBufferQueue);
-    assert(NULL == context);
     audioplay::setPlaying(false);
 }
 
@@ -90,39 +87,56 @@
 }
 
 // create the engine and output mix objects
-void createEngine() {
+bool createEngine() {
     SLresult result;
 
     // create engine
     result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("slCreateEngine failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // realize the engine
     result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl engine Realize failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // get the engine interface, which is needed in order to create other objects
     result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl engine GetInterface failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // create output mix, with environmental reverb specified as a non-required interface
     const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
     const SLboolean req[1] = {SL_BOOLEAN_FALSE};
     result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl engine CreateOutputMix failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // realize the output mix
     result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl outputMix Realize failed with result %d", result);
+        return false;
+    }
     (void)result;
+
+    return true;
 }
 
 // create buffer queue audio player
-void createBufferQueueAudioPlayer(const ChunkFormat* chunkFormat) {
+bool createBufferQueueAudioPlayer(const ChunkFormat* chunkFormat) {
     SLresult result;
 
     // configure audio source
@@ -148,83 +162,89 @@
     const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
     result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
             2, ids, req);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl CreateAudioPlayer failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // realize the player
     result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl player Realize failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // get the play interface
     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl player GetInterface failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // get the buffer queue interface
     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
             &bqPlayerBufferQueue);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl playberBufferQueue GetInterface failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // register callback on the buffer queue
     result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl bqPlayerBufferQueue RegisterCallback failed with result %d", result);
+        return false;
+    }
     (void)result;
 
-#if 0   // mute/solo is not supported for sources that are known to be mono, as this is
-    // get the mute/solo interface
-    result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
-    assert(SL_RESULT_SUCCESS == result);
-    (void)result;
-#endif
-
     // get the volume interface
     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
-    assert(SL_RESULT_SUCCESS == result);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("sl volume GetInterface failed with result %d", result);
+        return false;
+    }
     (void)result;
 
     // set the player's state to playing
     audioplay::setPlaying(true);
     CHATTY("Created buffer queue player: %p", bqPlayerBufferQueue);
+    return true;
 }
 
-} // namespace
-
-void create() {
-    createEngine();
-}
-
-bool playClip(const uint8_t* buf, int size) {
-    // Parse the WAV header
-    nextBuffer = buf;
-    nextSize = size;
-    const RiffWaveHeader* wavHeader = (const RiffWaveHeader*)buf;
-    if (nextSize < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
+bool parseClipBuf(const uint8_t* clipBuf, int clipBufSize, const ChunkFormat** oChunkFormat,
+                  const uint8_t** oSoundBuf, unsigned* oSoundBufSize) {
+    *oSoundBuf = clipBuf;
+    *oSoundBufSize = clipBufSize;
+    *oChunkFormat = NULL;
+    const RiffWaveHeader* wavHeader = (const RiffWaveHeader*)*oSoundBuf;
+    if (*oSoundBufSize < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
         (wavHeader->wave_id != ID_WAVE)) {
         ALOGE("Error: audio file is not a riff/wave file\n");
         return false;
     }
-    nextBuffer += sizeof(*wavHeader);
-    nextSize -= sizeof(*wavHeader);
+    *oSoundBuf += sizeof(*wavHeader);
+    *oSoundBufSize -= sizeof(*wavHeader);
 
-    const ChunkFormat* chunkFormat = nullptr;
     while (true) {
-        const ChunkHeader* chunkHeader = (const ChunkHeader*)nextBuffer;
-        if (nextSize < sizeof(*chunkHeader)) {
+        const ChunkHeader* chunkHeader = (const ChunkHeader*)*oSoundBuf;
+        if (*oSoundBufSize < sizeof(*chunkHeader)) {
             ALOGE("EOF reading chunk headers");
             return false;
         }
 
-        nextBuffer += sizeof(*chunkHeader);
-        nextSize -= sizeof(*chunkHeader);
+        *oSoundBuf += sizeof(*chunkHeader);
+        *oSoundBufSize -= sizeof(*chunkHeader);
 
         bool endLoop = false;
         switch (chunkHeader->id) {
             case ID_FMT:
-                chunkFormat = (const ChunkFormat*)nextBuffer;
-                nextBuffer += chunkHeader->sz;
-                nextSize -= chunkHeader->sz;
+                *oChunkFormat = (const ChunkFormat*)*oSoundBuf;
+                *oSoundBuf += chunkHeader->sz;
+                *oSoundBufSize -= chunkHeader->sz;
                 break;
             case ID_DATA:
                 /* Stop looking for chunks */
@@ -232,27 +252,49 @@
                 break;
             default:
                 /* Unknown chunk, skip bytes */
-                nextBuffer += chunkHeader->sz;
-                nextSize -= chunkHeader->sz;
+                *oSoundBuf += chunkHeader->sz;
+                *oSoundBufSize -= chunkHeader->sz;
         }
         if (endLoop) {
             break;
         }
     }
 
-    if (!chunkFormat) {
+    if (*oChunkFormat == NULL) {
         ALOGE("format not found in WAV file");
         return false;
     }
+    return true;
+}
 
-    // If this is the first clip, create the buffer based on this WAV's header.
-    // We assume all future clips with be in the same format.
-    if (bqPlayerBufferQueue == nullptr) {
-        createBufferQueueAudioPlayer(chunkFormat);
+} // namespace
+
+bool create(const uint8_t* exampleClipBuf, int exampleClipBufSize) {
+    if (!createEngine()) {
+        return false;
     }
 
-    assert(bqPlayerBufferQueue != nullptr);
-    assert(buf != nullptr);
+    // Parse the example clip.
+    const ChunkFormat* chunkFormat;
+    const uint8_t* soundBuf;
+    unsigned soundBufSize;
+    if (!parseClipBuf(exampleClipBuf, exampleClipBufSize, &chunkFormat, &soundBuf, &soundBufSize)) {
+        return false;
+    }
+
+    // Initialize the BufferQueue based on this clip's format.
+    if (!createBufferQueueAudioPlayer(chunkFormat)) {
+        return false;
+    }
+    return true;
+}
+
+bool playClip(const uint8_t* buf, int size) {
+    // Parse the WAV header
+    const ChunkFormat* chunkFormat;
+    if (!parseClipBuf(buf, size, &chunkFormat, &nextBuffer, &nextSize)) {
+        return false;
+    }
 
     if (!hasPlayer()) {
         ALOGD("cannot play clip %p without a player", buf);
@@ -285,8 +327,6 @@
         // set the player's state
         result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay,
             isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_STOPPED);
-        assert(SL_RESULT_SUCCESS == result);
-        (void)result;
     }
 
 }
diff --git a/cmds/bootanimation/audioplay.h b/cmds/bootanimation/audioplay.h
index bdc0a1c..0e5705af 100644
--- a/cmds/bootanimation/audioplay.h
+++ b/cmds/bootanimation/audioplay.h
@@ -22,10 +22,12 @@
 
 namespace audioplay {
 
-void create();
+// Initializes the engine with an example of the type of WAV clip to play.
+// All buffers passed to playClip are assumed to be in the same format.
+bool create(const uint8_t* exampleClipBuf, int exampleClipBufSize);
 
-// Play a WAV pointed to by buf.  All clips are assumed to be in the same format.
-// playClip should not be called while a clip is still playing.
+// Plays a WAV contained in buf.
+// Should not be called while a clip is still playing.
 bool playClip(const uint8_t* buf, int size);
 void setPlaying(bool isPlaying);
 void destroy();
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/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 5823abf..734bf69 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -165,6 +165,9 @@
      * network restrictions for the requesting app. Note that this flag alone
      * doesn't actually place your {@link JobService} in the foreground; you
      * still need to post the notification yourself.
+     * <p>
+     * To use this flag, the caller must hold the
+     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} permission.
      *
      * @hide
      */
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index de52f73..f994d7e 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -67,17 +67,4 @@
 
     public abstract boolean hasShortcutHostPermission(int launcherUserId,
             @NonNull String callingPackage);
-
-    /**
-     * Called by AM when the system locale changes *within the AM lock*.  ABSOLUTELY do not take
-     * 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/net/network-policy-restrictions.md b/core/java/android/net/network-policy-restrictions.md
index fe13f7a..63ce1a2 100644
--- a/core/java/android/net/network-policy-restrictions.md
+++ b/core/java/android/net/network-policy-restrictions.md
@@ -29,8 +29,8 @@
 | **DS**  |  *WL* |  ok  | blk   |  ok  |  ok   |
 | **ON**  | *!WL* | blk  | blk   | blk  | blk   |
 |         |  *BL* | blk  | blk   | blk  | blk   |
-| **DS**  |  *WL* | blk  |  ok   |  ok  |  ok   |
-| **OFF** | *!WL* | blk  |  ok   |  ok  |  ok   |
+| **DS**  |  *WL* | blk  | blk   |  ok  |  ok   |
+| **OFF** | *!WL* | blk  | blk   |  ok  |  ok   |
 |         |  *BL* | blk  | blk   | blk  | blk   |
 
 
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/provider/Settings.java b/core/java/android/provider/Settings.java
index 5c2778d..765a3a8 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5295,15 +5295,6 @@
                 "accessibility_display_daltonizer";
 
         /**
-         * Float list that specifies the color matrix to apply to
-         * the display. Valid values are defined in AccessibilityManager.
-         *
-         * @hide
-         */
-        public static final String ACCESSIBILITY_DISPLAY_COLOR_MATRIX =
-                "accessibility_display_color_matrix";
-
-        /**
          * Setting that specifies whether automatic click when the mouse pointer stops moving is
          * enabled.
          *
@@ -6334,7 +6325,6 @@
             USB_MASS_STORAGE_ENABLED,                           // moved to global
             ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
             ACCESSIBILITY_DISPLAY_DALTONIZER,
-            ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
             ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 6911b01..69960b0 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -20,6 +20,8 @@
 import android.app.NotificationManager.Policy;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Parcel;
@@ -118,6 +120,7 @@
     private static final String RULE_ATT_ZEN = "zen";
     private static final String RULE_ATT_CONDITION_ID = "conditionId";
     private static final String RULE_ATT_CREATION_TIME = "creationTime";
+    private static final String RULE_ATT_ENABLER = "enabler";
 
     public boolean allowCalls = DEFAULT_ALLOW_CALLS;
     public boolean allowRepeatCallers = DEFAULT_ALLOW_REPEAT_CALLERS;
@@ -502,6 +505,7 @@
         rt.conditionId = safeUri(parser, RULE_ATT_CONDITION_ID);
         rt.component = safeComponentName(parser, RULE_ATT_COMPONENT);
         rt.creationTime = safeLong(parser, RULE_ATT_CREATION_TIME, 0);
+        rt.enabler = parser.getAttributeValue(null, RULE_ATT_ENABLER);
         rt.condition = readConditionXml(parser);
         return rt;
     }
@@ -520,6 +524,9 @@
             out.attribute(null, RULE_ATT_CONDITION_ID, rule.conditionId.toString());
         }
         out.attribute(null, RULE_ATT_CREATION_TIME, Long.toString(rule.creationTime));
+        if (rule.enabler != null) {
+            out.attribute(null, RULE_ATT_ENABLER, rule.enabler);
+        }
         if (rule.condition != null) {
             writeConditionXml(rule.condition, out);
         }
@@ -989,6 +996,25 @@
         return UUID.randomUUID().toString().replace("-", "");
     }
 
+    private static String getOwnerCaption(Context context, String owner) {
+        final PackageManager pm = context.getPackageManager();
+        try {
+            final ApplicationInfo info = pm.getApplicationInfo(owner, 0);
+            if (info != null) {
+                final CharSequence seq = info.loadLabel(pm);
+                if (seq != null) {
+                    final String str = seq.toString().trim();
+                    if (str.length() > 0) {
+                        return str;
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            Slog.w(TAG, "Error loading owner caption", e);
+        }
+        return "";
+    }
+
     public static String getConditionSummary(Context context, ZenModeConfig config,
             int userHandle, boolean shortVersion) {
         return getConditionLine(context, config, userHandle, false /*useLine1*/, shortVersion);
@@ -997,23 +1023,28 @@
     private static String getConditionLine(Context context, ZenModeConfig config,
             int userHandle, boolean useLine1, boolean shortVersion) {
         if (config == null) return "";
+        String summary = "";
         if (config.manualRule != null) {
             final Uri id = config.manualRule.conditionId;
-            if (id == null) {
-                return context.getString(com.android.internal.R.string.zen_mode_forever);
+            if (config.manualRule.enabler != null) {
+                summary = getOwnerCaption(context, config.manualRule.enabler);
+            } else {
+                if (id == null) {
+                    summary = context.getString(com.android.internal.R.string.zen_mode_forever);
+                } else {
+                    final long time = tryParseCountdownConditionId(id);
+                    Condition c = config.manualRule.condition;
+                    if (time > 0) {
+                        final long now = System.currentTimeMillis();
+                        final long span = time - now;
+                        c = toTimeCondition(context, time, Math.round(span / (float) MINUTES_MS),
+                                userHandle, shortVersion);
+                    }
+                    final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary;
+                    summary = TextUtils.isEmpty(rt) ? "" : rt;
+                }
             }
-            final long time = tryParseCountdownConditionId(id);
-            Condition c = config.manualRule.condition;
-            if (time > 0) {
-                final long now = System.currentTimeMillis();
-                final long span = time - now;
-                c = toTimeCondition(context, time, Math.round(span / (float) MINUTES_MS),
-                        userHandle, shortVersion);
-            }
-            final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary;
-            return TextUtils.isEmpty(rt) ? "" : rt;
         }
-        String summary = "";
         for (ZenRule automaticRule : config.automaticRules.values()) {
             if (automaticRule.isAutomaticActive()) {
                 if (summary.isEmpty()) {
@@ -1023,6 +1054,7 @@
                             .getString(R.string.zen_mode_rule_name_combination, summary,
                                     automaticRule.name);
                 }
+
             }
         }
         return summary;
@@ -1038,6 +1070,7 @@
         public ComponentName component;  // optional
         public String id;                // required for automatic (unique)
         public long creationTime;        // required for automatic
+        public String enabler;          // package name, only used for manual rules.
 
         public ZenRule() { }
 
@@ -1055,6 +1088,9 @@
                 id = source.readString();
             }
             creationTime = source.readLong();
+            if (source.readInt() == 1) {
+                enabler = source.readString();
+            }
         }
 
         @Override
@@ -1083,6 +1119,12 @@
                 dest.writeInt(0);
             }
             dest.writeLong(creationTime);
+            if (enabler != null) {
+                dest.writeInt(1);
+                dest.writeString(enabler);
+            } else {
+                dest.writeInt(0);
+            }
         }
 
         @Override
@@ -1097,6 +1139,7 @@
                     .append(",component=").append(component)
                     .append(",id=").append(id)
                     .append(",creationTime=").append(creationTime)
+                    .append(",enabler=").append(enabler)
                     .append(']').toString();
         }
 
@@ -1143,6 +1186,9 @@
             if (creationTime != to.creationTime) {
                 d.addLine(item, "creationTime", creationTime, to.creationTime);
             }
+            if (enabler != to.enabler) {
+                d.addLine(item, "enabler", enabler, to.enabler);
+            }
         }
 
         @Override
@@ -1158,13 +1204,14 @@
                     && Objects.equals(other.condition, condition)
                     && Objects.equals(other.component, component)
                     && Objects.equals(other.id, id)
-                    && other.creationTime == creationTime;
+                    && other.creationTime == creationTime
+                    && Objects.equals(other.enabler, enabler);
         }
 
         @Override
         public int hashCode() {
             return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
-                    component, id, creationTime);
+                    component, id, creationTime, enabler);
         }
 
         public boolean isAutomaticActive() {
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
index b62cc66..b6d720d 100644
--- a/core/java/android/text/Emoji.java
+++ b/core/java/android/text/Emoji.java
@@ -32,111 +32,112 @@
         0x23EC, 0x23ED, 0x23EE, 0x23EF, 0x23F0, 0x23F1, 0x23F2, 0x23F3, 0x23F8, 0x23F9, 0x23FA,
         0x24C2, 0x25AA, 0x25AB, 0x25B6, 0x25C0, 0x25FB, 0x25FC, 0x25FD, 0x25FE, 0x2600, 0x2601,
         0x2602, 0x2603, 0x2604, 0x260E, 0x2611, 0x2614, 0x2615, 0x2618, 0x261D, 0x2620, 0x2622,
-        0x2623, 0x2626, 0x262A, 0x262E, 0x262F, 0x2638, 0x2639, 0x263A, 0x2648, 0x2649, 0x264A,
-        0x264B, 0x264C, 0x264D, 0x264E, 0x264F, 0x2650, 0x2651, 0x2652, 0x2653, 0x2660, 0x2663,
-        0x2665, 0x2666, 0x2668, 0x267B, 0x267F, 0x2692, 0x2693, 0x2694, 0x2696, 0x2697, 0x2699,
-        0x269B, 0x269C, 0x26A0, 0x26A1, 0x26AA, 0x26AB, 0x26B0, 0x26B1, 0x26BD, 0x26BE, 0x26C4,
-        0x26C5, 0x26C8, 0x26CE, 0x26CF, 0x26D1, 0x26D3, 0x26D4, 0x26E9, 0x26EA, 0x26F0, 0x26F1,
-        0x26F2, 0x26F3, 0x26F4, 0x26F5, 0x26F7, 0x26F8, 0x26F9, 0x26FA, 0x26FD, 0x2702, 0x2705,
-        0x2708, 0x2709, 0x270A, 0x270B, 0x270C, 0x270D, 0x270F, 0x2712, 0x2714, 0x2716, 0x271D,
-        0x2721, 0x2728, 0x2733, 0x2734, 0x2744, 0x2747, 0x274C, 0x274E, 0x2753, 0x2754, 0x2755,
-        0x2757, 0x2763, 0x2764, 0x2795, 0x2796, 0x2797, 0x27A1, 0x27B0, 0x27BF, 0x2934, 0x2935,
-        0x2B05, 0x2B06, 0x2B07, 0x2B1B, 0x2B1C, 0x2B50, 0x2B55, 0x3030, 0x303D, 0x3297, 0x3299,
-        0x1F004, 0x1F0CF, 0x1F170, 0x1F171, 0x1F17E, 0x1F17F, 0x1F18E, 0x1F191, 0x1F192, 0x1F193,
-        0x1F194, 0x1F195, 0x1F196, 0x1F197, 0x1F198, 0x1F199, 0x1F19A, 0x1F1E6, 0x1F1E7, 0x1F1E8,
-        0x1F1E9, 0x1F1EA, 0x1F1EB, 0x1F1EC, 0x1F1ED, 0x1F1EE, 0x1F1EF, 0x1F1F0, 0x1F1F1, 0x1F1F2,
-        0x1F1F3, 0x1F1F4, 0x1F1F5, 0x1F1F6, 0x1F1F7, 0x1F1F8, 0x1F1F9, 0x1F1FA, 0x1F1FB, 0x1F1FC,
-        0x1F1FD, 0x1F1FE, 0x1F1FF, 0x1F201, 0x1F202, 0x1F21A, 0x1F22F, 0x1F232, 0x1F233, 0x1F234,
-        0x1F235, 0x1F236, 0x1F237, 0x1F238, 0x1F239, 0x1F23A, 0x1F250, 0x1F251, 0x1F300, 0x1F301,
-        0x1F302, 0x1F303, 0x1F304, 0x1F305, 0x1F306, 0x1F307, 0x1F308, 0x1F309, 0x1F30A, 0x1F30B,
-        0x1F30C, 0x1F30D, 0x1F30E, 0x1F30F, 0x1F310, 0x1F311, 0x1F312, 0x1F313, 0x1F314, 0x1F315,
-        0x1F316, 0x1F317, 0x1F318, 0x1F319, 0x1F31A, 0x1F31B, 0x1F31C, 0x1F31D, 0x1F31E, 0x1F31F,
-        0x1F320, 0x1F321, 0x1F324, 0x1F325, 0x1F326, 0x1F327, 0x1F328, 0x1F329, 0x1F32A, 0x1F32B,
-        0x1F32C, 0x1F32D, 0x1F32E, 0x1F32F, 0x1F330, 0x1F331, 0x1F332, 0x1F333, 0x1F334, 0x1F335,
-        0x1F336, 0x1F337, 0x1F338, 0x1F339, 0x1F33A, 0x1F33B, 0x1F33C, 0x1F33D, 0x1F33E, 0x1F33F,
-        0x1F340, 0x1F341, 0x1F342, 0x1F343, 0x1F344, 0x1F345, 0x1F346, 0x1F347, 0x1F348, 0x1F349,
-        0x1F34A, 0x1F34B, 0x1F34C, 0x1F34D, 0x1F34E, 0x1F34F, 0x1F350, 0x1F351, 0x1F352, 0x1F353,
-        0x1F354, 0x1F355, 0x1F356, 0x1F357, 0x1F358, 0x1F359, 0x1F35A, 0x1F35B, 0x1F35C, 0x1F35D,
-        0x1F35E, 0x1F35F, 0x1F360, 0x1F361, 0x1F362, 0x1F363, 0x1F364, 0x1F365, 0x1F366, 0x1F367,
-        0x1F368, 0x1F369, 0x1F36A, 0x1F36B, 0x1F36C, 0x1F36D, 0x1F36E, 0x1F36F, 0x1F370, 0x1F371,
-        0x1F372, 0x1F373, 0x1F374, 0x1F375, 0x1F376, 0x1F377, 0x1F378, 0x1F379, 0x1F37A, 0x1F37B,
-        0x1F37C, 0x1F37D, 0x1F37E, 0x1F37F, 0x1F380, 0x1F381, 0x1F382, 0x1F383, 0x1F384, 0x1F385,
-        0x1F386, 0x1F387, 0x1F388, 0x1F389, 0x1F38A, 0x1F38B, 0x1F38C, 0x1F38D, 0x1F38E, 0x1F38F,
-        0x1F390, 0x1F391, 0x1F392, 0x1F393, 0x1F396, 0x1F397, 0x1F399, 0x1F39A, 0x1F39B, 0x1F39E,
-        0x1F39F, 0x1F3A0, 0x1F3A1, 0x1F3A2, 0x1F3A3, 0x1F3A4, 0x1F3A5, 0x1F3A6, 0x1F3A7, 0x1F3A8,
-        0x1F3A9, 0x1F3AA, 0x1F3AB, 0x1F3AC, 0x1F3AD, 0x1F3AE, 0x1F3AF, 0x1F3B0, 0x1F3B1, 0x1F3B2,
-        0x1F3B3, 0x1F3B4, 0x1F3B5, 0x1F3B6, 0x1F3B7, 0x1F3B8, 0x1F3B9, 0x1F3BA, 0x1F3BB, 0x1F3BC,
-        0x1F3BD, 0x1F3BE, 0x1F3BF, 0x1F3C0, 0x1F3C1, 0x1F3C2, 0x1F3C3, 0x1F3C4, 0x1F3C5, 0x1F3C6,
-        0x1F3C7, 0x1F3C8, 0x1F3C9, 0x1F3CA, 0x1F3CB, 0x1F3CC, 0x1F3CD, 0x1F3CE, 0x1F3CF, 0x1F3D0,
-        0x1F3D1, 0x1F3D2, 0x1F3D3, 0x1F3D4, 0x1F3D5, 0x1F3D6, 0x1F3D7, 0x1F3D8, 0x1F3D9, 0x1F3DA,
-        0x1F3DB, 0x1F3DC, 0x1F3DD, 0x1F3DE, 0x1F3DF, 0x1F3E0, 0x1F3E1, 0x1F3E2, 0x1F3E3, 0x1F3E4,
-        0x1F3E5, 0x1F3E6, 0x1F3E7, 0x1F3E8, 0x1F3E9, 0x1F3EA, 0x1F3EB, 0x1F3EC, 0x1F3ED, 0x1F3EE,
-        0x1F3EF, 0x1F3F0, 0x1F3F3, 0x1F3F4, 0x1F3F5, 0x1F3F7, 0x1F3F8, 0x1F3F9, 0x1F3FA, 0x1F3FB,
-        0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF, 0x1F400, 0x1F401, 0x1F402, 0x1F403, 0x1F404, 0x1F405,
-        0x1F406, 0x1F407, 0x1F408, 0x1F409, 0x1F40A, 0x1F40B, 0x1F40C, 0x1F40D, 0x1F40E, 0x1F40F,
-        0x1F410, 0x1F411, 0x1F412, 0x1F413, 0x1F414, 0x1F415, 0x1F416, 0x1F417, 0x1F418, 0x1F419,
-        0x1F41A, 0x1F41B, 0x1F41C, 0x1F41D, 0x1F41E, 0x1F41F, 0x1F420, 0x1F421, 0x1F422, 0x1F423,
-        0x1F424, 0x1F425, 0x1F426, 0x1F427, 0x1F428, 0x1F429, 0x1F42A, 0x1F42B, 0x1F42C, 0x1F42D,
-        0x1F42E, 0x1F42F, 0x1F430, 0x1F431, 0x1F432, 0x1F433, 0x1F434, 0x1F435, 0x1F436, 0x1F437,
-        0x1F438, 0x1F439, 0x1F43A, 0x1F43B, 0x1F43C, 0x1F43D, 0x1F43E, 0x1F43F, 0x1F440, 0x1F441,
-        0x1F442, 0x1F443, 0x1F444, 0x1F445, 0x1F446, 0x1F447, 0x1F448, 0x1F449, 0x1F44A, 0x1F44B,
-        0x1F44C, 0x1F44D, 0x1F44E, 0x1F44F, 0x1F450, 0x1F451, 0x1F452, 0x1F453, 0x1F454, 0x1F455,
-        0x1F456, 0x1F457, 0x1F458, 0x1F459, 0x1F45A, 0x1F45B, 0x1F45C, 0x1F45D, 0x1F45E, 0x1F45F,
-        0x1F460, 0x1F461, 0x1F462, 0x1F463, 0x1F464, 0x1F465, 0x1F466, 0x1F467, 0x1F468, 0x1F469,
-        0x1F46A, 0x1F46B, 0x1F46C, 0x1F46D, 0x1F46E, 0x1F46F, 0x1F470, 0x1F471, 0x1F472, 0x1F473,
-        0x1F474, 0x1F475, 0x1F476, 0x1F477, 0x1F478, 0x1F479, 0x1F47A, 0x1F47B, 0x1F47C, 0x1F47D,
-        0x1F47E, 0x1F47F, 0x1F480, 0x1F481, 0x1F482, 0x1F483, 0x1F484, 0x1F485, 0x1F486, 0x1F487,
-        0x1F488, 0x1F489, 0x1F48A, 0x1F48B, 0x1F48C, 0x1F48D, 0x1F48E, 0x1F48F, 0x1F490, 0x1F491,
-        0x1F492, 0x1F493, 0x1F494, 0x1F495, 0x1F496, 0x1F497, 0x1F498, 0x1F499, 0x1F49A, 0x1F49B,
-        0x1F49C, 0x1F49D, 0x1F49E, 0x1F49F, 0x1F4A0, 0x1F4A1, 0x1F4A2, 0x1F4A3, 0x1F4A4, 0x1F4A5,
-        0x1F4A6, 0x1F4A7, 0x1F4A8, 0x1F4A9, 0x1F4AA, 0x1F4AB, 0x1F4AC, 0x1F4AD, 0x1F4AE, 0x1F4AF,
-        0x1F4B0, 0x1F4B1, 0x1F4B2, 0x1F4B3, 0x1F4B4, 0x1F4B5, 0x1F4B6, 0x1F4B7, 0x1F4B8, 0x1F4B9,
-        0x1F4BA, 0x1F4BB, 0x1F4BC, 0x1F4BD, 0x1F4BE, 0x1F4BF, 0x1F4C0, 0x1F4C1, 0x1F4C2, 0x1F4C3,
-        0x1F4C4, 0x1F4C5, 0x1F4C6, 0x1F4C7, 0x1F4C8, 0x1F4C9, 0x1F4CA, 0x1F4CB, 0x1F4CC, 0x1F4CD,
-        0x1F4CE, 0x1F4CF, 0x1F4D0, 0x1F4D1, 0x1F4D2, 0x1F4D3, 0x1F4D4, 0x1F4D5, 0x1F4D6, 0x1F4D7,
-        0x1F4D8, 0x1F4D9, 0x1F4DA, 0x1F4DB, 0x1F4DC, 0x1F4DD, 0x1F4DE, 0x1F4DF, 0x1F4E0, 0x1F4E1,
-        0x1F4E2, 0x1F4E3, 0x1F4E4, 0x1F4E5, 0x1F4E6, 0x1F4E7, 0x1F4E8, 0x1F4E9, 0x1F4EA, 0x1F4EB,
-        0x1F4EC, 0x1F4ED, 0x1F4EE, 0x1F4EF, 0x1F4F0, 0x1F4F1, 0x1F4F2, 0x1F4F3, 0x1F4F4, 0x1F4F5,
-        0x1F4F6, 0x1F4F7, 0x1F4F8, 0x1F4F9, 0x1F4FA, 0x1F4FB, 0x1F4FC, 0x1F4FD, 0x1F4FF, 0x1F500,
-        0x1F501, 0x1F502, 0x1F503, 0x1F504, 0x1F505, 0x1F506, 0x1F507, 0x1F508, 0x1F509, 0x1F50A,
-        0x1F50B, 0x1F50C, 0x1F50D, 0x1F50E, 0x1F50F, 0x1F510, 0x1F511, 0x1F512, 0x1F513, 0x1F514,
-        0x1F515, 0x1F516, 0x1F517, 0x1F518, 0x1F519, 0x1F51A, 0x1F51B, 0x1F51C, 0x1F51D, 0x1F51E,
-        0x1F51F, 0x1F520, 0x1F521, 0x1F522, 0x1F523, 0x1F524, 0x1F525, 0x1F526, 0x1F527, 0x1F528,
-        0x1F529, 0x1F52A, 0x1F52B, 0x1F52C, 0x1F52D, 0x1F52E, 0x1F52F, 0x1F530, 0x1F531, 0x1F532,
-        0x1F533, 0x1F534, 0x1F535, 0x1F536, 0x1F537, 0x1F538, 0x1F539, 0x1F53A, 0x1F53B, 0x1F53C,
-        0x1F53D, 0x1F549, 0x1F54A, 0x1F54B, 0x1F54C, 0x1F54D, 0x1F54E, 0x1F550, 0x1F551, 0x1F552,
-        0x1F553, 0x1F554, 0x1F555, 0x1F556, 0x1F557, 0x1F558, 0x1F559, 0x1F55A, 0x1F55B, 0x1F55C,
-        0x1F55D, 0x1F55E, 0x1F55F, 0x1F560, 0x1F561, 0x1F562, 0x1F563, 0x1F564, 0x1F565, 0x1F566,
-        0x1F567, 0x1F56F, 0x1F570, 0x1F573, 0x1F574, 0x1F575, 0x1F576, 0x1F577, 0x1F578, 0x1F579,
-        0x1F57A, 0x1F587, 0x1F58A, 0x1F58B, 0x1F58C, 0x1F58D, 0x1F590, 0x1F595, 0x1F596, 0x1F5A4,
-        0x1F5A5, 0x1F5A8, 0x1F5B1, 0x1F5B2, 0x1F5BC, 0x1F5C2, 0x1F5C3, 0x1F5C4, 0x1F5D1, 0x1F5D2,
-        0x1F5D3, 0x1F5DC, 0x1F5DD, 0x1F5DE, 0x1F5E1, 0x1F5E3, 0x1F5E8, 0x1F5EF, 0x1F5F3, 0x1F5FA,
-        0x1F5FB, 0x1F5FC, 0x1F5FD, 0x1F5FE, 0x1F5FF, 0x1F600, 0x1F601, 0x1F602, 0x1F603, 0x1F604,
-        0x1F605, 0x1F606, 0x1F607, 0x1F608, 0x1F609, 0x1F60A, 0x1F60B, 0x1F60C, 0x1F60D, 0x1F60E,
-        0x1F60F, 0x1F610, 0x1F611, 0x1F612, 0x1F613, 0x1F614, 0x1F615, 0x1F616, 0x1F617, 0x1F618,
-        0x1F619, 0x1F61A, 0x1F61B, 0x1F61C, 0x1F61D, 0x1F61E, 0x1F61F, 0x1F620, 0x1F621, 0x1F622,
-        0x1F623, 0x1F624, 0x1F625, 0x1F626, 0x1F627, 0x1F628, 0x1F629, 0x1F62A, 0x1F62B, 0x1F62C,
-        0x1F62D, 0x1F62E, 0x1F62F, 0x1F630, 0x1F631, 0x1F632, 0x1F633, 0x1F634, 0x1F635, 0x1F636,
-        0x1F637, 0x1F638, 0x1F639, 0x1F63A, 0x1F63B, 0x1F63C, 0x1F63D, 0x1F63E, 0x1F63F, 0x1F640,
-        0x1F641, 0x1F642, 0x1F643, 0x1F644, 0x1F645, 0x1F646, 0x1F647, 0x1F648, 0x1F649, 0x1F64A,
-        0x1F64B, 0x1F64C, 0x1F64D, 0x1F64E, 0x1F64F, 0x1F680, 0x1F681, 0x1F682, 0x1F683, 0x1F684,
-        0x1F685, 0x1F686, 0x1F687, 0x1F688, 0x1F689, 0x1F68A, 0x1F68B, 0x1F68C, 0x1F68D, 0x1F68E,
-        0x1F68F, 0x1F690, 0x1F691, 0x1F692, 0x1F693, 0x1F694, 0x1F695, 0x1F696, 0x1F697, 0x1F698,
-        0x1F699, 0x1F69A, 0x1F69B, 0x1F69C, 0x1F69D, 0x1F69E, 0x1F69F, 0x1F6A0, 0x1F6A1, 0x1F6A2,
-        0x1F6A3, 0x1F6A4, 0x1F6A5, 0x1F6A6, 0x1F6A7, 0x1F6A8, 0x1F6A9, 0x1F6AA, 0x1F6AB, 0x1F6AC,
-        0x1F6AD, 0x1F6AE, 0x1F6AF, 0x1F6B0, 0x1F6B1, 0x1F6B2, 0x1F6B3, 0x1F6B4, 0x1F6B5, 0x1F6B6,
-        0x1F6B7, 0x1F6B8, 0x1F6B9, 0x1F6BA, 0x1F6BB, 0x1F6BC, 0x1F6BD, 0x1F6BE, 0x1F6BF, 0x1F6C0,
-        0x1F6C1, 0x1F6C2, 0x1F6C3, 0x1F6C4, 0x1F6C5, 0x1F6CB, 0x1F6CC, 0x1F6CD, 0x1F6CE, 0x1F6CF,
-        0x1F6D0, 0x1F6D1, 0x1F6D2, 0x1F6E0, 0x1F6E1, 0x1F6E2, 0x1F6E3, 0x1F6E4, 0x1F6E5, 0x1F6E9,
-        0x1F6EB, 0x1F6EC, 0x1F6F0, 0x1F6F3, 0x1F6F4, 0x1F6F5, 0x1F6F6, 0x1F910, 0x1F911, 0x1F912,
-        0x1F913, 0x1F914, 0x1F915, 0x1F916, 0x1F917, 0x1F918, 0x1F919, 0x1F91A, 0x1F91B, 0x1F91C,
-        0x1F91D, 0x1F91E, 0x1F920, 0x1F921, 0x1F922, 0x1F923, 0x1F924, 0x1F925, 0x1F926, 0x1F927,
-        0x1F930, 0x1F933, 0x1F934, 0x1F935, 0x1F936, 0x1F937, 0x1F938, 0x1F939, 0x1F93A, 0x1F93B,
-        0x1F93C, 0x1F93D, 0x1F93E, 0x1F940, 0x1F941, 0x1F942, 0x1F943, 0x1F944, 0x1F945, 0x1F946,
-        0x1F947, 0x1F948, 0x1F949, 0x1F94A, 0x1F94B, 0x1F950, 0x1F951, 0x1F952, 0x1F953, 0x1F954,
-        0x1F955, 0x1F956, 0x1F957, 0x1F958, 0x1F959, 0x1F95A, 0x1F95B, 0x1F95C, 0x1F95D, 0x1F95E,
-        0x1F980, 0x1F981, 0x1F982, 0x1F983, 0x1F984, 0x1F985, 0x1F986, 0x1F987, 0x1F988, 0x1F989,
-        0x1F98A, 0x1F98B, 0x1F98C, 0x1F98D, 0x1F98E, 0x1F98F, 0x1F990, 0x1F991, 0x1F9C0
+        0x2623, 0x2626, 0x262A, 0x262E, 0x262F, 0x2638, 0x2639, 0x263A, 0x2640, 0x2642, 0x2648,
+        0x2649, 0x264A, 0x264B, 0x264C, 0x264D, 0x264E, 0x264F, 0x2650, 0x2651, 0x2652, 0x2653,
+        0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267B, 0x267F, 0x2692, 0x2693, 0x2694, 0x2695,
+        0x2696, 0x2697, 0x2699, 0x269B, 0x269C, 0x26A0, 0x26A1, 0x26AA, 0x26AB, 0x26B0, 0x26B1,
+        0x26BD, 0x26BE, 0x26C4, 0x26C5, 0x26C8, 0x26CE, 0x26CF, 0x26D1, 0x26D3, 0x26D4, 0x26E9,
+        0x26EA, 0x26F0, 0x26F1, 0x26F2, 0x26F3, 0x26F4, 0x26F5, 0x26F7, 0x26F8, 0x26F9, 0x26FA,
+        0x26FD, 0x2702, 0x2705, 0x2708, 0x2709, 0x270A, 0x270B, 0x270C, 0x270D, 0x270F, 0x2712,
+        0x2714, 0x2716, 0x271D, 0x2721, 0x2728, 0x2733, 0x2734, 0x2744, 0x2747, 0x274C, 0x274E,
+        0x2753, 0x2754, 0x2755, 0x2757, 0x2763, 0x2764, 0x2795, 0x2796, 0x2797, 0x27A1, 0x27B0,
+        0x27BF, 0x2934, 0x2935, 0x2B05, 0x2B06, 0x2B07, 0x2B1B, 0x2B1C, 0x2B50, 0x2B55, 0x3030,
+        0x303D, 0x3297, 0x3299, 0x1F004, 0x1F0CF, 0x1F170, 0x1F171, 0x1F17E, 0x1F17F, 0x1F18E,
+        0x1F191, 0x1F192, 0x1F193, 0x1F194, 0x1F195, 0x1F196, 0x1F197, 0x1F198, 0x1F199, 0x1F19A,
+        0x1F1E6, 0x1F1E7, 0x1F1E8, 0x1F1E9, 0x1F1EA, 0x1F1EB, 0x1F1EC, 0x1F1ED, 0x1F1EE, 0x1F1EF,
+        0x1F1F0, 0x1F1F1, 0x1F1F2, 0x1F1F3, 0x1F1F4, 0x1F1F5, 0x1F1F6, 0x1F1F7, 0x1F1F8, 0x1F1F9,
+        0x1F1FA, 0x1F1FB, 0x1F1FC, 0x1F1FD, 0x1F1FE, 0x1F1FF, 0x1F201, 0x1F202, 0x1F21A, 0x1F22F,
+        0x1F232, 0x1F233, 0x1F234, 0x1F235, 0x1F236, 0x1F237, 0x1F238, 0x1F239, 0x1F23A, 0x1F250,
+        0x1F251, 0x1F300, 0x1F301, 0x1F302, 0x1F303, 0x1F304, 0x1F305, 0x1F306, 0x1F307, 0x1F308,
+        0x1F309, 0x1F30A, 0x1F30B, 0x1F30C, 0x1F30D, 0x1F30E, 0x1F30F, 0x1F310, 0x1F311, 0x1F312,
+        0x1F313, 0x1F314, 0x1F315, 0x1F316, 0x1F317, 0x1F318, 0x1F319, 0x1F31A, 0x1F31B, 0x1F31C,
+        0x1F31D, 0x1F31E, 0x1F31F, 0x1F320, 0x1F321, 0x1F324, 0x1F325, 0x1F326, 0x1F327, 0x1F328,
+        0x1F329, 0x1F32A, 0x1F32B, 0x1F32C, 0x1F32D, 0x1F32E, 0x1F32F, 0x1F330, 0x1F331, 0x1F332,
+        0x1F333, 0x1F334, 0x1F335, 0x1F336, 0x1F337, 0x1F338, 0x1F339, 0x1F33A, 0x1F33B, 0x1F33C,
+        0x1F33D, 0x1F33E, 0x1F33F, 0x1F340, 0x1F341, 0x1F342, 0x1F343, 0x1F344, 0x1F345, 0x1F346,
+        0x1F347, 0x1F348, 0x1F349, 0x1F34A, 0x1F34B, 0x1F34C, 0x1F34D, 0x1F34E, 0x1F34F, 0x1F350,
+        0x1F351, 0x1F352, 0x1F353, 0x1F354, 0x1F355, 0x1F356, 0x1F357, 0x1F358, 0x1F359, 0x1F35A,
+        0x1F35B, 0x1F35C, 0x1F35D, 0x1F35E, 0x1F35F, 0x1F360, 0x1F361, 0x1F362, 0x1F363, 0x1F364,
+        0x1F365, 0x1F366, 0x1F367, 0x1F368, 0x1F369, 0x1F36A, 0x1F36B, 0x1F36C, 0x1F36D, 0x1F36E,
+        0x1F36F, 0x1F370, 0x1F371, 0x1F372, 0x1F373, 0x1F374, 0x1F375, 0x1F376, 0x1F377, 0x1F378,
+        0x1F379, 0x1F37A, 0x1F37B, 0x1F37C, 0x1F37D, 0x1F37E, 0x1F37F, 0x1F380, 0x1F381, 0x1F382,
+        0x1F383, 0x1F384, 0x1F385, 0x1F386, 0x1F387, 0x1F388, 0x1F389, 0x1F38A, 0x1F38B, 0x1F38C,
+        0x1F38D, 0x1F38E, 0x1F38F, 0x1F390, 0x1F391, 0x1F392, 0x1F393, 0x1F396, 0x1F397, 0x1F399,
+        0x1F39A, 0x1F39B, 0x1F39E, 0x1F39F, 0x1F3A0, 0x1F3A1, 0x1F3A2, 0x1F3A3, 0x1F3A4, 0x1F3A5,
+        0x1F3A6, 0x1F3A7, 0x1F3A8, 0x1F3A9, 0x1F3AA, 0x1F3AB, 0x1F3AC, 0x1F3AD, 0x1F3AE, 0x1F3AF,
+        0x1F3B0, 0x1F3B1, 0x1F3B2, 0x1F3B3, 0x1F3B4, 0x1F3B5, 0x1F3B6, 0x1F3B7, 0x1F3B8, 0x1F3B9,
+        0x1F3BA, 0x1F3BB, 0x1F3BC, 0x1F3BD, 0x1F3BE, 0x1F3BF, 0x1F3C0, 0x1F3C1, 0x1F3C2, 0x1F3C3,
+        0x1F3C4, 0x1F3C5, 0x1F3C6, 0x1F3C7, 0x1F3C8, 0x1F3C9, 0x1F3CA, 0x1F3CB, 0x1F3CC, 0x1F3CD,
+        0x1F3CE, 0x1F3CF, 0x1F3D0, 0x1F3D1, 0x1F3D2, 0x1F3D3, 0x1F3D4, 0x1F3D5, 0x1F3D6, 0x1F3D7,
+        0x1F3D8, 0x1F3D9, 0x1F3DA, 0x1F3DB, 0x1F3DC, 0x1F3DD, 0x1F3DE, 0x1F3DF, 0x1F3E0, 0x1F3E1,
+        0x1F3E2, 0x1F3E3, 0x1F3E4, 0x1F3E5, 0x1F3E6, 0x1F3E7, 0x1F3E8, 0x1F3E9, 0x1F3EA, 0x1F3EB,
+        0x1F3EC, 0x1F3ED, 0x1F3EE, 0x1F3EF, 0x1F3F0, 0x1F3F3, 0x1F3F4, 0x1F3F5, 0x1F3F7, 0x1F3F8,
+        0x1F3F9, 0x1F3FA, 0x1F3FB, 0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF, 0x1F400, 0x1F401, 0x1F402,
+        0x1F403, 0x1F404, 0x1F405, 0x1F406, 0x1F407, 0x1F408, 0x1F409, 0x1F40A, 0x1F40B, 0x1F40C,
+        0x1F40D, 0x1F40E, 0x1F40F, 0x1F410, 0x1F411, 0x1F412, 0x1F413, 0x1F414, 0x1F415, 0x1F416,
+        0x1F417, 0x1F418, 0x1F419, 0x1F41A, 0x1F41B, 0x1F41C, 0x1F41D, 0x1F41E, 0x1F41F, 0x1F420,
+        0x1F421, 0x1F422, 0x1F423, 0x1F424, 0x1F425, 0x1F426, 0x1F427, 0x1F428, 0x1F429, 0x1F42A,
+        0x1F42B, 0x1F42C, 0x1F42D, 0x1F42E, 0x1F42F, 0x1F430, 0x1F431, 0x1F432, 0x1F433, 0x1F434,
+        0x1F435, 0x1F436, 0x1F437, 0x1F438, 0x1F439, 0x1F43A, 0x1F43B, 0x1F43C, 0x1F43D, 0x1F43E,
+        0x1F43F, 0x1F440, 0x1F441, 0x1F442, 0x1F443, 0x1F444, 0x1F445, 0x1F446, 0x1F447, 0x1F448,
+        0x1F449, 0x1F44A, 0x1F44B, 0x1F44C, 0x1F44D, 0x1F44E, 0x1F44F, 0x1F450, 0x1F451, 0x1F452,
+        0x1F453, 0x1F454, 0x1F455, 0x1F456, 0x1F457, 0x1F458, 0x1F459, 0x1F45A, 0x1F45B, 0x1F45C,
+        0x1F45D, 0x1F45E, 0x1F45F, 0x1F460, 0x1F461, 0x1F462, 0x1F463, 0x1F464, 0x1F465, 0x1F466,
+        0x1F467, 0x1F468, 0x1F469, 0x1F46A, 0x1F46B, 0x1F46C, 0x1F46D, 0x1F46E, 0x1F46F, 0x1F470,
+        0x1F471, 0x1F472, 0x1F473, 0x1F474, 0x1F475, 0x1F476, 0x1F477, 0x1F478, 0x1F479, 0x1F47A,
+        0x1F47B, 0x1F47C, 0x1F47D, 0x1F47E, 0x1F47F, 0x1F480, 0x1F481, 0x1F482, 0x1F483, 0x1F484,
+        0x1F485, 0x1F486, 0x1F487, 0x1F488, 0x1F489, 0x1F48A, 0x1F48B, 0x1F48C, 0x1F48D, 0x1F48E,
+        0x1F48F, 0x1F490, 0x1F491, 0x1F492, 0x1F493, 0x1F494, 0x1F495, 0x1F496, 0x1F497, 0x1F498,
+        0x1F499, 0x1F49A, 0x1F49B, 0x1F49C, 0x1F49D, 0x1F49E, 0x1F49F, 0x1F4A0, 0x1F4A1, 0x1F4A2,
+        0x1F4A3, 0x1F4A4, 0x1F4A5, 0x1F4A6, 0x1F4A7, 0x1F4A8, 0x1F4A9, 0x1F4AA, 0x1F4AB, 0x1F4AC,
+        0x1F4AD, 0x1F4AE, 0x1F4AF, 0x1F4B0, 0x1F4B1, 0x1F4B2, 0x1F4B3, 0x1F4B4, 0x1F4B5, 0x1F4B6,
+        0x1F4B7, 0x1F4B8, 0x1F4B9, 0x1F4BA, 0x1F4BB, 0x1F4BC, 0x1F4BD, 0x1F4BE, 0x1F4BF, 0x1F4C0,
+        0x1F4C1, 0x1F4C2, 0x1F4C3, 0x1F4C4, 0x1F4C5, 0x1F4C6, 0x1F4C7, 0x1F4C8, 0x1F4C9, 0x1F4CA,
+        0x1F4CB, 0x1F4CC, 0x1F4CD, 0x1F4CE, 0x1F4CF, 0x1F4D0, 0x1F4D1, 0x1F4D2, 0x1F4D3, 0x1F4D4,
+        0x1F4D5, 0x1F4D6, 0x1F4D7, 0x1F4D8, 0x1F4D9, 0x1F4DA, 0x1F4DB, 0x1F4DC, 0x1F4DD, 0x1F4DE,
+        0x1F4DF, 0x1F4E0, 0x1F4E1, 0x1F4E2, 0x1F4E3, 0x1F4E4, 0x1F4E5, 0x1F4E6, 0x1F4E7, 0x1F4E8,
+        0x1F4E9, 0x1F4EA, 0x1F4EB, 0x1F4EC, 0x1F4ED, 0x1F4EE, 0x1F4EF, 0x1F4F0, 0x1F4F1, 0x1F4F2,
+        0x1F4F3, 0x1F4F4, 0x1F4F5, 0x1F4F6, 0x1F4F7, 0x1F4F8, 0x1F4F9, 0x1F4FA, 0x1F4FB, 0x1F4FC,
+        0x1F4FD, 0x1F4FF, 0x1F500, 0x1F501, 0x1F502, 0x1F503, 0x1F504, 0x1F505, 0x1F506, 0x1F507,
+        0x1F508, 0x1F509, 0x1F50A, 0x1F50B, 0x1F50C, 0x1F50D, 0x1F50E, 0x1F50F, 0x1F510, 0x1F511,
+        0x1F512, 0x1F513, 0x1F514, 0x1F515, 0x1F516, 0x1F517, 0x1F518, 0x1F519, 0x1F51A, 0x1F51B,
+        0x1F51C, 0x1F51D, 0x1F51E, 0x1F51F, 0x1F520, 0x1F521, 0x1F522, 0x1F523, 0x1F524, 0x1F525,
+        0x1F526, 0x1F527, 0x1F528, 0x1F529, 0x1F52A, 0x1F52B, 0x1F52C, 0x1F52D, 0x1F52E, 0x1F52F,
+        0x1F530, 0x1F531, 0x1F532, 0x1F533, 0x1F534, 0x1F535, 0x1F536, 0x1F537, 0x1F538, 0x1F539,
+        0x1F53A, 0x1F53B, 0x1F53C, 0x1F53D, 0x1F549, 0x1F54A, 0x1F54B, 0x1F54C, 0x1F54D, 0x1F54E,
+        0x1F550, 0x1F551, 0x1F552, 0x1F553, 0x1F554, 0x1F555, 0x1F556, 0x1F557, 0x1F558, 0x1F559,
+        0x1F55A, 0x1F55B, 0x1F55C, 0x1F55D, 0x1F55E, 0x1F55F, 0x1F560, 0x1F561, 0x1F562, 0x1F563,
+        0x1F564, 0x1F565, 0x1F566, 0x1F567, 0x1F56F, 0x1F570, 0x1F573, 0x1F574, 0x1F575, 0x1F576,
+        0x1F577, 0x1F578, 0x1F579, 0x1F57A, 0x1F587, 0x1F58A, 0x1F58B, 0x1F58C, 0x1F58D, 0x1F590,
+        0x1F595, 0x1F596, 0x1F5A4, 0x1F5A5, 0x1F5A8, 0x1F5B1, 0x1F5B2, 0x1F5BC, 0x1F5C2, 0x1F5C3,
+        0x1F5C4, 0x1F5D1, 0x1F5D2, 0x1F5D3, 0x1F5DC, 0x1F5DD, 0x1F5DE, 0x1F5E1, 0x1F5E3, 0x1F5E8,
+        0x1F5EF, 0x1F5F3, 0x1F5FA, 0x1F5FB, 0x1F5FC, 0x1F5FD, 0x1F5FE, 0x1F5FF, 0x1F600, 0x1F601,
+        0x1F602, 0x1F603, 0x1F604, 0x1F605, 0x1F606, 0x1F607, 0x1F608, 0x1F609, 0x1F60A, 0x1F60B,
+        0x1F60C, 0x1F60D, 0x1F60E, 0x1F60F, 0x1F610, 0x1F611, 0x1F612, 0x1F613, 0x1F614, 0x1F615,
+        0x1F616, 0x1F617, 0x1F618, 0x1F619, 0x1F61A, 0x1F61B, 0x1F61C, 0x1F61D, 0x1F61E, 0x1F61F,
+        0x1F620, 0x1F621, 0x1F622, 0x1F623, 0x1F624, 0x1F625, 0x1F626, 0x1F627, 0x1F628, 0x1F629,
+        0x1F62A, 0x1F62B, 0x1F62C, 0x1F62D, 0x1F62E, 0x1F62F, 0x1F630, 0x1F631, 0x1F632, 0x1F633,
+        0x1F634, 0x1F635, 0x1F636, 0x1F637, 0x1F638, 0x1F639, 0x1F63A, 0x1F63B, 0x1F63C, 0x1F63D,
+        0x1F63E, 0x1F63F, 0x1F640, 0x1F641, 0x1F642, 0x1F643, 0x1F644, 0x1F645, 0x1F646, 0x1F647,
+        0x1F648, 0x1F649, 0x1F64A, 0x1F64B, 0x1F64C, 0x1F64D, 0x1F64E, 0x1F64F, 0x1F680, 0x1F681,
+        0x1F682, 0x1F683, 0x1F684, 0x1F685, 0x1F686, 0x1F687, 0x1F688, 0x1F689, 0x1F68A, 0x1F68B,
+        0x1F68C, 0x1F68D, 0x1F68E, 0x1F68F, 0x1F690, 0x1F691, 0x1F692, 0x1F693, 0x1F694, 0x1F695,
+        0x1F696, 0x1F697, 0x1F698, 0x1F699, 0x1F69A, 0x1F69B, 0x1F69C, 0x1F69D, 0x1F69E, 0x1F69F,
+        0x1F6A0, 0x1F6A1, 0x1F6A2, 0x1F6A3, 0x1F6A4, 0x1F6A5, 0x1F6A6, 0x1F6A7, 0x1F6A8, 0x1F6A9,
+        0x1F6AA, 0x1F6AB, 0x1F6AC, 0x1F6AD, 0x1F6AE, 0x1F6AF, 0x1F6B0, 0x1F6B1, 0x1F6B2, 0x1F6B3,
+        0x1F6B4, 0x1F6B5, 0x1F6B6, 0x1F6B7, 0x1F6B8, 0x1F6B9, 0x1F6BA, 0x1F6BB, 0x1F6BC, 0x1F6BD,
+        0x1F6BE, 0x1F6BF, 0x1F6C0, 0x1F6C1, 0x1F6C2, 0x1F6C3, 0x1F6C4, 0x1F6C5, 0x1F6CB, 0x1F6CC,
+        0x1F6CD, 0x1F6CE, 0x1F6CF, 0x1F6D0, 0x1F6D1, 0x1F6D2, 0x1F6E0, 0x1F6E1, 0x1F6E2, 0x1F6E3,
+        0x1F6E4, 0x1F6E5, 0x1F6E9, 0x1F6EB, 0x1F6EC, 0x1F6F0, 0x1F6F3, 0x1F6F4, 0x1F6F5, 0x1F6F6,
+        0x1F910, 0x1F911, 0x1F912, 0x1F913, 0x1F914, 0x1F915, 0x1F916, 0x1F917, 0x1F918, 0x1F919,
+        0x1F91A, 0x1F91B, 0x1F91C, 0x1F91D, 0x1F91E, 0x1F920, 0x1F921, 0x1F922, 0x1F923, 0x1F924,
+        0x1F925, 0x1F926, 0x1F927, 0x1F930, 0x1F933, 0x1F934, 0x1F935, 0x1F936, 0x1F937, 0x1F938,
+        0x1F939, 0x1F93A, 0x1F93B, 0x1F93C, 0x1F93D, 0x1F93E, 0x1F940, 0x1F941, 0x1F942, 0x1F943,
+        0x1F944, 0x1F945, 0x1F946, 0x1F947, 0x1F948, 0x1F949, 0x1F94A, 0x1F94B, 0x1F950, 0x1F951,
+        0x1F952, 0x1F953, 0x1F954, 0x1F955, 0x1F956, 0x1F957, 0x1F958, 0x1F959, 0x1F95A, 0x1F95B,
+        0x1F95C, 0x1F95D, 0x1F95E, 0x1F980, 0x1F981, 0x1F982, 0x1F983, 0x1F984, 0x1F985, 0x1F986,
+        0x1F987, 0x1F988, 0x1F989, 0x1F98A, 0x1F98B, 0x1F98C, 0x1F98D, 0x1F98E, 0x1F98F, 0x1F990,
+        0x1F991, 0x1F9C0
     };
 
     // See http://www.unicode.org/Public/emoji/3.0/emoji-data.txt
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 3770a45..2f327f3 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -129,8 +129,8 @@
         // The offset is immediately before a variation selector.
         final int STATE_BEFORE_VS = 6;
 
-        // The offset is immediately before a ZWJ emoji.
-        final int STATE_BEFORE_ZWJ_EMOJI = 7;
+        // The offset is immediately before an emoji.
+        final int STATE_BEFORE_EMOJI = 7;
         // The offset is immediately before a ZWJ that were seen before a ZWJ emoji.
         final int STATE_BEFORE_ZWJ = 8;
         // The offset is immediately before a variation selector and a ZWJ that were seen before a
@@ -169,7 +169,7 @@
                     } else if (codePoint == Emoji.COMBINING_ENCLOSING_KEYCAP) {
                         state = STATE_BEFORE_KEYCAP;
                     } else if (Emoji.isEmoji(codePoint)) {
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                     } else {
                         state = STATE_FINISHED;
                     }
@@ -232,7 +232,7 @@
                 case STATE_BEFORE_VS:
                     if (Emoji.isEmoji(codePoint)) {
                         deleteCharCount += Character.charCount(codePoint);
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                         break;
                     }
 
@@ -242,7 +242,7 @@
                     }
                     state = STATE_FINISHED;
                     break;
-                case STATE_BEFORE_ZWJ_EMOJI:
+                case STATE_BEFORE_EMOJI:
                     if (codePoint == Emoji.ZERO_WIDTH_JOINER) {
                         state = STATE_BEFORE_ZWJ;
                     } else {
@@ -252,7 +252,8 @@
                 case STATE_BEFORE_ZWJ:
                     if (Emoji.isEmoji(codePoint)) {
                         deleteCharCount += Character.charCount(codePoint) + 1;  // +1 for ZWJ.
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = Emoji.isEmojiModifier(codePoint) ?
+                                STATE_BEFORE_EMOJI_MODIFIER : STATE_BEFORE_EMOJI;
                     } else if (isVariationSelector(codePoint)) {
                         lastSeenVSCharCount = Character.charCount(codePoint);
                         state = STATE_BEFORE_VS_AND_ZWJ;
@@ -265,7 +266,7 @@
                         // +1 for ZWJ.
                         deleteCharCount += lastSeenVSCharCount + 1 + Character.charCount(codePoint);
                         lastSeenVSCharCount = 0;
-                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        state = STATE_BEFORE_EMOJI;
                     } else {
                         state = STATE_FINISHED;
                     }
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 48bcc093..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/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 898cf77..85092ad4 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -768,6 +768,21 @@
         return false;
     }
 
+    // Don't count glyphs that are the recommended "space" glyph and are zero width.
+    // This logic makes assumptions about HarfBuzz layout, but does correctly handle
+    // cases where ligatures form and zero width space glyphs are left in as
+    // placeholders.
+    static size_t countNonSpaceGlyphs(const Layout& layout) {
+        size_t count = 0;
+        static unsigned int kSpaceGlyphId = 3;
+        for (size_t i = 0; i < layout.nGlyphs(); i++) {
+            if (layout.getGlyphId(i) != kSpaceGlyphId || layout.getCharAdvance(i) != 0.0) {
+                count++;
+            }
+        }
+        return count;
+    }
+
     // Returns true if the given string is exact one pair of regional indicators.
     static bool isFlag(const jchar* str, size_t length) {
         const jchar RI_LEAD_SURROGATE = 0xD83C;
@@ -831,7 +846,7 @@
         Layout layout;
         MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(),
                 str.size());
-        size_t nGlyphs = layout.nGlyphs();
+        size_t nGlyphs = countNonSpaceGlyphs(layout);
         if (nGlyphs != 1 && nChars > 1) {
             // multiple-character input, and was not a ligature
             // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures
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-af/strings.xml b/core/res/res/values-af/strings.xml
index 6eabd52..d5c1dd8 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimeer tans berging."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android gradeer tans op"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Sommige programme sal dalk nie behoorlik werk voordat die opgradering voltooi is nie"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimeer program <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Berei tans <xliff:g id="APPNAME">%1$s</xliff:g> voor."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Begin programme."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index e3cae6a..a90d056 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ማከማቻን በማመቻቸት ላይ።"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android በማላቅ ላይ ነው"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"አንዳንድ መተግበሪያዎች ማላቁ እስኪጠናቀቅ ድረስ በአግባቡ ላይሰሩ ይችላሉ"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"መተግበሪያዎች በአግባቡ በመጠቀም ላይ <xliff:g id="NUMBER_0">%1$d</xliff:g> ከ <xliff:g id="NUMBER_1">%2$d</xliff:g> ፡፡"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ን ማዘጋጀት።"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1778e0c..10cb7c5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1116,6 +1116,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"جارٍ تحسين السعة التخزينية."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"‏جارٍ ترقية Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"قد لا تعمل بعض التطبيقات بشكل مناسب إلا بعد انتهاء الترقية"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"جارٍ تحسين التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"جارٍ تحضير <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"بدء التطبيقات."</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index a1e851b..53a238b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Yaddaş optimallaşdırılır."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android təkmilləşdirilir"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Güncəllənmə tamamlanana kimi bəzi tətbiqlər düzgün işləməyə bilər"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> əddədən <xliff:g id="NUMBER_0">%1$d</xliff:g> tətbiq optimallaşır."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> proqramının hazırlanması."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Tətbiqlər başladılır."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 17dfef1..54c4710 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хранилището се оптимизира."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android се надстройва"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Някои приложения може да не работят правилно, докато надстройването не завърши"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизира се приложение <xliff:g id="NUMBER_0">%1$d</xliff:g> от <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> се подготвя."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Приложенията се стартират."</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 8435f96..292fefd 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"সঞ্চয়স্থান অপ্টিমাইজ করা হচ্ছে৷"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android আপগ্রেড করা হচ্ছে"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"আপগ্রেড সম্পন্ন না হওয়া পর্যন্ত কিছু অ্যাপ্লিকেশান সঠিকভাবে কাজ নাও করতে পারে"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান অপ্টিমাইজ করা হচ্ছে৷"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> প্রস্তুত করা হচ্ছে৷"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 59f7d95..7890068 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"S\'està optimitzant l\'emmagatzematge."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android s\'està actualitzant"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Pot ser que algunes aplicacions no funcionin correctament fins que no es completi l\'actualització"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"S\'està optimitzant l\'aplicació <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"S\'està preparant <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"S\'estan iniciant les aplicacions."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 1eb497f..f5e74ce 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Probíhá optimalizace úložiště."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android se upgraduje"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Před dokončením upgradu nemusí některé aplikace fungovat správně"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimalizování aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Příprava aplikace <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Spouštění aplikací."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index f5b7788..446c950c 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lageret optimeres."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android opgraderes"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Nogle apps fungerer muligvis ikke korrekt, før opgraderingen er gennemført"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerer app <xliff:g id="NUMBER_0">%1$d</xliff:g> ud af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Åbner dine apps."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1345f76..25f3912 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Speicher wird optimiert"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android wird aktualisiert"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Einige Apps funktionieren unter Umständen nicht richtig, bis das Upgrade abgeschlossen ist"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> wird vorbereitet"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 8434fff..3e220da 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Βελτιστοποίηση αποθηκευτικού χώρου."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Το Android αναβαθμίζεται"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Ορισμένες εφαρμογές ενδέχεται να μην λειτουργούν σωστά μέχρι την ολοκλήρωση της αναβάθμισης"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Βελτιστοποίηση της εφαρμογής <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Προετοιμασία <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Έναρξη εφαρμογών."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 6c693bc..60e9e86 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android is upgrading"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Some apps may not work properly until the upgrade finishes"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 6c693bc..60e9e86 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android is upgrading"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Some apps may not work properly until the upgrade finishes"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 6c693bc..60e9e86 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android is upgrading"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Some apps may not work properly until the upgrade finishes"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index fcfc752..c5dc210 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android se está actualizando"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Es posible que algunas apps no funcionen correctamente hasta que termine la actualización"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando la aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 21b4af3..9e1859b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamiento."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Actualizando Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Es posible que algunas aplicaciones no funcionen correctamente hasta que finalice la actualización"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index e96c93f..aa1a252 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1024,6 +1024,7 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Salvestusruumi optimeerimine."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android viiakse üle uuemale versioonile"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Mõned rakendused ei pruugi enne uuemale versioonile ülemineku lõpetamist korralikult töötada"</string>
+    <string name="app_upgrading_toast" msgid="3008139776215597053">"Rakenduse <xliff:g id="APPLICATION">%1$s</xliff:g> versiooni uuendatakse …"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. rakenduse <xliff:g id="NUMBER_1">%2$d</xliff:g>-st optimeerimine."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> ettevalmistamine."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Rakenduste käivitamine."</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 49ee82f..70ee283 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Memoria optimizatzen."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android bertsioa berritzen ari gara"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Aplikazio batzuek agian ez dute behar bezala funtzionatuko bertsioa berritzen amaitu arte"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> aplikazio optimizatzen."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> prestatzen."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 71bdc2e..aa9c148 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -937,7 +937,7 @@
     <string name="selectAll" msgid="6876518925844129331">"انتخاب همه"</string>
     <string name="cut" msgid="3092569408438626261">"برش"</string>
     <string name="copy" msgid="2681946229533511987">"کپی"</string>
-    <string name="paste" msgid="5629880836805036433">"جای گذاری"</string>
+    <string name="paste" msgid="5629880836805036433">"جای‌گذاری"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"جای‌گذاری به عنوان متن ساده"</string>
     <string name="replace" msgid="5781686059063148930">"جایگزین شود..."</string>
     <string name="delete" msgid="6098684844021697789">"حذف"</string>
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"بهینه‌سازی فضای ذخیره‌سازی."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"‏Android درحال ارتقا است"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"تا پایان ارتقا، ممکن است برخی از برنامه‌ها به‌درستی کار نکنند."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"در حال بهینه‌سازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامه‌ها."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 62c148e..1aca741 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimoidaan tallennustilaa."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Androidia päivitetään"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Kaikki sovellukset eivät ehkä toimi oikein, ennen kuin päivitys on valmis."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimoidaan sovellusta <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Valmistellaan: <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Käynnistetään sovelluksia."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2df3680..7b194a09e 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Installation de la m. à niveau d\'Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Il se peut que certaines applications ne fonctionnent pas correctement jusqu\'à ce que la mise à niveau soit terminée"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 90def0d..ff0876e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimisation du stockage en cours…"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Mise à jour d\'Android…"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Certaines applications peuvent ne pas fonctionner correctement jusqu\'à ce que la mise à jour soit terminée."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 85be7f3..abe09de 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizando almacenamento."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Estase actualizando Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"É posible que algunhas aplicacións non funcionen correctamente ata que finalice o proceso de actualización"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicacións."</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index e611f30..1589426 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"સંગ્રહ ઓપ્ટિમાઇઝ કરી રહ્યું છે."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android અપગ્રેડ થઈ રહ્યું છે"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"અપગ્રેડ સમાપ્ત ન થાય ત્યાં સુધી કેટલીક ઍપ્લિકેશનો કદાચ યોગ્ય રીતે કામ ન કરે"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> માંથી <xliff:g id="NUMBER_0">%1$d</xliff:g> ઍપ્લિકેશન ઓપ્ટિમાઇઝ કરી રહ્યું છે."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> તૈયાર કરી રહ્યું છે."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ઍપ્લિકેશનો શરૂ કરી રહ્યાં છે."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 76bc028..7a81b47 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"मेमोरी ऑप्‍टिमाइज़ हो रही है."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android अपग्रेड हो रहा है"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"जब तक अपग्रेड पूरा नहीं हो जाता, तब तक संभव है कि कुछ ऐप्लिकेशन ठीक से कार्य ना करें"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप्स  अनुकूलित हो रहा है."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तैयार हो रहा है."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ऐप्स  प्रारंभ होने वाले हैं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 461888a..9ff8363 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1047,6 +1047,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje pohrane."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android se nadograđuje"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Neke aplikacije možda neće funkcionirati pravilno dok nadogradnja ne završi"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Pripremanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 920fc39..ce4bef5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1024,6 +1024,7 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tárhely-optimalizálás."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android frissítése folyamatban"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"A frissítés befejezéséig előfordulhat, hogy egyes alkalmazások nem megfelelően működnek."</string>
+    <string name="app_upgrading_toast" msgid="3008139776215597053">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> frissítése folyamatban van"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Alkalmazás optimalizálása: <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> előkészítése."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Kezdő alkalmazások."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 2f6efcb..76bc42e 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Պահեստի օպտիմալացում:"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android-ը նորացվում է"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Հնարավոր է՝ որոշ հավելվածներ մինչև նորացման ավարտը ճիշտ չաշխատեն"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Օպտիմալացվում է հավելված <xliff:g id="NUMBER_0">%1$d</xliff:g>-ը <xliff:g id="NUMBER_1">%2$d</xliff:g>-ից:"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը պատրաստվում է:"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Հավելվածները մեկնարկում են:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 9a6f48e..d780b8c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimalkan penyimpanan."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android sedang meningkatkan versi"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Beberapa aplikasi mungkin tidak berfungsi dengan baik jika peningkatan versi belum selesai"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimalkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Menyiapkan <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index a40db198..33b4783 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Fínstillir geymslu."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android er að uppfæra"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Hugsanlega virka sum forrit ekki fyrr en uppfærslunni lýkur"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Fínstillir forrit <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Undirbýr <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ræsir forrit."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 12e18db..d03b91d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ottimizzazione archiviazione."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Aggiornamento di Android in corso"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Alcune app potrebbero non funzionare correttamente fino al completamento dell\'upgrade"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Ottimizzazione applicazione <xliff:g id="NUMBER_0">%1$d</xliff:g> di <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> in preparazione."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Avvio applicazioni."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 6efa246..6df7a0f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"מתבצעת אופטימיזציה של האחסון."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"‏Android מבצע שדרוג"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ייתכן שאפליקציות מסוימות לא יפעלו כראוי עד סיום השדרוג"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"מבצע אופטימיזציה של אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"מכין את <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"מפעיל אפליקציות."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index ef63264..e08520e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ストレージを最適化しています。"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android のアップグレード中"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"アップグレードが完了するまで一部のアプリが正常に動作しない可能性があります"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>個中<xliff:g id="NUMBER_0">%1$d</xliff:g>個のアプリを最適化しています。"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>をペア設定しています。"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"アプリを起動しています。"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 2091e4a..9ab0f2b20 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"მეხსიერების ოპტიმიზირება."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android ახალ ვერსიაზე გადადის"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ახალ ვერსიაზე გადასვლის დასრულებამდე, ზოგიერთმა აპმა შეიძლება არასწორად იმუშაოს"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"მიმდინარეობს აპლიკაციების ოპტიმიზაცია. დასრულებულია <xliff:g id="NUMBER_0">%1$d</xliff:g>, სულ <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"ემზადება <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"აპების ჩართვა"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 174f430..49d7139 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Қойманы оңтайландыру."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android жаңартылуда"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Жаңарту аяқталғанға дейін кейбір қолданбалар дұрыс жұмыс істемеуі мүмкін"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ішінен <xliff:g id="NUMBER_0">%1$d</xliff:g> қолданба оңтайландырылуда."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> дайындалуда."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Қолданбалар іске қосылуда."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 4584d21..3ffa561 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -975,7 +975,7 @@
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"កែសម្រួល​ជាមួយ​ %1$s"</string>
     <string name="whichEditApplicationLabel" msgid="7183524181625290300">"កែសម្រួល"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"ចែករំលែក​ជាមួយ"</string>
-    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"ចែករំលែក​ជាមួយ"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"ចែករំលែក​ជាមួយ %1$s"</string>
     <string name="whichSendApplicationLabel" msgid="4579076294675975354">"ចែករំលែក"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"ផ្ញើដោយប្រើ"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"ផ្ញើដោយប្រើ %1$s"</string>
@@ -1026,6 +1026,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"កំពុងធ្វើឲ្យឧបករណ៍ផ្ទុកមានប្រសិទ្ធភាព។"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android កំពុងអាប់គ្រេត..."</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"កម្មវិធីមួយចំនួនអាចនឹងមិនដំណើរការប្រក្រតីនោះទេ រហូតដល់ការអាប់គ្រេតបញ្ចប់"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"ធ្វើ​ឲ្យ​កម្មវិធី​ប្រសើរ​ឡើង <xliff:g id="NUMBER_0">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_1">%2$d</xliff:g> ។"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"កំពុងរៀបចំ <xliff:g id="APPNAME">%1$s</xliff:g>។"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ចាប់ផ្ដើម​កម្មវិធី។"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index a6d754d..7960cba 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ಸಂಗ್ರಹಣೆಯನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android ಅಪ್‌ಗ್ರೇಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ಅಪ್‌ಗ್ರೇಡ್ ಮುಗಿಯುವ ತನಕ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡದಿರಬಹುದು"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 6d07713..2e58e82 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"저장소 최적화 중"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android 업그레이드 중"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"특정 앱은 업그레이드가 완료될 때까지 제대로 작동하지 않을 수 있습니다."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"앱 <xliff:g id="NUMBER_1">%2$d</xliff:g>개 중 <xliff:g id="NUMBER_0">%1$d</xliff:g>개 최적화 중"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> 준비 중..."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"앱을 시작하는 중입니다."</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index a024db69..5ba9427 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Сактагыч ыңгайлаштырылууда."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android жаңыртылууда"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Жаңыртуу аягына чыкмайынча айрым колдонмолор талаптагыдай иштебей калышы мүмкүн"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Колдонмолорду иштетип баштоо"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 0be6875..aa4d468 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1024,6 +1024,7 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ການ​ປັບ​ບ່ອນ​ເກັບ​ຂໍ້​ມູນ​ໃຫ້​ເໝາະ​ສົມ."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"ກຳລັງອັບເກຣດ Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ບາງແອັບອາດບໍ່ສາມາດເຮັດວຽກໄດ້ປົກກະຕິຈົນກວ່າຈະອັບເກຣດສຳເລັດ"</string>
+    <string name="app_upgrading_toast" msgid="3008139776215597053">"ກຳລັງອັບເກຣດ<xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"ກຳລັງ​ປັບປຸງ​ປະສິດທິພາບ​ແອັບຯ​ທີ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຈາກ​ທັງ​ໝົດ <xliff:g id="NUMBER_1">%2$d</xliff:g> ແອັບຯ."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"ກຳ​ລັງ​ກຽມ <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ກຳລັງເປີດແອັບຯ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f4da72e..c8e3532 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimizuojama saugykla."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"„Android“ naujovinama"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Kai kurios programos gali tinkamai neveikti, kol naujovinimo procesas nebus baigtas"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizuojama <xliff:g id="NUMBER_0">%1$d</xliff:g> progr. iš <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Ruošiama „<xliff:g id="APPNAME">%1$s</xliff:g>“."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Paleidžiamos programos."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index dba8beb..e482618 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1047,6 +1047,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Notiek krātuves optimizēšana."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Notiek Android jaunināšana..."</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Kamēr jaunināšana nebūs pabeigta, dažas lietotnes, iespējams, nedarbosies pareizi."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Tiek optimizēta <xliff:g id="NUMBER_0">%1$d</xliff:g>. lietotne no <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Notiek lietotnes <xliff:g id="APPNAME">%1$s</xliff:g> sagatavošana."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Notiek lietotņu palaišana."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index a6a7793..4ebd66b 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизирање на складирањето."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android се ажурира"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Некои апликации може да не работат правилно додека не се заврши надградбата"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Се оптимизира апликација <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Се подготвува <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Се стартуваат апликациите."</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 284db98..ac9018cf 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"സ്റ്റോറേജ്  ഒപ്‌റ്റിമൈസ് ചെയ്യുന്നു."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android അപ്ഗ്രേഡുചെയ്യുന്നു"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"അപ്‌ഗ്രേഡ് പൂർത്തിയാകുന്നത് വരെ ചില ആപ്‌സ് ശരിയായി പ്രവർത്തിച്ചേക്കില്ല"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> അപ്ലിക്കേഷൻ ഓപ്റ്റിമൈസ് ചെയ്യുന്നു."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> തയ്യാറാക്കുന്നു."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 8160813..0b55a7a 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Хадгалалтыг сайжруулж байна."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Андройдыг дэвшүүлж байна"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Шинэчилж дуустал зарим апп хэвийн бус ажиллаж болзошгүй"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>-н <xliff:g id="NUMBER_0">%1$d</xliff:g> апп-г тохируулж байна."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Бэлдэж байна <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Апп-г эхлүүлж байна."</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 7d0fa6d..a1269e1 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"संचयन ऑप्टिमाइझ करत आहे."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android श्रेणीसुधारित होत आहे"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"श्रेणीसुधारणा पूर्ण होईपर्यंत काही अॅप्स योग्यरित्या कार्य करणार नाहीत"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अॅप ऑप्टिमाइझ करत आहे."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तयार करीत आहे."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index b66ea933..3f9e156 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Mengoptimumkan storan."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android sedang ditingkatkan"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Sesetengah apl mungkin tidak berfungsi dengan betul sehingga peningkatan selesai"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Menyediakan <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index e9264af..d7d5902 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"သိုလှောင်မှုအား ပြုပြင်ခြင်း။"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android ကိုအဆင့်မြှင့်တင်နေပါသည်"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"အဆင့်မြှင့်တင်ခြင်း မပြီးဆုံးသေးသ၍ အချို့အက်ပ်များကို ကောင်းမွန်စွာအသုံးပြုနိုင်ဦးမည် မဟုတ်ပါ"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> ထဲက အက်ပ်<xliff:g id="NUMBER_1">%2$d</xliff:g>ကို ဆီလျော်အောင် လုပ်နေ"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> အားပြင်ဆင်နေသည်။"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"အက်ပ်များကို စတင်နေ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 381fc1f..d2e4d71 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimaliser lagring."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android oppgraderes"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Noen apper fungerer kanskje ikke skikkelig før oppgraderingen er fullført"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimaliserer app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starter apper."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 8f382968..b3de0aa 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1030,6 +1030,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"भण्डारण अनुकूलन गर्दै।"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android को स्तरवृद्धि हुँदैछ"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"स्तरवृद्धि सम्पन्न नभएसम्म केही अनुप्रयोगहरू राम्ररी काम नगर्न सक्छन्"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"अनुप्रयोग अनुकुल हुँदै <xliff:g id="NUMBER_0">%1$d</xliff:g> को <xliff:g id="NUMBER_1">%2$d</xliff:g>।"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तयारी गर्दै।"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"सुरुवात अनुप्रयोगहरू।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index d43d6c6..f23d046 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Opslagruimte wordt geoptimaliseerd."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android wordt geüpgraded"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Sommige apps werken mogelijk pas correct nadat de upgrade is voltooid"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> voorbereiden."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps starten."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index bea0682..d96b89e 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ਸਟੋਰੇਜ ਅਨੁਕੂਲ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android ਅੱਪਗ੍ਰੇਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਐਪਾਂ ਅੱਪਗ੍ਰੇਡ ਦੇ ਪੂਰੀ ਹੋਣ ਤੱਕ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰਨ"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> <xliff:g id="NUMBER_1">%2$d</xliff:g> ਦਾ ਐਪ ਅਨੁਕੂਲ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ਐਪਸ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index cff4fe40..dcbf9d0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optymalizacja pamięci."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android jest uaktualniany"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Niektóre aplikacje mogą nie działać prawidłowo, dopóki nie zakończy się aktualizacja."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optymalizowanie aplikacji <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Przygotowuję aplikację <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uruchamianie aplikacji."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f5b2389..6998871 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"O Android está sendo atualizado"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Alguns apps podem não funcionar corretamente até que a atualização seja concluída"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3079a61..1e96a4d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"A otimizar o armazenamento."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"O Android está a ser atualizado"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Algumas aplicações podem não funcionar corretamente enquanto a atualização não for concluída"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"A otimizar a aplicação <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"A preparar o <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"A iniciar aplicações"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f5b2389..6998871 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"O Android está sendo atualizado"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Alguns apps podem não funcionar corretamente até que a atualização seja concluída"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 0cb12af..0058858 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1047,6 +1047,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Se optimizează stocarea."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android face upgrade"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Este posibil ca unele aplicații să nu funcționeze corespunzător până când nu se finalizează upgrade-ul"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Se optimizează aplicația <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Se pregătește <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Se pornesc aplicațiile."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index abd9012..e202854 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1020,7 +1020,7 @@
     <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Изменить"</string>
     <string name="whichSendApplication" msgid="6902512414057341668">"Поделиться с помощью:"</string>
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Поделиться через %1$s"</string>
-    <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Открыть доступ"</string>
+    <string name="whichSendApplicationLabel" msgid="4579076294675975354">"Поделиться"</string>
     <string name="whichSendToApplication" msgid="8272422260066642057">"Выберите приложение"</string>
     <string name="whichSendToApplicationNamed" msgid="7768387871529295325">"Отправка с помощью %1$s"</string>
     <string name="whichSendToApplicationLabel" msgid="8878962419005813500">"Отправить"</string>
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимизация хранилища…"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Обновление Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Во время обновления возможны неполадки в работе приложений."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизация приложения <xliff:g id="NUMBER_0">%1$d</xliff:g> из <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Подготовка приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"..."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск приложений."</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index c64d1ed..9240212 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1026,6 +1026,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"ආචයනය ප්‍රශස්තිකරණය කිරීම."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android උත්ශ්‍රේණි කරමින්"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"උත්ශ්‍රේණි කිරීම අවසන් වන තෙක් සමහර යෙදුම් නිසි ලෙස ක්‍රියා නොකළ හැකිය"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> කින් <xliff:g id="NUMBER_0">%1$d</xliff:g> වැනි යෙදුම ප්‍රශස්ත කරමින්."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> සූදානම් කරමින්."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"යෙදුම් ආරම්භ කරමින්."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 97180db..e077075 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimalizuje sa úložisko"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Prebieha inovácia systému Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Niektoré aplikácie môžu správne fungovať až po dokončení inovácie"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Prebieha optimalizácia aplikácie <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Pripravuje sa aplikácia <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Prebieha spúšťanie aplikácií."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 9653ff8..e1eea81 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje shrambe."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Poteka nadgradnja Androida."</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Nekatere aplikacije morda ne bodo delovale pravilno, dokler ne bo dokončana nadgradnja."</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Pripravljanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Zagon aplikacij."</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index d9b14dc..5ad7ba4 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Po përshtat ruajtjen."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android po përmirësohet"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Disa aplikacione mund të mos funksionojnë si duhet deri sa të përfundojë përmirësimi"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Po përshtat aplikacionin <xliff:g id="NUMBER_0">%1$d</xliff:g> nga gjithsej <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Po përgatit <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikacionet e fillimit."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index b3fc8ca..7bfc3dd 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1047,6 +1047,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Меморија се оптимизује."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android се надограђује…"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Неке апликације можда неће исправно функционисати док се надоградња не доврши"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Припрема се <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Покретање апликација."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 8557f28..8673360 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Lagringsutrymmet optimeras."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android uppgraderas"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"En del appar kanske inte fungerar som de ska innan uppgraderingen har slutförts"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimerar app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> förbereds."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Appar startas."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 30f22ff..71d9bf7 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1022,6 +1022,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Inaboresha hifadhi."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Tunasasisha Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Huenda baadhi ya programu zisifanye kazi vizuri hadi itakapomaliza kusasisha"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Inaboresha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> kutoka <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Inaandaa <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index f606000..823286c 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"சேமிப்பகத்தை உகந்ததாக்குகிறது."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android மேம்படுத்தப்படுகிறது"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"மேம்படுத்துவது முடியும் வரை, சில பயன்பாடுகள் சரியாக வேலைசெய்யாமல் போகக்கூடும்"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> பயன்பாட்டை ஒருங்கிணைக்கிறது."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ஐத் தயார்செய்கிறது."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 56c2eac..6218cdf 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"నిల్వను అనుకూలపరుస్తోంది."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android అప్‌గ్రేడ్ అవుతోంది"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"అప్‌గ్రేడ్ పూర్తయ్యే వరకు కొన్ని అనువర్తనాలు సరిగ్గా పని చేయకపోవచ్చు"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> అనువర్తనాన్ని అనుకూలీకరిస్తోంది."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ని సిద్ధం చేస్తోంది."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"అనువర్తనాలను ప్రారంభిస్తోంది."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b64eb8f..2dfd2e7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"กำลังเพิ่มประสิทธิภาพพื้นที่จัดเก็บข้อมูล"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android กำลังอัปเกรด"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"แอปบางแอปอาจทำงานไม่ถูกต้องจนกว่าจะอัปเกรดเสร็จ"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"กำลังเพิ่มประสิทธิภาพแอปพลิเคชัน <xliff:g id="NUMBER_0">%1$d</xliff:g> จาก <xliff:g id="NUMBER_1">%2$d</xliff:g> รายการ"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"กำลังเตรียม <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 7c91c68..8553992 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ino-optimize ang storage."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Nag-a-upgrade ang Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Maaaring hindi gumana nang maayos ang ilang app hangga\'t hindi pa natatapos ang pag-upgrade"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Ino-optimize ang app <xliff:g id="NUMBER_0">%1$d</xliff:g> ng <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Ihinahanda ang <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Sinisimulan ang apps."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 805f1d2..1033e11 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Depolama optimize ediliyor."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android yeni sürüme geçiriliyor"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Yeni sürüme geçiş işlemi tamamlanana kadar bazı uygulamalar düzgün çalışmayabilir"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> uygulama optimize ediliyor."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> hazırlanıyor."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Uygulamalar başlatılıyor"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6694981..21c1e3f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1070,6 +1070,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Оптимізація пам’яті."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android оновлюється"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Деякі додатки можуть не працювати належним чином, доки не завершиться оновлення"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Оптимізація програми <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Підготовка додатка <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск програм."</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 651d9ea..ff99fb0 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"اسٹوریج کو بہترین بنایا جا رہا ہے۔"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"‏Android اپ گریڈ ہو رہا ہے"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"اپ گریڈ ختم ہونے تک شاید کچھ ایپس ٹھیک طرح سے کام نہ کریں"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"ایپ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g> کو بہتر بنایا جا رہا ہے۔"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> تیار ہو رہی ہے۔"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ایپس شروع ہو رہی ہیں۔"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 03d16b7..194b506 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Xotira optimallashtirilmoqda."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android yangilanmoqda"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Yangilanish vaqtida ba’zi ilovalar to‘g‘ri ishlamasligi mumkin"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Ilovalar optimallashtirilmoqda (<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>)."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> tayyorlanmoqda."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Ilovalar ishga tushirilmoqda."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a302ae4..4ce86cf 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Tối ưu hóa lưu trữ."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android đang nâng cấp"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Một số ứng dụng có thể không hoạt động bình thường cho đến khi nâng cấp xong"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Đang tối ưu hóa ứng dụng <xliff:g id="NUMBER_0">%1$d</xliff:g> trong tổng số <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Đang chuẩn bị <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Khởi động ứng dụng."</string>
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-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b5b87c7..3b2abe7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在优化存储空间。"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"Android 正在升级"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"在升级完成之前,部分应用可能无法正常运行"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"正在优化第<xliff:g id="NUMBER_0">%1$d</xliff:g>个应用(共<xliff:g id="NUMBER_1">%2$d</xliff:g>个)。"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"正在准备升级<xliff:g id="APPNAME">%1$s</xliff:g>。"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index d912ce5..5aa4648 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在優化儲存空間。"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"正在升級 Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"部分應用程式需要完成升級方可正常運作"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"正在優化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"正在準備 <xliff:g id="APPNAME">%1$s</xliff:g>。"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 3c6c2b3..cd3ee3a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"正在對儲存空間進行最佳化處理。"</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"正在升級 Android"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"升級完成前,部分應用程式可能無法正常運作"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"正在最佳化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"正在準備升級「<xliff:g id="APPNAME">%1$s</xliff:g>」。"</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在啟動應用程式。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e29b05f..b00b745 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1024,6 +1024,8 @@
     <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Ikhulisa isitoreji."</string>
     <string name="android_upgrading_notification_title" msgid="1619393112444671028">"I-Android iyathuthukiswa"</string>
     <string name="android_upgrading_notification_body" msgid="5761201379457064286">"Ezinye izinhlelo zokusebenza kungenzeka zingasebenzi kahle kuze kuqedwe ukuthuthukiswa"</string>
+    <!-- no translation found for app_upgrading_toast (3008139776215597053) -->
+    <skip />
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> uhlelo lokusebenza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"Ukulungisela i-<xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinhlelo zokusebenza."</string>
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/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index a9fa4dd..fd686b9 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -170,10 +170,27 @@
         backspace(state, 0);
         state.assertEquals("|");
 
+        state.setByString("U+1F469 U+200D U+1F373 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F487 U+200D U+2640 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F487 U+200D U+2640 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
         state.setByString("U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 |");
         backspace(state, 0);
         state.assertEquals("|");
 
+        // Emoji modifier can be appended to the first emoji.
+        state.setByString("U+1F469 U+1F3FB U+200D U+1F4BC |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
         // End with ZERO WIDTH JOINER
         state.setByString("U+1F441 U+200D |");
         backspace(state, 0);
@@ -445,13 +462,6 @@
         backspace(state, 0);
         state.assertEquals("|");
 
-        // Emoji modifier + ZERO WIDTH JOINER
-        state.setByString("U+1F466 U+1F3FB U+200D U+1F469 |");
-        backspace(state, 0);
-        state.assertEquals("U+1F466 |");
-        backspace(state, 0);
-        state.assertEquals("|");
-
         // Regional indicator symbol + Emoji modifier
         state.setByString("U+1F1FA U+1F3FB |");
         backspace(state, 0);
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index d4732f8..4a9cab6 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -361,6 +361,8 @@
   to: /about/dashboards/index.html
 - from: /resources/community-groups.html
   to: /support.html
+- from: /community/index.html
+  to: /support.html
 - from: /guide/tutorials/
   to: /resources/tutorials/
 - from: /resources/tutorials/views/hello-linearlayout.html
@@ -1193,3 +1195,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/community/index.html b/docs/html/community/index.html
deleted file mode 100644
index e3834ba..0000000
--- a/docs/html/community/index.html
+++ /dev/null
@@ -1,320 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=device-width" />
-
-<meta name="google-site-verification" content="sa-bIAI6GKvct3f61-WpRguHq-aNjtF7xJjMTSi79as" />
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Android Developers Community</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto:regular,medium,thin,italic,mediumitalic,bold" title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-<!-- JAVASCRIPT -->
-<script src="//www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
-<script type="text/javascript">
-  var toRoot = "/";
-  var devsite = false;
-</script>
-
-<script type="text/javascript">
-  var _gaq = _gaq || [];
-  _gaq.push(['_setAccount', 'UA-5831155-1']);
-  _gaq.push(['_trackPageview']);
-
-  (function() {
-    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-  })();
-</script>
-
-<style>
-#header {
-  padding: 2.2em 0 0.2em 0;
-}
-#header-wrap h1 {
-  margin:0;
-  padding:0;
-  line-height:16px;
-}
-#body-content {
-  margin-top:20px;
-}
-#nav-x.wrap {
-  overflow:auto;
-}
-h2 {
-  border-bottom:1px solid #CCC;
-}
-</style>
-</head>
-
-
-
-
-
-
-<body>
-
-
-<!-- Header -->
-<div id="header">
-  <div class="wrap" id="header-wrap">
-    <div class="col-3 logo">
-      <a href="/index.html">
-        <img src="http://developer.android.com/assets/images/dac_logo.png" width="123" height="25" alt="Android Developers" />
-      </a>
-    </div>
-    <div class="col-8">
-      <h1>Community Outreach</h1>
-    </div>
-
-    <div class="menu-container">
-    <div class="moremenu">
-      <div id="more-btn"></div>
-    </div>
-    <div class="morehover" id="moremenu">
-      <div class="top"></div>
-      <div class="mid">
-        <div class="header">Links</div>
-        <ul style="margin-bottom:0">
-          <li><a href="https://www.youtube.com/user/androiddevelopers">Android Developers Live</a></li>
-          <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
-          <li><a href="http://developer.android.com/training/">Android Developer Training</a></li>
-          <li><a href="http://developer.android.com/samples/">Samples</a></li>
-        </ul>
-        <br class="clear-fix">
-    </div>
-      <div class="bottom"></div>
-    </div><!-- end morehover -->
-  </div><!-- end menu-container -->
-  </div><!-- end header-wrap -->
-</div>
-<!-- /Header -->
-
-<div id="nav-x" class="wrap">
-    <ul class="nav-x col-9 develop">
-  <li><a href="#News">News</a></li>
-  <li><a href="#Community">Community</a></li>
-  <li><a href="#Content">Content</a></li>
-  <li><a href="#Social">Social</a></li>
-  </ul>
-</div>
-
-
-<!-- MAIN CONTENT -->
-
-
-<div class="wrap" id="body-content">
-
-<img src="/images/community/aco1small.png" alt="" style="float:right;margin:20px 0 0 40px">
-
-<p style="clear:left">
-  Android is working with communities to 
-<ul>
-<li>Create a cooperative relationship between highly impactful communities and high performing developers</li>
-<li>Strengthen relationships between Android and coding communities so that developers have a motivation to interact with those communities</li>
-<li>Reward communities for attracting developers by providing them with resources and direct access to the Android team</li></ul>
-<p>Our IMPACT is measured by <strong>good apps</strong> and a <strong>thriving community</strong></p>
-
-<h2 id="News" style="clear:left">News</h2>
-<p>Our current theme is on the <b><em>Android 4.4 KitKat and Updated Developer Tools</em></b> release, with new ways to create beautiful apps, printing and storage frameworks, low-power sensors, new media capabilities and RenderScript in the NDK.</p>
-
-<div class="col-8" style="margin-left:0">
-<img src="/images/community/kk-hero2.jpg" alt="" height="277">
-</div>
-
-<div class="col-8" style="margin-right:0">
-<h3 style="margin-top:0"><a href="http://developer.android.com/about/versions/kitkat.html">Android 4.4 Platform Highlights</a></h3>
-<p>Android KitKat brings all of Android's most innovative, most beautiful, and most useful features to more devices everywhere.</p>
-
-<h3><a href="http://developer.android.com/about/versions/android-4.4.html">Android 4.4 APIs</a></h3>
-<p>Android 4.4 (KITKAT) is a new release for the Android platform that offers new features for users and app developers. This document provides an introduction to the most notable new APIs.</p>
-
-<h3><a href="https://play.google.com/store/devices/details?id=nexus_5_white_32gb">New Nexus 5</a></h3>
-<p>Nexus 5 helps you capture the everyday and the epic in fresh new ways. It's the slimmest and fastest Nexus phone ever made, powered by Android 4.4, KitKat.</p>
-</div>
-<p></p>
-
-<h2 id="Community" style="clear:left">Community Spotlight</h2>
-
-<div class="col-8" style="margin-left:0">
-<h3>Android Community Groups</h3>
-<h4>July 2013</h4>
-<p><a href="mailto:gtugam@gmail.com">GDG Armenia</a> held <a href="http://eca.hackathon.am/">ecaHack Yerevan</a>, an Android hackathon featuring &quot;Angry Designers vs Android Developers&quot;, where the designers had a look into developers apps and gave them some advices regarding to design. The hackathon was sponsored by Alcatel One Touch and each member of the winner team got one Alcatel One Touch Idol. Check out the <a href="https://plus.google.com/u/0/events/gallery/cgj9d39gphiephlq0e2899dv6j4?cfem=1">photos.</a></p>
-<h4>September 2013</h4>
-<p><a href="mailto:soham.mondal@gmail.com">GDG Blrdroid</a> held a <a href="http://www.meetup.com/blrdroid/events/140665852/">meetup</a> on performance optimisation.</p>
-<p><a href="mailto:baileye@gmail.com">GDG Dublin</a> held their meetup with a talk on AdMob for Android and iOS, entitled &ldquo;Admob for Android and iOS developers&rdquo;. </p>
-<p>GDG Mbale&rsquo;s <a href="mailto:nsubugahassan@gmail.com">Hassan Nsubuga</a> has been managing a university <a href="https://plus.google.com/103735976334615631393/posts/gQMWCGUhMBn">course session</a> since September. They are now through with the basics and have a firm foundation, so this month they will be doing a lot of advanced stuff including exploring the latest API enhancements with KitKat. </p>
-<p><a href="mailto:wojtek.kalicinski@gmail.com">GDG Warsaw</a> held an Android Barcamp focused on App Quality. The discussion was moderated by GDG organisers, but the talks were given by the community members, including some top Android companies and developers in Poland.</p>
-<h4>October 2013</h4>
-<p><a href="mailto:benjamin.r.m.weiss@gmail.com">GDG Berlin Android</a> held their <a href="https://berlin.ticketbud.com/devfest-berlin-2013">DevFest</a>.</p>
-<p><a href="mailto:soham.mondal@gmail.com">GDG Blrdroid</a> held their <a href="http://www.meetup.com/blrdroid/events/144457162/">meetup</a> in collaboration with GDG Bangalore, where they talked about a wider range of things from incorporating user feedback to effectively using the cell radio. David McLaughlin from the Developer Relations team also visited during the meetup and delivered the keynote. They also hit a milestone with its 4th anniversary on the 9th of October and crossed 4300 members in the past few days so its been a memorable couple of months for them.</p>
-<p><a href="mailto:hir3npatel@gmail.com">GDG Cape Town</a> held an <a href="https://plus.google.com/108309780217630451504/posts/9BTCEqnBHoQ">Android Workshop</a> where they gave away lots of branded KitKats.</p>
-<p><a href="mailto:baileye@gmail.com">GDG Dublin</a> held its DevFest, which featured a codeLab on Android titled &ldquo;Codelab: Intro to Android Development.&rdquo;</p>
-<p><a href="mailto:hugo@dutchaug.org">GDG Dutch Android User Group</a> held their <a href="http://www.devfest.nl/program">DevFest</a>. They had a bunch of Android sessions, mostly by local speakers. In addition to the Android sessions, they also ran a workshop on writing custom views.</p>
-<p><a href="mailto:hugo@dutchaug.org">Hugo Visser</a> from the Dutch Android User Group spoke at <a href="https://bitbucket.org/qbusict/cupboard">DroidCon UK barcamp</a>, where he delivered a talk on Cupboard, a simple and lightweight persistence framework, specifically for Android.</p> 
-<p><a href="mailto:prajyotmainkar@gmail.com">GDG GAUG</a> held the <a href="https://plus.google.com/110448195989468248957/posts/8doJuCpySWS">Google Devfest 2013</a>, where they had two tracks and more than 200 delegates attending. They also had a <a href="https://plus.google.com/110448195989468248957/posts/6rxLzj2Rpde">Hackathon</a> and they hit the <a href="https://plus.google.com/110448195989468248957">1000 member</a> mark this month, which makes them the second largest android community in India after GDG Blrdroid. </p>
-<p><a href="mailto:cyrilleguipie@gmail.com">GDG Miage</a> held their DevFest where they gave a talk about Intents and Services. The also held a startup Weekend Bootcamp where they talked about Activites and Layouts. They will also hold an Android Workshop in December.</p>
-<p><a href="mailto:gabriel.kb@gmail.com">GDG Uruguay</a> had their <a href="http://gdg.uy/devfest2013">DevFest</a>, where they held an Android workshop for beginners as an Android vs iOS comparison, a session on best practices using YouTube APIs in Android, and &nbsp;What's new in Google for developers (with a special section about Android). You can see pictures on <a href="https://plus.google.com/114520966453242230657/posts/dqZAuMqc12Z">the G+ page</a>. </p>
-
-<h4>November 2013</h4>
-<p><a href="mailto:yorogoule@gmail.com">Abidjandroid/GDG Côte d'Ivoire</a> held an Android Launch Party featuring the KitKat release.</p>
-<p>The <a href="mailto:hugo@dutchaug.org">Dutch Android User Group</a> had a very interactive presentation on Android Code Puzzlers and Tips &amp; tricks, where they rewarded participation by giving out books, tshirts, jelly beans and kitkats. The presentation was at the <a href="http://www.nljug.org/jfall">Dutch JFall conference</a>, organized by the NLJUG. It's a large yearly Java conference and the DAUG had the only Android session there.</p>
-<p>The <a href="mailto:benjamin.r.m.weiss@gmail.com">GDG Berlin Android</a> meetup this month  featured the KitKat release.</p>
-<p><a href="mailto:soham.mondal@gmail.com">The GDG Blrdroid</a> <a href="http://www.meetup.com/blrdroid/events/148210762/%20">meetup</a> was another focused on KitKat.</p>
-<p>At the <a href="mailto:amahdy7@gmail.com">GDG Cairo</a> <a href="https://plus.google.com/events/co59j0870in5a4kh8n5navifnm8">DevFest</a> there was a &quot;What's new in Android SDK&quot; session on day 1, and an Android workshop on day 2. Kitkat also provided interest in the sessions and the snacks bar. The KitKat <a href="http://buff.ly/HNE7yq">presentation</a>, the track organization, and everything related to it were all organized by women.</p>
-<p><a href="mailto:hir3npatel@gmail.com">GDG Cape Town</a> held an Android Workshop.</p>
-<p><a href="mailto:alessandro.gbridge@gmail.com">GDG Udine</a>  organized a talk after the release of KitKat for a school in Pordenone.</p>
-<p><a href="mailto:hugo@dutchaug.org">Hugo Visser</a> from Droidcon Netherlands  organized an Android hackathon themed &quot;Location, Location, Location&quot;. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
-<p><a href="mailto:eyal.lezmy@gmail.com">Paris Android User Group</a> welcomed <a href="https://plus.google.com/+RomainGuy">Romain Guy</a> and <a href="https://plus.google.com/+ChetHaase">Chet Haase</a> to their meetup this month. They&rsquo;ll be meeting up with other GDG leads and UG managers meet at <a href="https://plus.google.com/events/cupo201fjreo9g9t2e596gv8nd4">Devoxx</a> next Thursday.</p>
-<p><a href="mailto:wojtek.kalicinski@gmail.com">GDG Warsaw</a> had over 250 attendees at their DevFest, which featured session tracks on Android and Web and a whole day of Code Labs in Android, AngularJS and Arduino.</p>
-<h4>December 2013</h4>
-<p><a href="mailto:prajyotmainkar@gmail.com">GDG GAUG</a> are planning a codelab and hackathon.</p>
-<p><a href="mailto:psvensson@gmail.com">Peter Svensson</a> spoke at <a href="http://swdc.se/droidcon/events/stockholm-2013/">DroidCon Stockholm</a></p>
-The unstoppable <a href="mailto:bonbhel@gmail.com">Max Bonbhel</a> from the African GDG Android is hosting AAC 2014 and Android GDG Barcamp events in December. Also, in order to encourage African Java developers to move to the Android platform, he created the <a href="https://docs.google.com/spreadsheet/ccc?key=0AtFPan-z2ps-dHBtX1luY2pRQjdtRjliUGcxMVBNeVE&usp=sharing#gid=0">Africa Android Training (AAT) program</a>. The training material targets developers with different levels of experience in Java development. More than 60 developers have been taking part in the weekly sessions. The next 10 sessions will start Saturday, November 9, 2013. 260 GDG and Java User Group members have already registered from 12 Countries.
-<p>&nbsp;</p>
-</div>
-
-<div class="col-8" style="margin-right:0">
-<h3>Android Community Experts</h3>
-
-<h4>October 2013</h4>
-<p><a href="mailto:eyal.lezmy@gmail.com">Eyal Lezmy</a> presented two sessions. &ldquo;<a href="http://bit.ly/andbigfail">Play Store bashing, learn from the biggest fails</a>&rdquo; looked at several applications, mainly developed by huge companies, and analyzed why they failed to satisfy the users or the Android guidelines. &ldquo;<a href="http://bit.ly/lifeofapp">Android, the life of your app</a>&rdquo; tells a story, living the life of a user, identify the frustrations he can encounter and present ways to avoid it, as a developer.</p>
-<p><a href="mailto:mariux01@gmail.com">Mario Viviani</a> presented and recorded the next <a href="http://www.youtube.com/watch?v=jaT0bYhhaGY">Android App Clinic - Italia</a>. This episode was regarding the Cards UI and SMS app support in Android 4.4. They experimented with a short form of the video (10 minutes instead of 20) and in less than day it got almost 400+ views -- which is great considering it's in Italian! The previous episode reached 1300 views all-time and was the most successful video of GDL Italia in Q2.</p>
-<p><a href="mailto:m.kaeppler@gmail.com">Matthias Käppler</a> contributed the <a href="https://github.com/Netflix/RxJava/tree/master/rxjava-contrib/rxjava-android">first Android specific component</a> to the RxJava project, and spoke about <a href="http://uk.droidcon.com/2013/sessions/conquering-concurrency-bringing-the-reactive-extensions-to-the-android-platform/">RxJava and reactive programming on Android</a> at DroidCon UK. He has also open sourced <a href="https://github.com/mttkay/memento">Memento</a>, an Android annotation processor to replace the deprecated onRetainNonConfigurationInstance.</p>
-<p><a href="mailto:wojtek.kalicinski@gmail.com">Wojtek Kaliciński</a>&rsquo;s talk, &quot;Android - is it time for a break yet?&quot; highlights not only what's new in Android 4.4 KitKat, but also how to take your app to the next level by making sure you provide the best app experience possible to all 4.0+ users.</p>
-<a href="https://plus.sandbox.google.com/110448195989468248957/posts"><img src="/images/community/hackathon-gdgaug.jpg" alt=""  align="right"></a>
-
-</div>
-
-<h2 id="Content" style="clear:left">New Content</h2>
-<div class="col-8" style="margin-left:0">
-<p><h4>Android 4.4 What's New</h4>
-KitKat has been optimized to run on a much broader range of devices, with special focus on the millions of entry-level devices that have as little as 512MB RAM. To help, we've created new APIs, better tools, and better documentation to let you create apps that perform well on all devices.<br>
-Check out this video summary of some of the most significant developer features in the latest Android release, including  new ways to make your apps beautiful, NFC Host Card Emulation, a printing framework, the storage access framework, low-power step detector and step counter sensors, and more!<br>
-<h5><a href="http://www.youtube.com/watch?v=sONcojECWXs&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<i>Be sure to get the <a href="http://developer.android.com/about/versions/android-4.4.html">full Android 4.4 API Overview</a>, and take a look at our <a href="https://www.youtube.com/playlist?list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">related DevBytes videos</a></i></p>
-
-<p><h4>WebView in Android 4.4</h4>
-Android 4.4 (API level 19) introduces a new version of WebView that is based on Chromium. This change upgrades WebView performance and standards support for HTML5, CSS3, and JavaScript to match the latest web browsers. Any apps using WebView will inherit these upgrades when running on Android 4.4 and higher.
-<h5><a href="http://developer.android.com/guide/webapps/migrating.html">API Guide</a></h5>
-</p>
-
-<p><h4>Android 4.4 Immersive Mode</h4>
-With Android 4.4 KitKat, your apps can now truly go full-screen with a new Immersive Mode. Immersive Mode lets your apps hide the system's status and navigation bars while capturing all touch events—ideal for rich interactive content such as books and games. This video demonstrates how to use the new API, in addition to recapping earlier full-screen APIs on Android.
-<h5><a href="http://www.youtube.com/watch?v=cBi8fjv90E4&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<h5><a href="http://developer.android.com/samples/ImmersiveMode/index.html">Sample</a></h5>
-</p>
-
-<p>
-<h4>Android 4.4 Storage Access Framework - Provider</h4>
-Get up to speed on the new document storage API in Android 4.4 KitKat. This video gets you up and running with your own DocumentProvider by stepping you through the making of a simple cloud storage app.
-<h5><a href="http://www.youtube.com/watch?v=zxHVeXbK1P4&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<h5><a href="http://developer.android.com/guide/topics/providers/document-provider.html">Training</a></h5>
-<h5><a href="http://developer.android.com/samples/StorageProvider/index.html">Sample</a>, <a href="https://play.google.com/store/apps/details?id=com.box.android">Box Application</a></h5>
-</blockquote>
-
-</p>
-
-
-<p><h4>Android 4.4 Storage Access Framework - Client</h4>
-Get up to speed on the new storage access framework in Android 4.4 KitKat. This video teaches you how to quickly create, edit, save and delete documents provided by other apps as a client of the storage access framework.
-<h5><a href="http://www.youtube.com/watch?v=UFj9AEz0DHQ&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<h5><a href="http://developer.android.com/samples/StorageClient/index.html">Sample</a></h5>
-</p>
-
-<p><h4>Android 4.4 Closed Captioning</h4>
-Displaying closed captions in your app's videos can be quick and simple in Android 4.4 KitKat,. Learn how to attach timed text tracks to VideoView and allow users to customize how captions are displayed.
-<h5><a href="http://www.youtube.com/watch?v=hCRGc2PcmB8&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a>
-</p>
-</h5>
-</div>
-
-<div class="col-8" style="margin-right:0">
-
-<p>
-<h4>Android 4.4 Transitions</h4>
-In this episode, we introduce the new Transitions API in Android 4.4 Kitkat. This API provides a simple way for developers to provide animated segues to different scenes of their application, helping users to understand the application flow with very little code. The general approach is to tell the system that you'd like to run a transition animation, then make the necessary changes to your UI. The system figures out the differences and animates the changes.
-<h5><a href="http://www.youtube.com/watch?v=S3H7nJ4QaD8&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K&index=3">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></p>
-</h5>
-<p><h4>Android 4.4: SMS APIs</h4>
-Android 4.4 KitKat introduces the new SMS APIs as well as the new concept of a default SMS app. This video discusses these new APIs and how your app should use them to send and receive SMS and MMS messages.<br>
-<h5><a href="http://www.youtube.com/watch?v=mdq0R2WQssQ&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<i>See also -<br>
-<a href="http://goo.gl/sw5NdH">Android Developer Blog post on Android 4.4 KitKat SMS APIs</a><br>
-<a href="http://goo.gl/7vTx3s">Android Protip on using booleans in your AndroidManifest.xml</a></i></p>
-
-
-<p><h4>Android 4.4 Printing API</h4>
-In this video, we introduce the new Printing API in Android 4.4 KitKat. This API provides a simple way for developers to print to cloud-connected printers using Google Cloud Print. It's really easy to print bitmaps, and HTML (that you generate on the device, or just web content).<br>
-<h5><a href="http://www.youtube.com/watch?v=Iub67ic87KI&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a></h5>
-<h5><a href="http://developer.android.com/training/printing/index.html">Training</a></h5>
-<i>Some pro-tips:</i>
-<ul>
-  <li>For Webview/HTML printing, printing from javascript is not supported yet (window.print() for example). Also we are planning to address the limitations around WebView/HTML printing in future releases (eg: headers/footers, and specifying print ranges).</li>
-<li>We encourage developers to open Android Open Source bugs for features that they feel important as a feedback.</li>
-</ul>
-
-<p><h4>App Indexing</h4>
-In this episode we discuss the new App Indexing feature that we recently announced for Google Search for Android.<br>
-Currently, when you do a google search on the web, you get results that are links to websites. With App Indexing, you will be able to point Google Search users on Android directly to content within your app!
-If you’re an Android app developer who has a web presence and you want more control over how your content is accessed from search, via your website or Android app, App Indexing is a great feature for you to explore.
-Also, enabling your website and app for indexing is a way to increase engagement with your app by making the content more discoverable, and more accessible to users directly from the search results page.
-For information on App Indexing, please visit <a href="http://g.co/appindexing">http://g.co/appindexing</a>
-<h5><a href="http://www.youtube.com/watch?v=Xh_W82JgOms&list=PLWz5rJ2EKKc-2quE-o0enpILZF3nBZg_K">Video</a></h5>
-<h5><a href="https://drive.google.com/a/google.com/folderview?id=0BwhAiXVwzMoFc28wWEpyeE9qYTQ&usp=sharing">Presentation</a>
-</p>
-</h5>
-</div>
-
-<h2 id="Social" style="clear:left">Social</h2>
-<div class="col-8" style="margin-left:0">
-
-<h3 >G+</h3>
-
-<ul>
-<li><a href="https://plus.google.com/u/1/108967384991768947849/posts/1iVvwyfTM8y">What's New in Android 4.4</a>
-  <ul>
-    <li><a href="http://www.youtube.com/watch?v=HrFRY32i_sE">What's New in Android 4.4 [JAPANESE!]</a></li>
-    <li><a href="https://www.youtube.com/watch?v=U9jAcwaETD4">What's New in Android 4.4 [KOREAN!]</a></li>
-    <li><a href="https://plus.google.com/u/1/108967384991768947849/posts/WfqdvDG2Cyr">Quer saber das novidades do Android 4.4? [PORTUGUESE!]</a></li>
-  </ul>
-</li>
-<li><a href="https://plus.google.com/u/1/+AndroidDevelopers/posts/femjRbay18f">Android 4.4 and Updated Developer Tools 
-</a></li>
-<li><a href="https://plus.google.com/u/1/108967384991768947849/posts/P2q82aYN7do">Google Play Services 4.0 
-</a></li>
-</ul>
-</div>
-
-<div class="col-8" style="margin-right:0">
-<h3>Blog</h3>
-
-<ul>
-  <li><a href="http://android-developers.blogspot.hk/2013/10/android-44-kitkat-and-updated-developer.html">Android 4.4 KitKat and Updated Developer Tools</a></li>
-  <li><a href="http://android-developers.blogspot.hk/2013/10/google-play-services-40.html">Google Play Services 4.0</a></li>
-  <li><a href="http://android-developers.blogspot.hk/2013/10/making-your-app-content-more-accessible.html">Making your App Content more Accessible from Googl...</a></li>
-  <li><a href="http://android-developers.blogspot.hk/2013/10/getting-your-sms-apps-ready-for-kitkat.html">Getting Your SMS Apps Ready for KitKat</a></li>
-</ul>
-</div>
-
-</div><!-- /MAIN CONTENT 'wrap' -->
-</body>
-</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/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index 39b8d3d..84451ba 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -530,14 +530,14 @@
 }
 
 void ClipArea::applyTransformToRegion(const Matrix4& transform, SkRegion* region) {
-    if (transform.isSimple() && !transform.isPureTranslate()) {
+    if (transform.rectToRect() && !transform.isPureTranslate()) {
         // handle matrices with scale manually by mapping each rect
         SkRegion other;
         SkRegion::Iterator it(*region);
         while (!it.done()) {
             Rect rect(it.rect());
             transform.mapRect(rect);
-            rect.roundOut();
+            rect.snapGeometryToPixelBoundaries(true);
             other.op(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kUnion_Op);
             it.next();
         }
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/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index afabd35..d4d7919 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -334,5 +334,14 @@
     EXPECT_EQ(SkIRect::MakeLTRB(12, 26, 16, 32), region.getBounds());
 }
 
+TEST(ClipArea, applyTransformToRegion_rotate90) {
+    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
+    Matrix4 transform;
+    transform.loadRotate(90);
+    ClipArea::applyTransformToRegion(transform, &region);
+    EXPECT_TRUE(region.isRect());
+    EXPECT_EQ(SkIRect::MakeLTRB(-4, 1, -2, 3), region.getBounds());
+}
+
 } // namespace uirenderer
 } // namespace android
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/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 542dced..264944f 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -133,9 +133,10 @@
  <p class=note>
  Note that on some devices the slice-height is advertised as 0. This could mean either that the
  slice-height is the same as the frame height, or that the slice-height is the frame height
- aligned to some value (usually a power of 2). Unfortunately, there is no way to tell the actual
- slice height in this case. Furthermore, the vertical stride of the {@code U} plane in planar
- formats is also not specified or defined, though usually it is half of the slice height.
+ aligned to some value (usually a power of 2). Unfortunately, there is no standard and simple way
+ to tell the actual slice height in this case. Furthermore, the vertical stride of the {@code U}
+ plane in planar formats is also not specified or defined, though usually it is half of the slice
+ height.
  <p>
  The {@link MediaFormat#KEY_WIDTH} and {@link MediaFormat#KEY_HEIGHT} keys specify the size of the
  video frames; however, for most encondings the video (picture) only occupies a portion of the
@@ -620,8 +621,9 @@
  mode} will be automatically applied with one exception:
  <p class=note>
  Prior to the {@link android.os.Build.VERSION_CODES#M} release, software decoders may not
- have applied the rotation when being rendered onto a Surface. Unfortunately, there is no way to
- identify software decoders, or if they apply the rotation other than by trying it out.
+ have applied the rotation when being rendered onto a Surface. Unfortunately, there is no standard
+ and simple way to identify software decoders, or if they apply the rotation other than by trying
+ it out.
  <p>
  There are also some caveats.
  <p class=note>
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index d7a18d9..d74aa81 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -49,12 +49,18 @@
  * <tr><td>{@link #KEY_FRAME_RATE}</td><td>Integer or Float</td><td>required for <b>encoders</b>,
  *         optional for <b>decoders</b></td></tr>
  * <tr><td>{@link #KEY_CAPTURE_RATE}</td><td>Integer</td><td></td></tr>
- * <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer</td><td><b>encoder-only</b></td></tr>
+ * <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer (or Float)</td><td><b>encoder-only</b>,
+ *         time-interval between key frames.
+ *         Float support added in {@link android.os.Build.VERSION_CODES#N_MR1}</td></tr>
  * <tr><td>{@link #KEY_INTRA_REFRESH_PERIOD}</td><td>Integer</td><td><b>encoder-only</b>, optional</td></tr>
  * <tr><td>{@link #KEY_MAX_WIDTH}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution width</td></tr>
  * <tr><td>{@link #KEY_MAX_HEIGHT}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution height</td></tr>
- * <tr><td>{@link #KEY_REPEAT_PREVIOUS_FRAME_AFTER}</td><td>Long</td><td><b>video encoder in surface-mode only</b></td></tr>
- * <tr><td>{@link #KEY_PUSH_BLANK_BUFFERS_ON_STOP}</td><td>Integer(1)</td><td><b>video decoder rendering to a surface only</b></td></tr>
+ * <tr><td>{@link #KEY_REPEAT_PREVIOUS_FRAME_AFTER}</td><td>Long</td><td><b>encoder in surface-mode
+ *         only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_PUSH_BLANK_BUFFERS_ON_STOP}</td><td>Integer(1)</td><td><b>decoder rendering
+ *         to a surface only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_TEMPORAL_LAYERING}</td><td>String</td><td><b>encoder only</b>, optional,
+ *         temporal-layering schema</td></tr>
  * </table>
  * Specify both {@link #KEY_MAX_WIDTH} and {@link #KEY_MAX_HEIGHT} to enable
  * adaptive playback (seamless resolution change) for a video decoder that
@@ -258,9 +264,20 @@
     public static final String KEY_CAPTURE_RATE = "capture-rate";
 
     /**
-     * A key describing the frequency of I frames expressed in secs
-     * between I frames.
-     * The associated value is an integer.
+     * A key describing the frequency of key frames expressed in seconds between key frames.
+     * <p>
+     * This key is used by video encoders.
+     * A negative value means no key frames are requested after the first frame.
+     * A zero value means a stream containing all key frames is requested.
+     * <p class=note>
+     * Most video encoders will convert this value of the number of non-key-frames between
+     * key-frames, using the {@linkplain #KEY_FRAME_RATE frame rate} information; therefore,
+     * if the actual frame rate differs (e.g. input frames are dropped or the frame rate
+     * changes), the <strong>time interval</strong> between key frames will not be the
+     * configured value.
+     * <p>
+     * The associated value is an integer (or float since
+     * {@link android.os.Build.VERSION_CODES#N_MR1}).
      */
     public static final String KEY_I_FRAME_INTERVAL = "i-frame-interval";
 
@@ -280,12 +297,18 @@
 
    /**
      * A key describing the temporal layering schema.  This is an optional parameter
-     * that applies only to video encoders.  Use {@link MediaCodec#getInputFormat}
+     * that applies only to video encoders.  Use {@link MediaCodec#getOutputFormat}
      * after {@link MediaCodec#configure configure} to query if the encoder supports
-     * the desired schema. Supported values are {@code webrtc.vp8.1-layer},
-     * {@code webrtc.vp8.2-layer}, {@code webrtc.vp8.3-layer}, and {@code none}.
-     * If the encoder does not support temporal layering, the input format will
-     * not have an entry with this key.
+     * the desired schema. Supported values are {@code webrtc.vp8.N-layer},
+     * {@code android.generic.N}, {@code android.generic.N+M} and {@code none}, where
+     * {@code N} denotes the total number of non-bidirectional layers (which must be at least 1)
+     * and {@code M} denotes the total number of bidirectional layers (which must be non-negative).
+     * <p class=note>{@code android.generic.*} schemas have been added in {@link
+     * android.os.Build.VERSION_CODES#N_MR1}.
+     * <p>
+     * The encoder may support fewer temporal layers, in which case the output format
+     * will contain the configured schema. If the encoder does not support temporal
+     * layering, the output format will not have an entry with this key.
      * The associated value is a string.
      */
     public static final String KEY_TEMPORAL_LAYERING = "ts-schema";
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/Keyguard/res/values-my-rMM/dimens.xml b/packages/Keyguard/res/values-my-rMM/dimens.xml
new file mode 100644
index 0000000..21b2a46
--- /dev/null
+++ b/packages/Keyguard/res/values-my-rMM/dimens.xml
@@ -0,0 +1,19 @@
+<?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
+  -->
+<resources>
+    <dimen name="bottom_text_spacing_digital">4dp</dimen>
+</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index 9d1df26..e1657c7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -127,6 +127,11 @@
         super.onConfigurationChanged(newConfig);
         mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
+        // Some layouts like burmese have a different margin for the clock
+        MarginLayoutParams layoutParams = (MarginLayoutParams) mClockView.getLayoutParams();
+        layoutParams.bottomMargin = getResources().getDimensionPixelSize(
+                R.dimen.bottom_text_spacing_digital);
+        mClockView.setLayoutParams(layoutParams);
         mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
         mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
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/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 99145b7b..eea92b5 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -94,6 +94,7 @@
                     // but the content has changed.
                     if (mNextCommand == null) {
                         if (mUpdateSpec.pages != null && (mDocumentInfo.changed
+                                || mDocumentInfo.writtenPages == null
                                 || (mDocumentInfo.info.getPageCount()
                                         != PrintDocumentInfo.PAGE_COUNT_UNKNOWN
                                 && !PageRangeUtils.contains(mDocumentInfo.writtenPages,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index b79ce80..bf48e5d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -247,7 +247,6 @@
                 return Settings.Secure.getInt(mContext.getContentResolver(), name, 0) != 0;
             case Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES:
             case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES:
-            case Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX:
             case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
             case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE:
                 return !TextUtils.isEmpty(Settings.Secure.getString(
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..aaca663e
--- /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/drawable/ic_qs_signal_4g_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
index 258bd0f..4d7f325 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
@@ -1,37 +1,30 @@
 <!--
-     Copyright (C) 2016 The Android Open Source Project
+    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
+    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
 
-     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.
+         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="18.0dp"
-    android:height="24dp"
-    android:viewportWidth="36.0"
-    android:viewportHeight="36.0">
-
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6.797,13.334h1.231v1.522H6.797v2.509h-1.62v-2.509H1.101l-0.039-1.157l4.069-7.643h1.666V13.334z
-M2.648,13.334h2.53V8.721L5.137,8.713L4.984,9.148L2.648,13.334z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M4.6,7.8l0.7,0.0l0.0,1.3L4.6,9.1L4.6,11.0L3.0,11.0L3.0,9.2L0.1,9.2L0.0,8.2l3.0,-5.7l1.7,0.0L4.6,7.8L4.6,7.8zM1.7,7.8L3.0,7.8l0.0,-3.0L2.9,5.0L1.7,7.8z"/>
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M16.155,15.836c-0.269,0.439-0.695,0.832-1.282,1.177c-0.587,0.344-1.344,0.517-2.271,0.517
-c-1.151,0-2.098-0.432-2.841-1.294c-0.744-0.862-1.115-1.978-1.115-3.345v-2.36c0-1.367,0.359-2.481,1.077-3.343
-c0.719-0.863,1.643-1.293,2.772-1.293c1.132,0,2.017,0.331,2.649,0.994c0.633,0.663,0.941,1.528,0.924,2.594l-0.021,0.047h-1.545
-c0-0.638-0.171-1.15-0.513-1.538c-0.341-0.389-0.831-0.583-1.469-0.583c-0.674,0-1.217,0.292-1.63,0.877
-c-0.413,0.585-0.619,1.328-0.619,2.229v2.375c0,0.912,0.215,1.662,0.645,2.25c0.431,0.587,0.992,0.881,1.684,0.881
-c0.522,0,0.935-0.068,1.238-0.205c0.304-0.138,0.533-0.305,0.688-0.502v-2.338h-2.041v-1.413h3.668V15.836z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M11.9,9.9c-0.2,0.4 -0.6,0.7 -1.0,0.9s-1.0,0.4 -1.8,0.4c-0.9,0.0 -1.7,-0.3 -2.2,-0.8S6.1,9.0 6.1,7.9L6.1,5.6c0.0,-1.1 0.3,-1.9 0.8,-2.4S8.2,2.4 9.0,2.4c1.0,0.0 1.7,0.2 2.1,0.7s0.7,1.2 0.7,2.1l-1.6,0.0c0.0,-0.5 -0.1,-0.9 -0.2,-1.1S9.5,3.7 9.0,3.7c-0.4,0.0 -0.7,0.2 -0.9,0.5S7.8,5.0 7.8,5.6l0.0,2.3c0.0,0.7 0.1,1.1 0.3,1.4c0.2,0.3 0.6,0.5 1.0,0.5c0.3,0.0 0.6,0.0 0.7,-0.1s0.3,-0.2 0.4,-0.3L10.2,7.8L9.0,7.8L9.0,6.6l2.9,0.0L11.9,9.9z"/>
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19.366,14.701v-2.232h-2.25v-1.541h2.25V8.695h1.5v2.232h2.256v1.541h-2.256v2.232H19.366z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M17.7,4.4l-1.900001,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.900001,0.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
new file mode 100644
index 0000000..3af0629
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
@@ -0,0 +1,33 @@
+<!--
+    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="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M2.0,9.7l2.0,0.0L4.0,11.0L0.4,11.0L0.4,2.5L2.0,2.5L2.0,9.7z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M8.3,3.8L7.0,3.8L7.0,11.0L5.4,11.0L5.4,3.8L4.0,3.8L4.0,2.5l4.3,0.0L8.3,3.8z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.4,7.3l-1.7,0.0l0.0,2.4l2.1,0.0L12.799999,11.0L9.0,11.0L9.0,2.5l3.7,0.0l0.0,1.3l-2.1,0.0l0.0,2.1l1.7,0.0L12.4,7.3L12.4,7.3z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18.4,4.4l-1.9,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.9,0.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
index 17a4394..3cdd3e1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
@@ -1,37 +1,30 @@
 <!--
-     Copyright (C) 2016 The Android Open Source Project
+    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
+    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
+         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.
+    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="15dp"
-    android:height="20dp"
-    android:viewportWidth="36"
-    android:viewportHeight="36">
-
+        android:width="17.0dp"
+        android:height="17.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6.797,13.334h1.231v1.522H6.797v2.509h-1.62v-2.509H1.101l-0.039-1.157l4.069-7.643h1.666V13.334z
-M2.648,13.334h2.53V8.721L5.137,8.713L4.984,9.148L2.648,13.334z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M4.6,7.8l0.7,0.0l0.0,1.3L4.6,9.1L4.6,11.0L3.0,11.0L3.0,9.2L0.1,9.2L0.0,8.2l3.0,-5.7l1.7,0.0L4.6,7.8L4.6,7.8zM1.7,7.8L3.0,7.8l0.0,-3.0L2.9,5.0L1.7,7.8z"/>
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M16.155,15.836c-0.269,0.439-0.695,0.832-1.282,1.177c-0.587,0.344-1.344,0.517-2.271,0.517
-c-1.151,0-2.098-0.432-2.841-1.294c-0.744-0.862-1.115-1.978-1.115-3.345v-2.36c0-1.367,0.359-2.481,1.077-3.343
-c0.719-0.863,1.643-1.293,2.772-1.293c1.132,0,2.017,0.331,2.649,0.994c0.633,0.663,0.941,1.528,0.924,2.594l-0.021,0.047h-1.545
-c0-0.638-0.171-1.15-0.513-1.538c-0.341-0.389-0.831-0.583-1.469-0.583c-0.674,0-1.217,0.292-1.63,0.877
-c-0.413,0.585-0.619,1.328-0.619,2.229v2.375c0,0.912,0.215,1.662,0.645,2.25c0.431,0.587,0.992,0.881,1.684,0.881
-c0.522,0,0.935-0.068,1.238-0.205c0.304-0.138,0.533-0.305,0.688-0.502v-2.338h-2.041v-1.413h3.668V15.836z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M11.9,9.9c-0.2,0.4 -0.6,0.7 -1.0,0.9s-1.0,0.4 -1.8,0.4c-0.9,0.0 -1.7,-0.3 -2.2,-0.8S6.1,9.0 6.1,7.9L6.1,5.6c0.0,-1.1 0.3,-1.9 0.8,-2.4S8.2,2.4 9.0,2.4c1.0,0.0 1.7,0.2 2.1,0.7s0.7,1.2 0.7,2.1l-1.6,0.0c0.0,-0.5 -0.1,-0.9 -0.2,-1.1S9.5,3.7 9.0,3.7c-0.4,0.0 -0.7,0.2 -0.9,0.5S7.8,5.0 7.8,5.6l0.0,2.3c0.0,0.7 0.1,1.1 0.3,1.4c0.2,0.3 0.6,0.5 1.0,0.5c0.3,0.0 0.6,0.0 0.7,-0.1s0.3,-0.2 0.4,-0.3L10.2,7.8L9.0,7.8L9.0,6.6l2.9,0.0L11.9,9.9z"/>
     <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19.366,14.701v-2.232h-2.25v-1.541h2.25V8.695h1.5v2.232h2.256v1.541h-2.256v2.232H19.366z" />
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M17.7,4.4l-1.900001,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.900001,0.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
new file mode 100644
index 0000000..db18fad
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
@@ -0,0 +1,33 @@
+<!--
+    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="17.0dp"
+        android:height="17.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M2.0,9.7l2.0,0.0L4.0,11.0L0.4,11.0L0.4,2.5L2.0,2.5L2.0,9.7z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M8.3,3.8L7.0,3.8L7.0,11.0L5.4,11.0L5.4,3.8L4.0,3.8L4.0,2.5l4.3,0.0L8.3,3.8z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.4,7.3l-1.7,0.0l0.0,2.4l2.1,0.0L12.799999,11.0L9.0,11.0L9.0,2.5l3.7,0.0l0.0,1.3l-2.1,0.0l0.0,2.1l1.7,0.0L12.4,7.3L12.4,7.3z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M18.4,4.4l-1.9,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.9,0.0z"/>
+</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..a0cb61a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -354,6 +354,9 @@
     <!-- Content description of the data connection type LTE for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_data_connection_lte">LTE</string>
 
+    <!-- Content description of the data connection type LTE+ for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_data_connection_lte_plus">LTE+</string>
+
     <!-- Content description of the data connection type CDMA for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_data_connection_cdma">CDMA</string>
 
@@ -752,6 +755,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/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 4b82279..64f205d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -58,6 +58,7 @@
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -78,7 +79,6 @@
     private static final int CAP_HEIGHT = 1456;
     private static final int FONT_HEIGHT = 2163;
 
-    private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
     private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
 
     private static final String COUNTER_PANEL_OPEN = "panel_open";
@@ -1376,8 +1376,7 @@
         int min = mStatusBarMinHeight;
         if (mStatusBar.getBarState() != StatusBarState.KEYGUARD
                 && mNotificationStackScroller.getNotGoneChildCount() == 0) {
-            int minHeight = (int) ((mQsMinExpansionHeight + getOverExpansionAmount())
-                    * HEADER_RUBBERBAND_FACTOR);
+            int minHeight = (int) (mQsMinExpansionHeight + getOverExpansionAmount());
             min = Math.max(min, minHeight);
         }
         int maxHeight;
@@ -1552,15 +1551,8 @@
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
             return 0;
         }
-        if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
-            return Math.min(0, mExpandedHeight / HEADER_RUBBERBAND_FACTOR - mQsMinExpansionHeight);
-        }
-        float stackTranslation = mNotificationStackScroller.getStackTranslation();
-        float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
-        if (mHeadsUpManager.hasPinnedHeadsUp() || mIsExpansionFromHeadsUp) {
-            translation = mNotificationStackScroller.getTopPadding() + stackTranslation
-                    - mQsMinExpansionHeight;
-        }
+        float translation = NotificationUtils.interpolate(-mQsMinExpansionHeight, 0,
+                mNotificationStackScroller.getAppearFraction(mExpandedHeight));
         return Math.min(0, translation);
     }
 
@@ -1968,7 +1960,7 @@
         if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
             return mNotificationStackScroller.getPeekHeight();
         } else {
-            return mQsMinExpansionHeight * HEADER_RUBBERBAND_FACTOR;
+            return mQsMinExpansionHeight;
         }
     }
 
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..482c698 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();
         }
 
@@ -2586,7 +2586,7 @@
     @Override
     public void handleSystemNavigationKey(int key) {
         if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
-        if (!panelsEnabled()) {
+        if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()) {
             return;
         }
 
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/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index f415ae5..0c9bfab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -338,11 +338,12 @@
 
     public void dump(PrintWriter pw) {
         int N = mStatusIcons.getChildCount();
-        pw.println("  system icons: " + N);
+        pw.println("  icon views: " + N);
         for (int i=0; i<N; i++) {
             StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
             pw.println("    [" + i + "] icon=" + ic);
         }
+        super.dump(pw);
     }
 
     public void dispatchDemoCommand(String command, Bundle args) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index 97b31f2..6821879 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -81,9 +81,9 @@
 
     public void dump(PrintWriter pw) {
         final int N = mSlots.size();
-        pw.println("Icon list:");
+        pw.println("  icon slots: " + N);
         for (int i=0; i<N; i++) {
-            pw.printf("  %2d: (%s) %s\n", i, mSlots.get(i), mIcons.get(i));
+            pw.printf("    %2d: (%s) %s\n", i, mSlots.get(i), mIcons.get(i));
         }
     }
 }
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/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
index 970fed0..c175180 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -112,6 +112,10 @@
         notifyKeyguardChanged();
     }
 
+    public boolean isDeviceInteractive() {
+        return mKeyguardUpdateMonitor.isDeviceInteractive();
+    }
+
     private void updateCanSkipBouncerState() {
         mCanSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer(mCurrentUser);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index ac3246d..8178bda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -201,7 +201,7 @@
                 TelephonyIcons.FOUR_G_PLUS);
         } else {
             mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
-            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, TelephonyIcons.LTE);
+            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, TelephonyIcons.LTE_PLUS);
         }
         mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 7a042af..a31bc04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -786,6 +786,7 @@
                             datatype.equals("g") ? TelephonyIcons.G :
                             datatype.equals("h") ? TelephonyIcons.H :
                             datatype.equals("lte") ? TelephonyIcons.LTE :
+                            datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
                             datatype.equals("roam") ? TelephonyIcons.ROAMING :
                             TelephonyIcons.UNKNOWN;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index d91b332..ed8c7ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -208,10 +208,12 @@
     };
 
     static final int QS_DATA_LTE = R.drawable.ic_qs_signal_lte;
+    static final int QS_DATA_LTE_PLUS = R.drawable.ic_qs_signal_lte_plus;
 
     static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
     static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam;
     static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
+    static final int ICON_LTE_PLUS = R.drawable.stat_sys_data_fully_connected_lte_plus;
     static final int ICON_G = R.drawable.stat_sys_data_fully_connected_g;
     static final int ICON_E = R.drawable.stat_sys_data_fully_connected_e;
     static final int ICON_H = R.drawable.stat_sys_data_fully_connected_h;
@@ -393,6 +395,21 @@
             TelephonyIcons.QS_DATA_LTE
             );
 
+    static final MobileIconGroup LTE_PLUS = new MobileIconGroup(
+            "LTE+",
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH,
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
+            0, 0,
+            TelephonyIcons.TELEPHONY_NO_NETWORK,
+            TelephonyIcons.QS_TELEPHONY_NO_NETWORK,
+            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
+            R.string.accessibility_data_connection_lte_plus,
+            TelephonyIcons.ICON_LTE_PLUS,
+            true,
+            TelephonyIcons.QS_DATA_LTE_PLUS
+            );
+
     static final MobileIconGroup ROAMING = new MobileIconGroup(
             "Roaming",
             TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING,
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..71b349f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -668,30 +668,74 @@
     public void setStackHeight(float height) {
         mLastSetStackHeight = height;
         setIsExpanded(height > 0.0f);
-        int newStackHeight = (int) height;
-        int minStackHeight = getLayoutMinHeight();
         int stackHeight;
-        float paddingOffset;
-        boolean trackingHeadsUp = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp();
-        int normalUnfoldPositionStart = trackingHeadsUp
-                ? mHeadsUpManager.getTopHeadsUpPinnedHeight()
-                : minStackHeight;
-        if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart
-                || getNotGoneChildCount() == 0) {
-            paddingOffset = mTopPaddingOverflow;
-            stackHeight = newStackHeight;
+        float translationY;
+        float appearEndPosition = getAppearEndPosition();
+        float appearStartPosition = getAppearStartPosition();
+        if (height >= appearEndPosition) {
+            translationY = mTopPaddingOverflow;
+            stackHeight = (int) height;
         } else {
-            int translationY;
-            translationY = newStackHeight - normalUnfoldPositionStart;
-            paddingOffset = translationY - mTopPadding;
-            stackHeight = (int) (height - (translationY - mTopPadding));
+            float appearFraction = getAppearFraction(height);
+            if (appearFraction >= 0) {
+                translationY = NotificationUtils.interpolate(getExpandTranslationStart(), 0,
+                        appearFraction);
+            } else {
+                // This may happen when pushing up a heads up. We linearly push it up from the
+                // start
+                translationY = height - appearStartPosition + getExpandTranslationStart();
+            }
+            stackHeight = (int) (height - translationY);
         }
         if (stackHeight != mCurrentStackHeight) {
             mCurrentStackHeight = stackHeight;
             updateAlgorithmHeightAndPadding();
             requestChildrenUpdate();
         }
-        setStackTranslation(paddingOffset);
+        setStackTranslation(translationY);
+    }
+
+    /**
+     * @return The translation at the beginning when expanding.
+     *         Measured relative to the resting position.
+     */
+    private float getExpandTranslationStart() {
+        int startPosition = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()
+                ? 0 : -getFirstChildMinHeight();
+        return startPosition - mTopPadding;
+    }
+
+    /**
+     * @return the position from where the appear transition starts when expanding.
+     *         Measured in absolute height.
+     */
+    private float getAppearStartPosition() {
+        return mTrackingHeadsUp
+                ? mHeadsUpManager.getTopHeadsUpPinnedHeight()
+                : 0;
+    }
+
+    /**
+     * @return the position from where the appear transition ends when expanding.
+     *         Measured in absolute height.
+     */
+    private float getAppearEndPosition() {
+        int firstItemHeight = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()
+                ? mHeadsUpManager.getTopHeadsUpPinnedHeight() + mBottomStackPeekSize
+                        + mBottomStackSlowDownHeight
+                : getLayoutMinHeight();
+        return firstItemHeight + mTopPadding + mTopPaddingOverflow;
+    }
+
+    /**
+     * @param height the height of the panel
+     * @return the fraction of the appear animation that has been performed
+     */
+    public float getAppearFraction(float height) {
+        float appearEndPosition = getAppearEndPosition();
+        float appearStartPosition = getAppearStartPosition();
+        return (height - appearStartPosition)
+                / (appearEndPosition - appearStartPosition);
     }
 
     public float getStackTranslation() {
@@ -2096,6 +2140,12 @@
     }
 
     public int getLayoutMinHeight() {
+        int firstChildMinHeight = getFirstChildMinHeight();
+        return Math.min(firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight,
+                mMaxLayoutHeight - mTopPadding);
+    }
+
+    private int getFirstChildMinHeight() {
         final ExpandableView firstChild = getFirstChildNotGone();
         int firstChildMinHeight = firstChild != null
                 ? firstChild.getIntrinsicHeight()
@@ -2105,8 +2155,7 @@
         if (mOwnScrollY > 0) {
             firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
         }
-        return Math.min(firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight,
-                mMaxLayoutHeight - mTopPadding);
+        return firstChildMinHeight;
     }
 
     public float getTopPaddingOverflow() {
@@ -2347,6 +2396,7 @@
         if (hasAddEvent) {
             // This child was just added lets remove all events.
             mHeadsUpChangeAnimations.removeAll(mTmpList);
+            ((ExpandableNotificationRow ) child).setHeadsupDisappearRunning(false);
         }
         mTmpList.clear();
         return hasAddEvent;
@@ -2604,6 +2654,10 @@
                 type = row.wasJustClicked()
                         ? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
                         : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
+                if (row.isChildInGroup()) {
+                    // We can otherwise get stuck in there if it was just isolated
+                    row.setHeadsupDisappearRunning(false);
+                }
             } else {
                 StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
                 if (viewState == null) {
@@ -3093,6 +3147,22 @@
         requestChildrenUpdate();
         runAnimationFinishedRunnables();
         clearViewOverlays();
+        clearHeadsUpDisappearRunning();
+    }
+
+    private void clearHeadsUpDisappearRunning() {
+        for (int i = 0; i < getChildCount(); i++) {
+            View view = getChildAt(i);
+            if (view instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+                row.setHeadsupDisappearRunning(false);
+                if (row.isSummaryWithChildren()) {
+                    for (ExpandableNotificationRow child : row.getNotificationChildren()) {
+                        child.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/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index f01e95f..995ecae 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -124,12 +124,8 @@
                 : null;
         Util.setText(mSummaryLine1, line1);
 
-        final boolean isForever = mConfig != null && mConfig.manualRule != null
-                && mConfig.manualRule.conditionId == null;
-        final CharSequence line2 =
-                isForever ? mContext.getString(com.android.internal.R.string.zen_mode_forever_dnd)
-                : ZenModeConfig.getConditionSummary(mContext, mConfig, mController.getCurrentUser(),
-                        true /*shortVersion*/);
+        final CharSequence line2 = ZenModeConfig.getConditionSummary(mContext, mConfig,
+                                mController.getCurrentUser(), true /*shortVersion*/);
         Util.setText(mSummaryLine2, line2);
     }
 
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 97efed0..05207b9 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -114,13 +114,17 @@
                 imageStage.delete();
                 lockImageStage.delete();
 
-                Os.link(mWallpaperInfo.getCanonicalPath(), infoStage.getCanonicalPath());
-                fullBackupFile(infoStage, data);
-                Os.link(mWallpaperFile.getCanonicalPath(), imageStage.getCanonicalPath());
-                fullBackupFile(imageStage, data);
+                if (mWallpaperInfo.exists()) {
+                    Os.link(mWallpaperInfo.getCanonicalPath(), infoStage.getCanonicalPath());
+                    fullBackupFile(infoStage, data);
+                }
+                if (mWallpaperFile.exists()) {
+                    Os.link(mWallpaperFile.getCanonicalPath(), imageStage.getCanonicalPath());
+                    fullBackupFile(imageStage, data);
+                }
 
                 // Don't try to store the lock image if we overran our quota last time
-                if (!mQuotaExceeded) {
+                if (mLockWallpaperFile.exists() && !mQuotaExceeded) {
                     Os.link(mLockWallpaperFile.getCanonicalPath(), lockImageStage.getCanonicalPath());
                     fullBackupFile(lockImageStage, data);
                 }
@@ -130,7 +134,7 @@
                 }
             }
         } catch (Exception e) {
-            Slog.e(TAG, "Unable to back up wallpaper: " + e.getMessage());
+            Slog.e(TAG, "Unable to back up wallpaper", e);
         } finally {
             if (DEBUG) {
                 Slog.v(TAG, "Removing backup stage links");
@@ -173,6 +177,9 @@
         final File lockImageStage = new File (filesDir, LOCK_IMAGE_STAGE);
 
         try {
+            // First off, revert to the factory state
+            mWm.clear(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+
             // It is valid for the imagery to be absent; it means that we were not permitted
             // to back up the original image on the source device, or there was no user-supplied
             // wallpaper image present.
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/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 60d3339..7ebc150 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1422,7 +1422,8 @@
         updateTouchExplorationLocked(userState);
         updatePerformGesturesLocked(userState);
         updateEnhancedWebAccessibilityLocked(userState);
-        updateDisplayColorAdjustmentSettingsLocked(userState);
+        updateDisplayDaltonizerLocked(userState);
+        updateDisplayInversionLocked(userState);
         updateMagnificationLocked(userState);
         updateSoftKeyboardShowModeLocked(userState);
         scheduleUpdateInputFilter(userState);
@@ -1539,7 +1540,6 @@
         somethingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
         somethingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
         somethingChanged |= readAutoclickEnabledSettingLocked(userState);
-        somethingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
 
         return somethingChanged;
     }
@@ -1602,18 +1602,6 @@
          return false;
     }
 
-    private boolean readDisplayColorAdjustmentSettingsLocked(UserState userState) {
-        final boolean displayAdjustmentsEnabled = DisplayAdjustmentUtils.hasAdjustments(mContext,
-                userState.mUserId);
-        if (displayAdjustmentsEnabled != userState.mHasDisplayColorAdjustment) {
-            userState.mHasDisplayColorAdjustment = displayAdjustmentsEnabled;
-            return true;
-        }
-        // If display adjustment is enabled, always assume there was a change in
-        // the adjustment settings.
-        return displayAdjustmentsEnabled;
-    }
-
     private boolean readHighTextContrastEnabledSettingLocked(UserState userState) {
         final boolean highTextContrastEnabled = Settings.Secure.getIntForUser(
                 mContext.getContentResolver(),
@@ -1730,8 +1718,12 @@
         return false;
     }
 
-    private void updateDisplayColorAdjustmentSettingsLocked(UserState userState) {
-        DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
+    private void updateDisplayDaltonizerLocked(UserState userState) {
+        DisplayAdjustmentUtils.applyDaltonizerSetting(mContext, userState.mUserId);
+    }
+
+    private void updateDisplayInversionLocked(UserState userState) {
+        DisplayAdjustmentUtils.applyInversionSetting(mContext, userState.mUserId);
     }
 
     private void updateMagnificationLocked(UserState userState) {
@@ -4184,7 +4176,6 @@
         public boolean mIsAutoclickEnabled;
         public boolean mIsPerformGesturesEnabled;
         public boolean mIsFilterKeyEventsEnabled;
-        public boolean mHasDisplayColorAdjustment;
         public boolean mAccessibilityFocusOnlyInActiveWindow;
 
         private Service mUiAutomationService;
@@ -4300,9 +4291,6 @@
         private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
 
-        private final Uri mDisplayColorMatrixUri = Settings.Secure.getUriFor(
-                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
-
         private final Uri mHighTextContrastUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
 
@@ -4334,8 +4322,6 @@
             contentResolver.registerContentObserver(
                     mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
-                    mDisplayColorMatrixUri, false, this, UserHandle.USER_ALL);
-            contentResolver.registerContentObserver(
                     mHighTextContrastUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
                     mAccessibilitySoftKeyboardModeUri, false, this, UserHandle.USER_ALL);
@@ -4377,14 +4363,11 @@
                     if (readEnhancedWebAccessibilityEnabledChangedLocked(userState)) {
                         onUserStateChangedLocked(userState);
                     }
-                } else if (mDisplayInversionEnabledUri.equals(uri)
-                        || mDisplayDaltonizerEnabledUri.equals(uri)
+                } else if (mDisplayDaltonizerEnabledUri.equals(uri)
                         || mDisplayDaltonizerUri.equals(uri)) {
-                    if (readDisplayColorAdjustmentSettingsLocked(userState)) {
-                        updateDisplayColorAdjustmentSettingsLocked(userState);
-                    }
-                } else if (mDisplayColorMatrixUri.equals(uri)) {
-                    updateDisplayColorAdjustmentSettingsLocked(userState);
+                    updateDisplayDaltonizerLocked(userState);
+                } else if (mDisplayInversionEnabledUri.equals(uri)) {
+                    updateDisplayInversionLocked(userState);
                 } else if (mHighTextContrastUri.equals(uri)) {
                     if (readHighTextContrastEnabledSettingLocked(userState)) {
                         onUserStateChangedLocked(userState);
diff --git a/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
index e1f3cd8..1532946 100644
--- a/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
+++ b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
@@ -18,23 +18,23 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.opengl.Matrix;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.util.Slog;
+import android.provider.Settings.Secure;
 import android.view.accessibility.AccessibilityManager;
 
+import com.android.server.LocalServices;
+import com.android.server.display.DisplayTransformManager;
+
 /**
  * Utility methods for performing accessibility display adjustments.
  */
 class DisplayAdjustmentUtils {
-    private static final String LOG_TAG = DisplayAdjustmentUtils.class.getSimpleName();
+
+    /** Default inversion mode for display color correction. */
+    private static final int DEFAULT_DISPLAY_DALTONIZER =
+            AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
 
     /** Matrix and offset used for converting color to gray-scale. */
-    private static final float[] GRAYSCALE_MATRIX = new float[] {
+    private static final float[] MATRIX_GRAYSCALE = new float[] {
         .2126f, .2126f, .2126f, 0,
         .7152f, .7152f, .7152f, 0,
         .0722f, .0722f, .0722f, 0,
@@ -48,150 +48,44 @@
      * represents a non-multiplied addition, see surfaceflinger's ProgramCache
      * for full implementation details.
      */
-    private static final float[] INVERSION_MATRIX_VALUE_ONLY = new float[] {
+    private static final float[] MATRIX_INVERT_COLOR = new float[] {
         0.402f, -0.598f, -0.599f, 0,
        -1.174f, -0.174f, -1.175f, 0,
        -0.228f, -0.228f,  0.772f, 0,
              1,       1,       1, 1
     };
 
-    /** Default inversion mode for display color correction. */
-    private static final int DEFAULT_DISPLAY_DALTONIZER =
-            AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
-
-    /**
-     * Returns whether the specified user with has any display color
-     * adjustments.
-     */
-    public static boolean hasAdjustments(Context context, int userId) {
+    public static void applyDaltonizerSetting(Context context, int userId) {
         final ContentResolver cr = context.getContentResolver();
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
 
-        if (Settings.Secure.getIntForUser(cr,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) != 0) {
-            return true;
+        int daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED;
+        if (Secure.getIntForUser(cr,
+                Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0) {
+            daltonizerMode = Secure.getIntForUser(cr,
+                    Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER, userId);
         }
 
-        if (Settings.Secure.getIntForUser(cr,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0) {
-            return true;
+        float[] grayscaleMatrix = null;
+        if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
+            // Monochromacy isn't supported by the native Daltonizer.
+            grayscaleMatrix = MATRIX_GRAYSCALE;
+            daltonizerMode = AccessibilityManager.DALTONIZER_DISABLED;
         }
-
-        return false;
+        dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, grayscaleMatrix);
+        dtm.setDaltonizerMode(daltonizerMode);
     }
 
     /**
      * Applies the specified user's display color adjustments.
      */
-    public static void applyAdjustments(Context context, int userId) {
+    public static void applyInversionSetting(Context context, int userId) {
         final ContentResolver cr = context.getContentResolver();
-        float[] colorMatrix = null;
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
 
-        if (Settings.Secure.getIntForUser(cr,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) != 0) {
-            colorMatrix = multiply(colorMatrix, INVERSION_MATRIX_VALUE_ONLY);
-        }
-
-        if (Settings.Secure.getIntForUser(cr,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0) {
-            final int daltonizerMode = Settings.Secure.getIntForUser(cr,
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER,
-                    userId);
-            // Monochromacy isn't supported by the native Daltonizer.
-            if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
-                colorMatrix = multiply(colorMatrix, GRAYSCALE_MATRIX);
-                setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
-            } else {
-                setDaltonizerMode(daltonizerMode);
-            }
-        } else {
-            setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
-        }
-
-        String matrix = Settings.Secure.getStringForUser(cr,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, userId);
-        if (matrix != null) {
-            final float[] userMatrix = get4x4Matrix(matrix);
-            if (userMatrix != null) {
-                colorMatrix = multiply(colorMatrix, userMatrix);
-            }
-        }
-
-        setColorTransform(colorMatrix);
+        final boolean invertColors = Secure.getIntForUser(cr,
+                Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) != 0;
+        dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_INVERT_COLOR,
+                invertColors ? MATRIX_INVERT_COLOR : null);
     }
-
-    private static float[] get4x4Matrix(String matrix) {
-        String[] strValues = matrix.split(",");
-        if (strValues.length != 16) {
-            return null;
-        }
-        float[] values = new float[strValues.length];
-        try {
-            for (int i = 0; i < values.length; i++) {
-                values[i] = Float.parseFloat(strValues[i]);
-            }
-        } catch (java.lang.NumberFormatException ex) {
-            return null;
-        }
-        return values;
-    }
-
-    private static float[] multiply(float[] matrix, float[] other) {
-        if (matrix == null) {
-            return other;
-        }
-        float[] result = new float[16];
-        Matrix.multiplyMM(result, 0, matrix, 0, other, 0);
-        return result;
-    }
-
-    /**
-     * Sets the surface flinger's Daltonization mode. This adjusts the color
-     * space to correct for or simulate various types of color blindness.
-     *
-     * @param mode new Daltonization mode
-     */
-    private static void setDaltonizerMode(int mode) {
-        try {
-            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
-            if (flinger != null) {
-                final Parcel data = Parcel.obtain();
-                data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                data.writeInt(mode);
-                flinger.transact(1014, data, null, 0);
-                data.recycle();
-            }
-        } catch (RemoteException ex) {
-            Slog.e(LOG_TAG, "Failed to set Daltonizer mode", ex);
-        }
-    }
-
-    /**
-     * Sets the surface flinger's color transformation as a 4x4 matrix. If the
-     * matrix is null, color transformations are disabled.
-     *
-     * @param m the float array that holds the transformation matrix, or null to
-     *            disable transformation
-     */
-    private static void setColorTransform(float[] m) {
-        try {
-            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
-            if (flinger != null) {
-                final Parcel data = Parcel.obtain();
-                data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                if (m != null) {
-                    data.writeInt(1);
-                    for (int i = 0; i < 16; i++) {
-                        data.writeFloat(m[i]);
-                    }
-                } else {
-                    data.writeInt(0);
-                }
-                flinger.transact(1015, data, null, 0);
-                data.recycle();
-            }
-        } catch (RemoteException ex) {
-            Slog.e(LOG_TAG, "Failed to set color transform", ex);
-        }
-    }
-
 }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5ce8c9e..d10080b 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5707,16 +5707,21 @@
         }
 
         void tearDownPipes() {
-            if (mPipes != null) {
-                try {
-                    mPipes[0].close();
-                    mPipes[0] = null;
-                    mPipes[1].close();
-                    mPipes[1] = null;
-                } catch (IOException e) {
-                    Slog.w(TAG, "Couldn't close agent pipes", e);
+            // Teardown might arise from the inline restore processing or from the asynchronous
+            // timeout mechanism, and these might race.  Make sure we don't try to close and
+            // null out the pipes twice.
+            synchronized (this) {
+                if (mPipes != null) {
+                    try {
+                        mPipes[0].close();
+                        mPipes[0] = null;
+                        mPipes[1].close();
+                        mPipes[1] = null;
+                    } catch (IOException e) {
+                        Slog.w(TAG, "Couldn't close agent pipes", e);
+                    }
+                    mPipes = null;
                 }
-                mPipes = null;
             }
         }
 
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index e28fa73..0cce2a2 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -584,6 +584,18 @@
                         Slog.e(TAG, "Invalid tied profile lock type: " + quality);
                     }
                 }
+                try {
+                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
+                    java.security.KeyStore keyStore =
+                            java.security.KeyStore.getInstance("AndroidKeyStore");
+                    keyStore.load(null);
+                    if (keyStore.containsAlias(alias)) {
+                        keyStore.deleteEntry(alias);
+                    }
+                } catch (KeyStoreException | NoSuchAlgorithmException |
+                        CertificateException | IOException e) {
+                    Slog.e(TAG, "Unable to remove tied profile key", e);
+                }
             }
         } catch (RemoteException re) {
             Slog.e(TAG, "Unable to migrate old data", re);
@@ -1027,37 +1039,38 @@
             KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
             keyGenerator.init(new SecureRandom());
             SecretKey secretKey = keyGenerator.generateKey();
-
             java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
             keyStore.load(null);
-            keyStore.setEntry(
-                    LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
-                    new java.security.KeyStore.SecretKeyEntry(secretKey),
-                    new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
-                            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                            .build());
-            keyStore.setEntry(
-                    LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
-                    new java.security.KeyStore.SecretKeyEntry(secretKey),
-                    new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                            .setUserAuthenticationRequired(true)
-                            .setUserAuthenticationValidityDurationSeconds(30)
-                            .build());
-
-            // Key imported, obtain a reference to it.
-            SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
-                    LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
-            // The original key can now be discarded.
-
-            Cipher cipher = Cipher.getInstance(
-                    KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                            + KeyProperties.ENCRYPTION_PADDING_NONE);
-            cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
-            encryptionResult = cipher.doFinal(randomLockSeed);
-            iv = cipher.getIV();
+            try {
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .build());
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .setUserAuthenticationRequired(true)
+                                .setUserAuthenticationValidityDurationSeconds(30)
+                                .build());
+                // Key imported, obtain a reference to it.
+                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
+                Cipher cipher = Cipher.getInstance(
+                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                                + KeyProperties.ENCRYPTION_PADDING_NONE);
+                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
+                encryptionResult = cipher.doFinal(randomLockSeed);
+                iv = cipher.getIV();
+            } finally {
+                // The original key can now be discarded.
+                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
+            }
         } catch (CertificateException | UnrecoverableKeyException
                 | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
                 | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index eaf317a..7ea8f1f 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -41,6 +41,7 @@
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.os.BackgroundThread;
 
+import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
 
 import java.util.ArrayList;
@@ -240,12 +241,6 @@
         }
         mPinnedCameraFiles.add(pf);
 
-        //find the location of the odex based on the location of the APK
-        int lastPeriod = camAPK.lastIndexOf('.');
-        int lastSlash = camAPK.lastIndexOf('/', lastPeriod);
-        String base = camAPK.substring(0, lastSlash);
-        String appName = camAPK.substring(lastSlash + 1, lastPeriod);
-
         // determine the ABI from either ApplicationInfo or Build
         String arch = "arm";
         if (cameraInfo.primaryCpuAbi != null
@@ -256,8 +251,18 @@
                 arch = arch + "64";
             }
         }
-        String odex = base + "/oat/" + arch + "/" + appName + ".odex";
-        //not all apps have odex files, so not pinning the odex is not a fatal error
+
+        // get the path to the odex or oat file
+        String baseCodePath = cameraInfo.getBaseCodePath();
+        String odex = null;
+        try {
+            odex = DexFile.getDexFileOutputPath(baseCodePath, arch);
+        } catch (IOException ioe) {}
+        if (odex == null) {
+            return true;
+        }
+
+        //not pinning the oat/odex is not a fatal error
         pf = pinFile(odex, 0, 0, MAX_CAMERA_PIN_SIZE);
         if (pf != null) {
             mPinnedCameraFiles.add(pf);
@@ -265,6 +270,7 @@
                 Slog.i(TAG, "Pinned " + pf.mFilename);
             }
         }
+
         return true;
     }
 
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index f7bd04b..577cada 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1225,11 +1225,13 @@
             } finally {
                 db.endTransaction();
             }
-            sendAccountsChangedBroadcast(accounts.userId);
         }
         if (getUserManager().getUserInfo(accounts.userId).canHaveProfile()) {
             addAccountToLinkedRestrictedUsers(account, accounts.userId);
         }
+
+        // Only send LOGIN_ACCOUNTS_CHANGED when the database changed.
+        sendAccountsChangedBroadcast(accounts.userId);
         return true;
     }
 
@@ -1412,7 +1414,6 @@
         synchronized (accounts.cacheLock) {
             final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
             db.beginTransaction();
-            boolean isSuccessful = false;
             Account renamedAccount = new Account(newName, accountToRename.type);
             try {
                 final long accountId = getAccountIdLocked(db, accountToRename);
@@ -1425,54 +1426,51 @@
                     values.put(ACCOUNTS_PREVIOUS_NAME, accountToRename.name);
                     db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
                     db.setTransactionSuccessful();
-                    isSuccessful = true;
                     logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_ACCOUNTS, accountId,
                             accounts);
                 }
             } finally {
                 db.endTransaction();
-                if (isSuccessful) {
-                    /*
-                     * Database transaction was successful. Clean up cached
-                     * data associated with the account in the user profile.
-                     */
-                    insertAccountIntoCacheLocked(accounts, renamedAccount);
-                    /*
-                     * Extract the data and token caches before removing the
-                     * old account to preserve the user data associated with
-                     * the account.
-                     */
-                    HashMap<String, String> tmpData = accounts.userDataCache.get(accountToRename);
-                    HashMap<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
-                    removeAccountFromCacheLocked(accounts, accountToRename);
-                    /*
-                     * Update the cached data associated with the renamed
-                     * account.
-                     */
-                    accounts.userDataCache.put(renamedAccount, tmpData);
-                    accounts.authTokenCache.put(renamedAccount, tmpTokens);
-                    accounts.previousNameCache.put(
-                          renamedAccount,
-                          new AtomicReference<String>(accountToRename.name));
-                    resultAccount = renamedAccount;
+            }
+            /*
+             * Database transaction was successful. Clean up cached
+             * data associated with the account in the user profile.
+             */
+            insertAccountIntoCacheLocked(accounts, renamedAccount);
+            /*
+             * Extract the data and token caches before removing the
+             * old account to preserve the user data associated with
+             * the account.
+             */
+            HashMap<String, String> tmpData = accounts.userDataCache.get(accountToRename);
+            HashMap<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
+            removeAccountFromCacheLocked(accounts, accountToRename);
+            /*
+             * Update the cached data associated with the renamed
+             * account.
+             */
+            accounts.userDataCache.put(renamedAccount, tmpData);
+            accounts.authTokenCache.put(renamedAccount, tmpTokens);
+            accounts.previousNameCache.put(
+                    renamedAccount,
+                    new AtomicReference<String>(accountToRename.name));
+            resultAccount = renamedAccount;
 
-                    int parentUserId = accounts.userId;
-                    if (canHaveProfile(parentUserId)) {
-                        /*
-                         * Owner or system user account was renamed, rename the account for
-                         * those users with which the account was shared.
-                         */
-                        List<UserInfo> users = getUserManager().getUsers(true);
-                        for (UserInfo user : users) {
-                            if (user.isRestricted()
-                                    && (user.restrictedProfileParentId == parentUserId)) {
-                                renameSharedAccountAsUser(accountToRename, newName, user.id);
-                            }
-                        }
+            int parentUserId = accounts.userId;
+            if (canHaveProfile(parentUserId)) {
+                /*
+                 * Owner or system user account was renamed, rename the account for
+                 * those users with which the account was shared.
+                 */
+                List<UserInfo> users = getUserManager().getUsers(true);
+                for (UserInfo user : users) {
+                    if (user.isRestricted()
+                            && (user.restrictedProfileParentId == parentUserId)) {
+                        renameSharedAccountAsUser(accountToRename, newName, user.id);
                     }
-                    sendAccountsChangedBroadcast(accounts.userId);
                 }
             }
+            sendAccountsChangedBroadcast(accounts.userId);
         }
         return resultAccount;
     }
@@ -1653,7 +1651,7 @@
     }
 
     private boolean removeAccountInternal(UserAccounts accounts, Account account, int callingUid) {
-        int deleted;
+        boolean isChanged = false;
         boolean userUnlocked = isLocalUnlockedUser(accounts.userId);
         if (!userUnlocked) {
             Slog.i(TAG, "Removing account " + account + " while user "+ accounts.userId
@@ -1663,25 +1661,38 @@
             final SQLiteDatabase db = userUnlocked
                     ? accounts.openHelper.getWritableDatabaseUserIsUnlocked()
                     : accounts.openHelper.getWritableDatabase();
-            final long accountId = getAccountIdLocked(db, account);
             db.beginTransaction();
+            // Set to a dummy value, this will only be used if the database
+            // transaction succeeds.
+            long accountId = -1;
             try {
-                deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
-                                + "=?", new String[]{account.name, account.type});
-                if (userUnlocked) {
-                    // Delete from CE table
-                    deleted = db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
-                            + "=?", new String[]{account.name, account.type});
+                accountId = getAccountIdLocked(db, account);
+                if (accountId >= 0) {
+                    db.delete(
+                            TABLE_ACCOUNTS,
+                            ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+                            new String[]{ account.name, account.type });
+                    if (userUnlocked) {
+                        // Delete from CE table
+                        db.delete(
+                                CE_TABLE_ACCOUNTS,
+                                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+                                new String[]{ account.name, account.type });
+                    }
+                    db.setTransactionSuccessful();
+                    isChanged = true;
                 }
-                db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
             }
-            removeAccountFromCacheLocked(accounts, account);
-            sendAccountsChangedBroadcast(accounts.userId);
-            String action = userUnlocked ? DebugDbHelper.ACTION_ACCOUNT_REMOVE
-                    : DebugDbHelper.ACTION_ACCOUNT_REMOVE_DE;
-            logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts);
+            if (isChanged) {
+                removeAccountFromCacheLocked(accounts, account);
+                // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occured.
+                sendAccountsChangedBroadcast(accounts.userId);
+                String action = userUnlocked ? DebugDbHelper.ACTION_ACCOUNT_REMOVE
+                        : DebugDbHelper.ACTION_ACCOUNT_REMOVE_DE;
+                logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts);
+            }
         }
         long id = Binder.clearCallingIdentity();
         try {
@@ -1698,7 +1709,7 @@
         } finally {
             Binder.restoreCallingIdentity(id);
         }
-        return (deleted > 0);
+        return isChanged;
     }
 
     @Override
@@ -1922,6 +1933,7 @@
         if (account == null) {
             return;
         }
+        boolean isChanged = false;
         synchronized (accounts.cacheLock) {
             final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
             db.beginTransaction();
@@ -1931,12 +1943,17 @@
                 final long accountId = getAccountIdLocked(db, account);
                 if (accountId >= 0) {
                     final String[] argsAccountId = {String.valueOf(accountId)};
-                    db.update(CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
-                    db.delete(CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
+                    db.update(
+                            CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
+                    db.delete(
+                            CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
                     accounts.authTokenCache.remove(account);
                     accounts.accountTokenCaches.remove(account);
                     db.setTransactionSuccessful();
-
+                    // If there is an account whose password will be updated and the database
+                    // transactions succeed, then we say that a change has occured. Even if the
+                    // new password is the same as the old and there were no authtokens to delete.
+                    isChanged = true;
                     String action = (password == null || password.length() == 0) ?
                             DebugDbHelper.ACTION_CLEAR_PASSWORD
                             : DebugDbHelper.ACTION_SET_PASSWORD;
@@ -1944,8 +1961,11 @@
                 }
             } finally {
                 db.endTransaction();
+                if (isChanged) {
+                    // Send LOGIN_ACCOUNTS_CHANGED only if the something changed.
+                    sendAccountsChangedBroadcast(accounts.userId);
+                }
             }
-            sendAccountsChangedBroadcast(accounts.userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4762a67..8716811 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -140,7 +140,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.UserInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -644,30 +643,41 @@
         return mShowDialogs && !mSleeping && !mShuttingDown;
     }
 
-    // it's a semaphore; boost when 0->1, reset when 1->0
-    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
-        @Override protected Integer initialValue() {
-            return 0;
+    private static final class PriorityState {
+        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
+        // the current thread is currently in. When it drops down to zero, we will no longer boost
+        // the thread's priority.
+        private int regionCounter = 0;
+
+        // The thread's previous priority before boosting.
+        private int prevPriority = Integer.MIN_VALUE;
+    }
+
+    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
+        @Override protected PriorityState initialValue() {
+            return new PriorityState();
         }
     };
 
     static void boostPriorityForLockedSection() {
-        if (sIsBoosted.get() == 0) {
-            // boost to prio 118 while holding a global lock
-            Process.setThreadPriority(Process.myTid(), -2);
-            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
+        int tid = Process.myTid();
+        int prevPriority = Process.getThreadPriority(tid);
+        PriorityState state = sThreadPriorityState.get();
+        if (state.regionCounter == 0 && prevPriority > -2) {
+            state.prevPriority = prevPriority;
+            Process.setThreadPriority(tid, -2);
         }
-        int cur = sIsBoosted.get();
-        sIsBoosted.set(cur + 1);
+        state.regionCounter++;
     }
 
     static void resetPriorityAfterLockedSection() {
-        sIsBoosted.set(sIsBoosted.get() - 1);
-        if (sIsBoosted.get() == 0) {
-            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
-            Process.setThreadPriority(Process.myTid(), 0);
+        PriorityState state = sThreadPriorityState.get();
+        state.regionCounter--;
+        if (state.regionCounter == 0 && state.prevPriority > -2) {
+            Process.setThreadPriority(Process.myTid(), state.prevPriority);
         }
     }
+
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
         public final Bundle extras;
@@ -12042,6 +12052,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: "
@@ -18862,15 +18875,6 @@
                         null, AppOpsManager.OP_NONE, null, false, false,
                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
-                    // Tell the shortcut manager that the system locale changed.  It needs to know
-                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
-                    // we "push" from here, rather than having the service listen to the broadcast.
-                    final ShortcutServiceInternal shortcutService =
-                            LocalServices.getService(ShortcutServiceInternal.class);
-                    if (shortcutService != null) {
-                        shortcutService.onSystemLocaleChangedNoLock();
-                    }
-
                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                     if (!mProcessesReady) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a4fc251..c16fc62 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3074,7 +3074,7 @@
         final boolean nowVisible = allResumedActivitiesVisible();
         for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
             ActivityRecord s = mStoppingActivities.get(activityNdx);
-            final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
+            boolean waitingVisible = mWaitingVisibleActivities.contains(s);
             if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
                     + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
             if (waitingVisible && nowVisible) {
@@ -3087,6 +3087,7 @@
                     // hidden by the activities in front of it.
                     if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
                     mWindowManager.setAppVisibility(s.appToken, false);
+                    waitingVisible = false;
                 }
             }
             if ((!waitingVisible || mService.isSleepingOrShuttingDownLocked()) && remove) {
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..b6c8d5d 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -450,8 +450,6 @@
 
     private int setWifiTethering(final boolean enable) {
         synchronized (mPublicSync) {
-            // Note that we're maintaining a predicate that mWifiTetherRequested always matches
-            // our last request to WifiManager re: its AP enabled status.
             mWifiTetherRequested = enable;
             final WifiManager wifiManager =
                     (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
@@ -591,13 +589,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);
@@ -794,10 +792,6 @@
                 }
             } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
                 synchronized (Tethering.this.mPublicSync) {
-                    if (!mWifiTetherRequested) {
-                        // We only care when we're trying to tether via our WiFi interface.
-                        return;
-                    }
                     int curState =  intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
                             WifiManager.WIFI_AP_STATE_DISABLED);
                     switch (curState) {
@@ -805,8 +799,10 @@
                             // We can see this state on the way to both enabled and failure states.
                             break;
                         case WifiManager.WIFI_AP_STATE_ENABLED:
-                            // Tell an appropriate interface state machine that it should tether.
-                            tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_WIFI);
+                            // When the AP comes up and we've been requested to tether it, do so.
+                            if (mWifiTetherRequested) {
+                                tetherMatchingInterfaces(true, ConnectivityManager.TETHERING_WIFI);
+                            }
                             break;
                         case WifiManager.WIFI_AP_STATE_DISABLED:
                         case WifiManager.WIFI_AP_STATE_DISABLING:
@@ -816,10 +812,20 @@
                                 Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" +
                                     curState);
                             }
-                            // Tell an appropriate interface state machine that
-                            // it needs to tear itself down.
-                            tetherMatchingInterfaces(false, ConnectivityManager.TETHERING_WIFI);
-                            setWifiTethering(false);
+                            // Tell appropriate interface state machines that they should tear
+                            // themselves down.
+                            for (int i = 0; i < mTetherStates.size(); i++) {
+                                TetherInterfaceStateMachine tism =
+                                        mTetherStates.valueAt(i).mStateMachine;
+                                if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
+                                    tism.sendMessage(
+                                            TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
+                                    break;  // There should be at most one of these.
+                                }
+                            }
+                            // Regardless of whether we requested this transition, the AP has gone
+                            // down.  Don't try to tether again unless we're requested to do so.
+                            mWifiTetherRequested = false;
                             break;
                     }
                 }
@@ -1018,15 +1024,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 +1065,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 +1104,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 +1219,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 +1376,7 @@
             }
 
             protected void chooseUpstreamType(boolean tryCell) {
+                final ConnectivityManager cm = getConnectivityManager();
                 int upType = ConnectivityManager.TYPE_NONE;
                 String iface = null;
 
@@ -1292,8 +1391,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 +1432,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 +1451,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 +1459,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 +1498,10 @@
                             ifaceName);
                 }
             }
+
+            protected void handleNewUpstreamNetworkState(NetworkState ns) {
+                mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
+            }
         }
 
         private final AtomicInteger mSimBcastGenerationNumber = new AtomicInteger(0);
@@ -1582,24 +1691,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/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6a6570b..fec7ed1 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -244,6 +244,7 @@
         publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
                 true /*allowIsolated*/);
         publishLocalService(DisplayManagerInternal.class, new LocalService());
+        publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
new file mode 100644
index 0000000..cfeae7b
--- /dev/null
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -0,0 +1,175 @@
+/*
+ * 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.display;
+
+import android.opengl.Matrix;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+import android.util.SparseArray;
+
+/**
+ * Manager for applying color transformations to the display.
+ */
+public class DisplayTransformManager {
+
+    private static final String TAG = "DisplayTransformManager";
+
+    /**
+     * Color transform level used by Night display to tint the display red.
+     */
+    public static final int LEVEL_COLOR_MATRIX_NIGHT_DISPLAY = 100;
+    /**
+     * Color transform level used by A11y services to make the display monochromatic.
+     */
+    public static final int LEVEL_COLOR_MATRIX_GRAYSCALE = 200;
+    /**
+     * Color transform level used by A11y services to invert the display colors.
+     */
+    public static final int LEVEL_COLOR_MATRIX_INVERT_COLOR = 300;
+
+    private final SparseArray<float[]> mColorMatrix = new SparseArray<>(3);
+
+    private int mDaltonizerMode = -1;
+
+    /* package */ DisplayTransformManager() {
+    }
+
+    /**
+     * Returns the color transform matrix set for a given level.
+     */
+    public float[] getColorMatrix(int key) {
+        synchronized (mColorMatrix) {
+            return mColorMatrix.get(key);
+        }
+    }
+
+    /**
+     * Sets and applies a current color transform matrix for a given level.
+     * <p>
+     * Note: all color transforms are first composed to a single matrix in ascending order based
+     * on level before being applied to the display.
+     *
+     * @param key   the level used to identify and compose the color transform (low -> high)
+     * @param value the 4x4 color transform matrix (in column-major order), or {@code null} to
+     *              remove the color transform matrix associated with the provided level
+     */
+    public void setColorMatrix(int key, float[] value) {
+        if (value != null && value.length != 16) {
+            throw new IllegalArgumentException("Expected length: 16 (4x4 matrix)"
+                    + ", actual length: " + value.length);
+        }
+
+        synchronized (mColorMatrix) {
+            if (value != null) {
+                mColorMatrix.put(key, value);
+            } else {
+                mColorMatrix.remove(key);
+            }
+
+            // Update the current color transform.
+            applyColorMatrix(computeColorMatrix());
+        }
+    }
+
+    /**
+     * Returns the composition of all current color matrices, or {@code null} if there are none.
+     */
+    private float[] computeColorMatrix() {
+        synchronized (mColorMatrix) {
+            final int count = mColorMatrix.size();
+            if (count == 0) {
+                return null;
+            }
+
+            final float[][] result = new float[2][16];
+            Matrix.setIdentityM(result[0], 0);
+            for (int i = 0; i < count; i++) {
+                float[] rhs = mColorMatrix.valueAt(i);
+                Matrix.multiplyMM(result[(i + 1) % 2], 0, result[i % 2], 0, rhs, 0);
+            }
+            return result[count % 2];
+        }
+    }
+
+    /**
+     * Returns the current Daltonization mode.
+     */
+    public int getDaltonizerMode() {
+        return mDaltonizerMode;
+    }
+
+    /**
+     * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate
+     * various types of color blindness.
+     *
+     * @param mode the new Daltonization mode, or -1 to disable
+     */
+    public void setDaltonizerMode(int mode) {
+        if (mDaltonizerMode != mode) {
+            mDaltonizerMode = mode;
+            applyDaltonizerMode(mode);
+        }
+    }
+
+    /**
+     * Propagates the provided color transformation matrix to the SurfaceFlinger.
+     */
+    private static void applyColorMatrix(float[] m) {
+        final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+        if (flinger != null) {
+            final Parcel data = Parcel.obtain();
+            data.writeInterfaceToken("android.ui.ISurfaceComposer");
+            if (m != null) {
+                data.writeInt(1);
+                for (int i = 0; i < 16; i++) {
+                    data.writeFloat(m[i]);
+                }
+            } else {
+                data.writeInt(0);
+            }
+            try {
+                flinger.transact(1015, data, null, 0);
+            } catch (RemoteException ex) {
+                Slog.e(TAG, "Failed to set color transform", ex);
+            } finally {
+                data.recycle();
+            }
+        }
+    }
+
+    /**
+     * Propagates the provided Daltonization mode to the SurfaceFlinger.
+     */
+    private static void applyDaltonizerMode(int mode) {
+        final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+        if (flinger != null) {
+            final Parcel data = Parcel.obtain();
+            data.writeInterfaceToken("android.ui.ISurfaceComposer");
+            data.writeInt(mode);
+            try {
+                flinger.transact(1014, data, null, 0);
+            } catch (RemoteException ex) {
+                Slog.e(TAG, "Failed to set Daltonizer mode", ex);
+            } finally {
+                data.recycle();
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index 27abd1e..1f4ee9b 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -22,6 +22,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -47,11 +49,19 @@
     private static final boolean DEBUG = false;
 
     /**
-     * Night mode ~= 3400 K.
+     * Night display ~= 3400 K.
      */
-    private static final String MATRIX_NIGHT = "1,0,0,0,0,.754,0,0,0,0,.516,0,0,0,0,1";
+    private static final float[] MATRIX_NIGHT = new float[] {
+        1,      0,      0, 0,
+        0, 0.754f,      0, 0,
+        0,      0, 0.516f, 0,
+        0,      0,      0, 1
+    };
+
+    private final Handler mHandler;
 
     private int mCurrentUser = UserHandle.USER_NULL;
+    private ContentObserver mUserSetupObserver;
     private boolean mBootCompleted;
 
     private NightDisplayController mController;
@@ -60,6 +70,7 @@
 
     public NightDisplayService(Context context) {
         super(context);
+        mHandler = new Handler(Looper.getMainLooper());
     }
 
     @Override
@@ -68,15 +79,23 @@
     }
 
     @Override
+    public void onBootPhase(int phase) {
+        if (phase == PHASE_BOOT_COMPLETED) {
+            mBootCompleted = true;
+
+            // Register listeners now that boot is complete.
+            if (mCurrentUser != UserHandle.USER_NULL && mUserSetupObserver == null) {
+                setUp();
+            }
+        }
+    }
+
+    @Override
     public void onStartUser(int userHandle) {
         super.onStartUser(userHandle);
 
-        // Register listeners for the new user.
         if (mCurrentUser == UserHandle.USER_NULL) {
-            mCurrentUser = userHandle;
-            if (mBootCompleted) {
-                setUpNightMode();
-            }
+            onUserChanged(userHandle);
         }
     }
 
@@ -84,44 +103,60 @@
     public void onSwitchUser(int userHandle) {
         super.onSwitchUser(userHandle);
 
-        // Unregister listeners for the old user.
-        if (mBootCompleted && mCurrentUser != UserHandle.USER_NULL) {
-            tearDownNightMode();
-        }
-
-        // Register listeners for the new user.
-        mCurrentUser = userHandle;
-        if (mBootCompleted) {
-            setUpNightMode();
-        }
+        onUserChanged(userHandle);
     }
 
     @Override
     public void onStopUser(int userHandle) {
         super.onStopUser(userHandle);
 
-        // Unregister listeners for the old user.
         if (mCurrentUser == userHandle) {
-            if (mBootCompleted) {
-                tearDownNightMode();
-            }
-            mCurrentUser = UserHandle.USER_NULL;
+            onUserChanged(UserHandle.USER_NULL);
         }
     }
 
-    @Override
-    public void onBootPhase(int phase) {
-        if (phase == PHASE_BOOT_COMPLETED) {
-            mBootCompleted = true;
+    private void onUserChanged(int userHandle) {
+        final ContentResolver cr = getContext().getContentResolver();
 
-            // Register listeners now that boot is complete.
-            if (mCurrentUser != UserHandle.USER_NULL) {
-                setUpNightMode();
+        if (mCurrentUser != UserHandle.USER_NULL) {
+            if (mUserSetupObserver != null) {
+                cr.unregisterContentObserver(mUserSetupObserver);
+                mUserSetupObserver = null;
+            } else if (mBootCompleted) {
+                tearDown();
+            }
+        }
+
+        mCurrentUser = userHandle;
+
+        if (mCurrentUser != UserHandle.USER_NULL) {
+            if (!isUserSetupCompleted(cr, mCurrentUser)) {
+                mUserSetupObserver = new ContentObserver(mHandler) {
+                    @Override
+                    public void onChange(boolean selfChange, Uri uri) {
+                        if (isUserSetupCompleted(cr, mCurrentUser)) {
+                            cr.unregisterContentObserver(this);
+                            mUserSetupObserver = null;
+
+                            if (mBootCompleted) {
+                                setUp();
+                            }
+                        }
+                    }
+                };
+                cr.registerContentObserver(Secure.getUriFor(Secure.USER_SETUP_COMPLETE),
+                        false /* notifyForDescendents */, mUserSetupObserver, mCurrentUser);
+            } else if (mBootCompleted) {
+                setUp();
             }
         }
     }
 
-    private void setUpNightMode() {
+    private static boolean isUserSetupCompleted(ContentResolver cr, int userHandle) {
+        return Secure.getIntForUser(cr, Secure.USER_SETUP_COMPLETE, 0, userHandle) == 1;
+    }
+
+    private void setUp() {
         // Create a new controller for the current user and start listening for changes.
         mController = new NightDisplayController(getContext(), mCurrentUser);
         mController.setListener(this);
@@ -135,8 +170,11 @@
         }
     }
 
-    private void tearDownNightMode() {
-        mController.setListener(null);
+    private void tearDown() {
+        if (mController != null) {
+            mController.setListener(null);
+            mController = null;
+        }
 
         if (mAutoMode != null) {
             mAutoMode.onStop();
@@ -144,7 +182,6 @@
         }
 
         mIsActivated = null;
-        mController = null;
     }
 
     @Override
@@ -159,9 +196,9 @@
             }
 
             // Update the current color matrix.
-            final ContentResolver cr = getContext().getContentResolver();
-            Secure.putStringForUser(cr, Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX,
-                    activated ? MATRIX_NIGHT : null, mCurrentUser);
+            final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+            dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY,
+                    activated ? MATRIX_NIGHT : null);
         }
     }
 
@@ -319,13 +356,11 @@
     private class TwilightAutoMode extends AutoMode implements TwilightListener {
 
         private final TwilightManager mTwilightManager;
-        private final Handler mHandler;
 
         private boolean mIsNight;
 
         public TwilightAutoMode() {
             mTwilightManager = getLocalService(TwilightManager.class);
-            mHandler = new Handler(Looper.getMainLooper());
         }
 
         private void updateActivated() {
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 8589de1..8f212db 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -1556,6 +1556,11 @@
                 }
             }
 
+            if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
+                getContext().enforceCallingOrSelfPermission(
+                        android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG);
+            }
+
             long ident = Binder.clearCallingIdentity();
             try {
                 return JobSchedulerService.this.schedule(job, uid);
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 552c990..0947554 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -486,6 +486,7 @@
                 + ":[" + job.getService()
                 + ",jId=" + job.getId()
                 + ",u" + getUserId()
+                + ",suid=" + getSourceUid()
                 + ",R=(" + formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME)
                 + "," + formatRunTime(latestRunTimeElapsedMillis, NO_LATEST_RUNTIME) + ")"
                 + ",N=" + job.getNetworkType() + ",C=" + job.isRequireCharging()
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/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ec77daf..8d19a24 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1851,7 +1851,7 @@
             enforceSystemOrSystemUIOrVolume("INotificationManager.setZenMode");
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(mode, conditionId, reason);
+                mZenModeHelper.setManualZenMode(mode, conditionId, null, reason);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1928,7 +1928,7 @@
             if (zen == -1) throw new IllegalArgumentException("Invalid filter: " + filter);
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(zen, null, "setInterruptionFilter");
+                mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter");
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 6864ed8..8c9dc3b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -54,7 +54,6 @@
 import android.service.notification.ZenModeConfig.EventInfo;
 import android.service.notification.ZenModeConfig.ScheduleInfo;
 import android.service.notification.ZenModeConfig.ZenRule;
-import android.text.TextUtils;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.util.SparseArray;
@@ -229,7 +228,7 @@
     public void requestFromListener(ComponentName name, int filter) {
         final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
         if (newZen != -1) {
-            setManualZenMode(newZen, null,
+            setManualZenMode(newZen, null, name != null ? name.getPackageName() : null,
                     "listener:" + (name != null ? name.flattenToShortString() : null));
         }
     }
@@ -452,11 +451,11 @@
                 rule.creationTime);
     }
 
-    public void setManualZenMode(int zenMode, Uri conditionId, String reason) {
-        setManualZenMode(zenMode, conditionId, reason, true /*setRingerMode*/);
+    public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
+        setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/);
     }
 
-    private void setManualZenMode(int zenMode, Uri conditionId, String reason,
+    private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
             boolean setRingerMode) {
         ZenModeConfig newConfig;
         synchronized (mConfig) {
@@ -478,6 +477,7 @@
                 newRule.enabled = true;
                 newRule.zenMode = zenMode;
                 newRule.conditionId = conditionId;
+                newRule.enabler = caller;
                 newConfig.manualRule = newRule;
             }
             setConfigLocked(newConfig, reason, setRingerMode);
@@ -950,7 +950,8 @@
                     break;
             }
             if (newZen != -1) {
-                setManualZenMode(newZen, null, "ringerModeInternal", false /*setRingerMode*/);
+                setManualZenMode(newZen, null, "ringerModeInternal", null,
+                        false /*setRingerMode*/);
             }
 
             if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
@@ -988,7 +989,8 @@
                     break;
             }
             if (newZen != -1) {
-                setManualZenMode(newZen, null, "ringerModeExternal", false /*setRingerMode*/);
+                setManualZenMode(newZen, null, "ringerModeExternal", caller,
+                        false /*setRingerMode*/);
             }
 
             ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller,
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/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b94d0f0..3c18198 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -34,6 +34,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.server.pm.ShortcutService.ShortcutOperation;
+import com.android.server.pm.ShortcutService.Stats;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -437,8 +438,6 @@
      * locale changes.
      */
     public int getApiCallCount() {
-        mShortcutUser.resetThrottlingIfNeeded();
-
         final ShortcutService s = mShortcutUser.mService;
 
         // Reset the counter if:
@@ -598,7 +597,37 @@
     }
 
     /**
-     * Called when the package is updated or added.
+     * @return false if any of the target activities are no longer enabled.
+     */
+    private boolean areAllActivitiesStillEnabled() {
+        if (mShortcuts.size() == 0) {
+            return true;
+        }
+        final ShortcutService s = mShortcutUser.mService;
+
+        // Normally the number of target activities is 1 or so, so no need to use a complex
+        // structure like a set.
+        final ArrayList<ComponentName> checked = new ArrayList<>(4);
+
+        for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+            final ShortcutInfo si = mShortcuts.valueAt(i);
+            final ComponentName activity = si.getActivity();
+
+            if (checked.contains(activity)) {
+                continue; // Already checked.
+            }
+            checked.add(activity);
+
+            if (!s.injectIsActivityEnabledAndExported(activity, getOwnerUserId())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Called when the package may be added or updated, or its activities may be disabled, and
+     * if so, rescan the package and do the necessary stuff.
      *
      * Add case:
      * - Publish manifest shortcuts.
@@ -606,23 +635,35 @@
      * Update case:
      * - Re-publish manifest shortcuts.
      * - If there are shortcuts with resources (icons or strings), update their timestamps.
+     * - Disable shortcuts whose target activities are disabled.
      *
      * @return TRUE if any shortcuts have been changed.
      */
-    public boolean handlePackageAddedOrUpdated(boolean isNewApp, boolean forceRescan) {
-        final PackageInfo pi = mShortcutUser.mService.getPackageInfo(
-                getPackageName(), getPackageUserId());
-        if (pi == null) {
-            return false; // Shouldn't happen.
-        }
+    public boolean rescanPackageIfNeeded(boolean isNewApp, boolean forceRescan) {
+        final ShortcutService s = mShortcutUser.mService;
+        final long start = s.injectElapsedRealtime();
 
-        if (!isNewApp && !forceRescan) {
-            // Make sure the version code or last update time has changed.
-            // Otherwise, nothing to do.
-            if (getPackageInfo().getVersionCode() >= pi.versionCode
-                    && getPackageInfo().getLastUpdateTime() >= pi.lastUpdateTime) {
-                return false;
+        final PackageInfo pi;
+        try {
+            pi = mShortcutUser.mService.getPackageInfo(
+                    getPackageName(), getPackageUserId());
+            if (pi == null) {
+                return false; // Shouldn't happen.
             }
+
+            if (!isNewApp && !forceRescan) {
+                // Return if the package hasn't changed, ie:
+                // - version code hasn't change
+                // - lastUpdateTime hasn't change
+                // - all target activities are still enabled.
+                if ((getPackageInfo().getVersionCode() >= pi.versionCode)
+                        && (getPackageInfo().getLastUpdateTime() >= pi.lastUpdateTime)
+                        && areAllActivitiesStillEnabled()) {
+                    return false;
+                }
+            }
+        } finally {
+            s.logDurationStat(Stats.PACKAGE_UPDATE_CHECK, start);
         }
 
         // Now prepare to publish manifest shortcuts.
@@ -654,8 +695,6 @@
 
         getPackageInfo().updateVersionInfo(pi);
 
-        final ShortcutService s = mShortcutUser.mService;
-
         boolean changed = false;
 
         // For existing shortcuts, update timestamps if they have any resources.
@@ -1001,7 +1040,7 @@
             }
         }
         if (changed) {
-            s.scheduleSaveUser(getPackageUserId());
+            s.packageShortcutsChanged(getPackageName(), getPackageUserId());
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index 757dd19..26b52e9 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -48,6 +48,10 @@
         mPackageInfo = Preconditions.checkNotNull(packageInfo);
     }
 
+    public ShortcutUser getUser() {
+        return mShortcutUser;
+    }
+
     /**
      * ID of the user who actually has this package running on.  For {@link ShortcutPackage},
      * this is the same thing as {@link #getOwnerUserId}, but if it's a {@link ShortcutLauncher} and
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..4286cd9 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -24,9 +24,11 @@
 import android.app.AppGlobals;
 import android.app.IUidObserver;
 import android.app.usage.UsageStatsManagerInternal;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
@@ -54,6 +56,7 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
+import android.os.LocaleList;
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
@@ -82,6 +85,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;
@@ -116,7 +120,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
@@ -176,7 +179,6 @@
 
     private static final String TAG_ROOT = "root";
     private static final String TAG_LAST_RESET_TIME = "last_reset_time";
-    private static final String TAG_LOCALE_CHANGE_SEQUENCE_NUMBER = "locale_seq_no";
 
     private static final String ATTR_VALUE = "value";
 
@@ -289,20 +291,8 @@
     @GuardedBy("mLock")
     private List<Integer> mDirtyUserIds = new ArrayList<>();
 
-    /**
-     * A counter that increments every time the system locale changes.  We keep track of it to
-     * reset
-     * throttling counters on the first call from each package after the last locale change.
-     *
-     * We need this mechanism because we can't do much in the locale change callback, which is
-     * {@link ShortcutServiceInternal#onSystemLocaleChangedNoLock()}.
-     */
-    private final AtomicLong mLocaleChangeSequenceNumber = new AtomicLong();
-
     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
@@ -325,8 +315,9 @@
         int GET_LAUNCHER_ACTIVITY = 11;
         int CHECK_LAUNCHER_ACTIVITY = 12;
         int IS_ACTIVITY_ENABLED = 13;
+        int PACKAGE_UPDATE_CHECK = 14;
 
-        int COUNT = IS_ACTIVITY_ENABLED + 1;
+        int COUNT = PACKAGE_UPDATE_CHECK + 1;
     }
 
     final Object mStatLock = new Object();
@@ -376,41 +367,34 @@
         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.
         }
 
+        // Register receivers.
+
+        // We need to set a priority, so let's just not use PackageMonitor for now.
+        // TODO Refactor PackageMonitor to support priorities.
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
+        packageFilter.addDataScheme("package");
+        packageFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiverAsUser(mPackageMonitor, UserHandle.ALL,
+                packageFilter, null, mHandler);
+
+        final IntentFilter localeFilter = new IntentFilter();
+        localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
+        localeFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL,
+                localeFilter, null, mHandler);
+
         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]++;
@@ -418,8 +402,9 @@
         }
     }
 
-    public long getLocaleChangeSequenceNumber() {
-        return mLocaleChangeSequenceNumber.get();
+    public String injectGetLocaleTagsForUser(@UserIdInt int userId) {
+        // TODO This should get the per-user locale.  b/30123329 b/30119489
+        return LocaleList.getDefault().toLanguageTags();
     }
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@@ -528,8 +513,11 @@
             Slog.d(TAG, "handleUnlockUser: user=" + userId);
         }
         synchronized (mLock) {
-            // Preload
-            getUserShortcutsLocked(userId);
+            // Preload the user's shortcuts.
+            // Also see if the locale has changed.
+            // Note as of nyc, the locale is per-user, so the locale shouldn't change
+            // when the user is locked.  However due to b/30119489 it still happens.
+            getUserShortcutsLocked(userId).detectLocaleChange();
 
             checkPackageChanges(userId);
         }
@@ -775,8 +763,6 @@
 
             // Body.
             writeTagValue(out, TAG_LAST_RESET_TIME, mRawLastResetTime);
-            writeTagValue(out, TAG_LOCALE_CHANGE_SEQUENCE_NUMBER,
-                    mLocaleChangeSequenceNumber.get());
 
             // Epilogue.
             out.endTag(null, TAG_ROOT);
@@ -821,9 +807,6 @@
                     case TAG_LAST_RESET_TIME:
                         mRawLastResetTime = parseLongAttribute(parser, ATTR_VALUE);
                         break;
-                    case TAG_LOCALE_CHANGE_SEQUENCE_NUMBER:
-                        mLocaleChangeSequenceNumber.set(parseLongAttribute(parser, ATTR_VALUE));
-                        break;
                     default:
                         Slog.e(TAG, "Invalid tag: " + tag);
                         break;
@@ -1468,6 +1451,10 @@
                     shortcut.getPackage().equals(shortcut.getActivity().getPackageName()),
                     "Cannot publish shortcut: activity " + shortcut.getActivity() + " does not"
                     + " belong to package " + shortcut.getPackage());
+            Preconditions.checkState(
+                    injectIsMainActivity(shortcut.getActivity(), shortcut.getUserId()),
+                    "Cannot publish shortcut: activity " + shortcut.getActivity() + " is not"
+                            + " main activity");
         }
 
         if (!forUpdate) {
@@ -1516,13 +1503,12 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
 
@@ -1567,13 +1553,12 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
 
@@ -1647,13 +1632,12 @@
             @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
         final int size = newShortcuts.size();
 
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
 
@@ -1699,10 +1683,9 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
 
@@ -1728,10 +1711,9 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
 
@@ -1750,10 +1732,9 @@
         verifyCaller(packageName, userId);
         Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
 
             ps.ensureImmutableShortcutsNotIncludedWithIds((List<String>) shortcutIds);
 
@@ -1774,10 +1755,10 @@
     public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
-            getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts();
+            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
+            ps.deleteAllDynamicShortcuts();
         }
         packageShortcutsChanged(packageName, userId);
 
@@ -1788,9 +1769,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 +1780,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 +1791,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,
@@ -1831,7 +1803,9 @@
 
         final ArrayList<ShortcutInfo> ret = new ArrayList<>();
 
-        getPackageShortcutsLocked(packageName, userId).findAll(ret, query, cloneFlags);
+        final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+        ps.getUser().onCalledByPublisher(packageName);
+        ps.findAll(ret, query, cloneFlags);
 
         return new ParceledListSlice<>(ret);
     }
@@ -1848,11 +1822,10 @@
     public int getRemainingCallCount(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
-            return mMaxUpdatesPerInterval
-                    - getPackageShortcutsLocked(packageName, userId).getApiCallCount();
+            final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
+            return mMaxUpdatesPerInterval - ps.getApiCallCount();
         }
     }
 
@@ -1860,8 +1833,6 @@
     public long getRateLimitResetTime(String packageName, @UserIdInt int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         synchronized (mLock) {
             return getNextResetTimeLocked();
         }
@@ -1880,8 +1851,6 @@
     public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
         verifyCaller(packageName, userId);
 
-        mPendingTasks.waitOnAllTasks();
-
         Preconditions.checkNotNull(shortcutId);
 
         if (DEBUG) {
@@ -1891,6 +1860,8 @@
 
         synchronized (mLock) {
             final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
+            ps.getUser().onCalledByPublisher(packageName);
+
             if (ps.findShortcutById(shortcutId) == null) {
                 Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s",
                         packageName, shortcutId));
@@ -1914,8 +1885,6 @@
     public void resetThrottling() {
         enforceSystemOrShell();
 
-        mPendingTasks.waitOnAllTasks();
-
         resetThrottlingInner(getCallingUserId());
     }
 
@@ -1948,9 +1917,6 @@
         if (DEBUG) {
             Slog.d(TAG, "onApplicationActive: package=" + packageName + "  userid=" + userId);
         }
-
-        mPendingTasks.waitOnAllTasks();
-
         enforceResetThrottlingPermission();
         resetPackageThrottling(packageName, userId);
     }
@@ -2093,7 +2059,7 @@
         if (appStillExists && (packageUserId == owningUserId)) {
             // This will do the notification and save when needed, so do it after the above
             // notifyListeners.
-            user.handlePackageAddedOrUpdated(packageName, /* forceRescan=*/ true);
+            user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
         }
 
         if (!wasUserLoaded) {
@@ -2113,14 +2079,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 +2157,6 @@
             Preconditions.checkStringNotEmpty(packageName, "packageName");
             Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2238,8 +2194,6 @@
             Preconditions.checkStringNotEmpty(packageName, "packageName");
             Preconditions.checkNotNull(shortcutIds, "shortcutIds");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 final ShortcutLauncher launcher =
                         getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
@@ -2260,8 +2214,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 +2244,6 @@
             Preconditions.checkNotNull(packageName, "packageName");
             Preconditions.checkNotNull(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2318,8 +2268,6 @@
             Preconditions.checkNotNull(packageName, "packageName");
             Preconditions.checkNotNull(shortcutId, "shortcutId");
 
-            mPendingTasks.waitOnAllTasks();
-
             synchronized (mLock) {
                 getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
                         .attemptToRestoreIfNeededAndSave();
@@ -2354,46 +2302,20 @@
                 @NonNull String callingPackage) {
             return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId);
         }
-
-        /**
-         * Called by AM when the system locale changes *within the AM lock.  ABSOLUTELY do not take
-         * any locks in this method.
-         */
-        @Override
-        public void onSystemLocaleChangedNoLock() {
-            // DO NOT HOLD ANY LOCKS HERE.
-
-            // We want to reset throttling for all packages for all users.  But we can't just do so
-            // here because:
-            // - We can't load/save users that are locked.
-            // - Even for loaded users, resetting the counters would require us to hold mLock.
-            //
-            // So we use a "pull" model instead.  In here, we just increment the "locale change
-            // sequence number".  Each ShortcutUser has the "last known locale change sequence".
-            //
-            // This allows ShortcutUser's to detect the system locale change, so they can reset
-            // counters.
-
-            // Ignore all callback during system boot.
-            if (mBootCompleted.get()) {
-                mLocaleChangeSequenceNumber.incrementAndGet();
-                if (DEBUG) {
-                    Slog.d(TAG, "onSystemLocaleChangedNoLock: " + mLocaleChangeSequenceNumber.get());
-                }
-                mPendingTasks.addTask(() -> handleLocaleChanged());
-            }
-        }
-
-        @Override
-        public void onPackageBroadcast(Intent intent) {
-            if (DEBUG) {
-                Slog.d(TAG, "onPackageBroadcast");
-            }
-            mPendingTasks.addTask(() -> ShortcutService.this.onPackageBroadcast(
-                    new Intent(intent)));
-        }
     }
 
+    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!mBootCompleted.get()) {
+                return; // Boot not completed, ignore the broadcast.
+            }
+            if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+                handleLocaleChanged();
+            }
+        }
+    };
+
     void handleLocaleChanged() {
         if (DEBUG) {
             Slog.d(TAG, "handleLocaleChanged");
@@ -2402,55 +2324,76 @@
 
         final long token = injectClearCallingIdentity();
         try {
-            forEachLoadedUserLocked(u -> u.forAllPackages(p -> p.resolveResourceStrings()));
+            forEachLoadedUserLocked(user -> user.detectLocaleChange());
         } finally {
             injectRestoreCallingIdentity(token);
         }
     }
 
-    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;
-        }
-
-        final String action = intent.getAction();
-
-        if (!mUserManager.isUserUnlocked(userId)) {
-            if (DEBUG) {
-                Slog.d(TAG, "Ignoring package broadcast " + action + " for locked/stopped user "
-                        + userId);
+    /**
+     * Package event callbacks.
+     */
+    @VisibleForTesting
+    final BroadcastReceiver mPackageMonitor = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, 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;
             }
-            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;
-        }
+            final String action = intent.getAction();
 
-        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+            // This is normally called on Handler, so clearCallingIdentity() isn't needed,
+            // but we still check it in unit tests.
+            final long token = injectClearCallingIdentity();
+            try {
 
-        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
-            if (replacing) {
-                handlePackageUpdateFinished(packageName, userId);
-            } else {
-                handlePackageAdded(packageName, userId);
+                if (!mUserManager.isUserUnlocked(userId)) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Ignoring package broadcast " + action
+                                + " for locked/stopped user " + userId);
+                    }
+                    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;
+                }
+
+                final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+                switch (action) {
+                    case Intent.ACTION_PACKAGE_ADDED:
+                        if (replacing) {
+                            handlePackageUpdateFinished(packageName, userId);
+                        } else {
+                            handlePackageAdded(packageName, userId);
+                        }
+                        break;
+                    case Intent.ACTION_PACKAGE_REMOVED:
+                        if (!replacing) {
+                            handlePackageRemoved(packageName, userId);
+                        }
+                        break;
+                    case Intent.ACTION_PACKAGE_CHANGED:
+                        handlePackageChanged(packageName, userId);
+
+                        break;
+                    case Intent.ACTION_PACKAGE_DATA_CLEARED:
+                        handlePackageDataCleared(packageName, userId);
+                        break;
+                }
+            } finally {
+                injectRestoreCallingIdentity(token);
             }
-        } 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);
         }
-    }
+    };
 
     /**
      * Called when a user is unlocked.
@@ -2499,7 +2442,7 @@
 
                 // Then for each installed app, publish manifest shortcuts when needed.
                 forUpdatedPackages(ownerUserId, user.getLastAppScanTime(), ai -> {
-                    user.handlePackageAddedOrUpdated(ai.packageName, /* forceRescan=*/ false);
+                    user.rescanPackageIfNeeded(ai.packageName, /* forceRescan=*/ false);
                 });
 
                 // Write the time just before the scan, because there may be apps that have just
@@ -2520,7 +2463,7 @@
         synchronized (mLock) {
             final ShortcutUser user = getUserShortcutsLocked(userId);
             user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
-            user.handlePackageAddedOrUpdated(packageName, /* forceRescan=*/ false);
+            user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
         }
         verifyStates();
     }
@@ -2535,7 +2478,7 @@
             user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
 
             if (isPackageInstalled(packageName, userId)) {
-                user.handlePackageAddedOrUpdated(packageName, /* forceRescan=*/ false);
+                user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
             }
         }
         verifyStates();
@@ -2571,7 +2514,7 @@
         synchronized (mLock) {
             final ShortcutUser user = getUserShortcutsLocked(packageUserId);
 
-            user.handlePackageAddedOrUpdated(packageName, /* forceRescan=*/ true);
+            user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
         }
 
         verifyStates();
@@ -3047,10 +2990,6 @@
             pw.print("] ");
             pw.print(formatTime(next));
 
-            pw.print("  Locale change seq#: ");
-            pw.print(mLocaleChangeSequenceNumber.get());
-            pw.println();
-
             pw.print("  Config:");
             pw.print("    Max icon dim: ");
             pw.println(mMaxIconDimension);
@@ -3086,6 +3025,7 @@
                 dumpStatLS(pw, p, Stats.GET_LAUNCHER_ACTIVITY, "getLauncherActivity");
                 dumpStatLS(pw, p, Stats.CHECK_LAUNCHER_ACTIVITY, "checkLauncherActivity");
                 dumpStatLS(pw, p, Stats.IS_ACTIVITY_ENABLED, "isActivityEnabled");
+                dumpStatLS(pw, p, Stats.PACKAGE_UPDATE_CHECK, "packageUpdateCheck");
             }
 
             pw.println();
@@ -3097,9 +3037,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 +3085,6 @@
 
         enforceShell();
 
-        mPendingTasks.waitOnAllTasks();
-
         final int status = (new MyShellCommand()).exec(this, in, out, err, args, resultReceiver);
 
         resultReceiver.send(status, null);
@@ -3176,6 +3111,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 +3440,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 +3450,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 +3486,4 @@
             forEachLoadedUserLocked(u -> u.forAllPackageItems(ShortcutPackageItem::verifyStates));
         }
     }
-
-    ShortcutPendingTasks getPendingTasksForTest() {
-        return mPendingTasks;
-    }
-
-    Object getLockForTest() {
-        return mLock;
-    }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 7ea89c9..9649641 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -19,6 +19,8 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
+import android.content.pm.ShortcutManager;
+import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -51,7 +53,7 @@
     private static final String TAG_LAUNCHER = "launcher";
 
     private static final String ATTR_VALUE = "value";
-    private static final String ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER = "locale-seq-no";
+    private static final String ATTR_KNOWN_LOCALES = "locales";
     private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time";
 
     static final class PackageWithUser {
@@ -104,7 +106,7 @@
     /** Default launcher that can access the launcher apps APIs. */
     private ComponentName mDefaultLauncherComponent;
 
-    private long mKnownLocaleChangeSequenceNumber;
+    private String mKnownLocales;
 
     private long mLastAppScanTime;
 
@@ -225,29 +227,62 @@
     }
 
     /**
-     * Reset all throttling counters for all packages, if there has been a system locale change.
+     * Must be called at any entry points on {@link ShortcutManager} APIs to make sure the
+     * information on the package is up-to-date.
+     *
+     * We use broadcasts to handle locale changes and package changes, but because broadcasts
+     * are asynchronous, there's a chance a publisher calls getXxxShortcuts() after a certain event
+     * (e.g. system locale change) but shortcut manager hasn't finished processing the broadcast.
+     *
+     * So we call this method at all entry points from publishers to make sure we update all
+     * relevant information.
+     *
+     * Similar inconsistencies can happen when the launcher fetches shortcut information, but
+     * that's a less of an issue because for the launcher we report shortcut changes with
+     * callbacks.
      */
-    public void resetThrottlingIfNeeded() {
-        final long currentNo = mService.getLocaleChangeSequenceNumber();
-        if (mKnownLocaleChangeSequenceNumber < currentNo) {
-            if (ShortcutService.DEBUG) {
-                Slog.d(TAG, "LocaleChange detected for user " + mUserId);
-            }
-
-            mKnownLocaleChangeSequenceNumber = currentNo;
-
-            forAllPackages(p -> p.resetRateLimiting());
-
-            mService.scheduleSaveUser(mUserId);
-        }
+    public void onCalledByPublisher(@NonNull String packageName) {
+        detectLocaleChange();
+        rescanPackageIfNeeded(packageName, /*forceRescan=*/ false);
     }
 
-    public void handlePackageAddedOrUpdated(@NonNull String packageName, boolean forceRescan) {
+    private String getKnownLocales() {
+        if (TextUtils.isEmpty(mKnownLocales)) {
+            mKnownLocales = mService.injectGetLocaleTagsForUser(mUserId);
+            mService.scheduleSaveUser(mUserId);
+        }
+        return mKnownLocales;
+    }
+
+    /**
+     * Check to see if the system locale has changed, and if so, reset throttling
+     * and update resource strings.
+     */
+    public void detectLocaleChange() {
+        final String currentLocales = mService.injectGetLocaleTagsForUser(mUserId);
+        if (getKnownLocales().equals(currentLocales)) {
+            return;
+        }
+        if (ShortcutService.DEBUG) {
+            Slog.d(TAG, "Locale changed from " + currentLocales + " to " + mKnownLocales
+                    + " for user " + mUserId);
+        }
+        mKnownLocales = currentLocales;
+
+        forAllPackages(pkg -> {
+            pkg.resetRateLimiting();
+            pkg.resolveResourceStrings();
+        });
+
+        mService.scheduleSaveUser(mUserId);
+    }
+
+    public void rescanPackageIfNeeded(@NonNull String packageName, boolean forceRescan) {
         final boolean isNewApp = !mPackages.containsKey(packageName);
 
         final ShortcutPackage shortcutPackage = getPackageShortcuts(packageName);
 
-        if (!shortcutPackage.handlePackageAddedOrUpdated(isNewApp, forceRescan)) {
+        if (!shortcutPackage.rescanPackageIfNeeded(isNewApp, forceRescan)) {
             if (isNewApp) {
                 mPackages.remove(packageName);
             }
@@ -265,8 +300,7 @@
             throws IOException, XmlPullParserException {
         out.startTag(null, TAG_ROOT);
 
-        ShortcutService.writeAttr(out, ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER,
-                mKnownLocaleChangeSequenceNumber);
+        ShortcutService.writeAttr(out, ATTR_KNOWN_LOCALES, mKnownLocales);
         ShortcutService.writeAttr(out, ATTR_LAST_APP_SCAN_TIME,
                 mLastAppScanTime);
 
@@ -307,8 +341,8 @@
             boolean fromBackup) throws IOException, XmlPullParserException {
         final ShortcutUser ret = new ShortcutUser(s, userId);
 
-        ret.mKnownLocaleChangeSequenceNumber = ShortcutService.parseLongAttribute(parser,
-                ATTR_KNOWN_LOCALE_CHANGE_SEQUENCE_NUMBER);
+        ret.mKnownLocales = ShortcutService.parseStringAttribute(parser,
+                ATTR_KNOWN_LOCALES);
 
         // If lastAppScanTime is in the future, that means the clock went backwards.
         // Just scan all apps again.
@@ -377,8 +411,8 @@
         pw.print(prefix);
         pw.print("User: ");
         pw.print(mUserId);
-        pw.print("  Known locale seq#: ");
-        pw.print(mKnownLocaleChangeSequenceNumber);
+        pw.print("  Known locales: ");
+        pw.print(mKnownLocales);
         pw.print("  Last app scan: [");
         pw.print(mLastAppScanTime);
         pw.print("] ");
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/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index ca92b90..552803f 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -29,6 +29,7 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.KeyEvent;
@@ -942,6 +943,20 @@
                                 + " token=" + tok.token);
             }
             pw.println("  mCurrentUserId=" + mCurrentUserId);
+            pw.println("  mIcons=");
+            for (String slot : mIcons.keySet()) {
+                pw.println("    ");
+                pw.print(slot);
+                pw.print(" -> ");
+                final StatusBarIcon icon = mIcons.get(slot);
+                pw.print(icon);
+                if (!TextUtils.isEmpty(icon.contentDescription)) {
+                    pw.print(" \"");
+                    pw.print(icon.contentDescription);
+                    pw.print("\"");
+                }
+                pw.println();
+            }
         }
     }
 }
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/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index 57f784a..0f812ac 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -180,6 +180,7 @@
     private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
     private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
     private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
+    private static final int IPV4_ANY_HOST_ADDRESS = 0;
 
     private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
     private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
@@ -201,12 +202,14 @@
     private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
 
     private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_REQUEST_HEADER = new byte[]{
+    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
+    private static final short ARP_OPCODE_REQUEST = 1;
+    private static final short ARP_OPCODE_REPLY = 2;
+    private static final byte[] ARP_IPV4_HEADER = new byte[]{
             0, 1, // Hardware type: Ethernet (1)
             8, 0, // Protocol type: IP (0x0800)
             6,    // Hardware size: 6
             4,    // Protocol size: 4
-            0, 1  // Opcode: request (1)
     };
     private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
 
@@ -667,23 +670,48 @@
     private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
         // Here's a basic summary of what the ARP filter program does:
         //
-        // if interface has IPv4 address:
-        //   if it's not an ARP IPv4 request:
-        //     pass
-        //   if it's not a request for our IPv4 address:
-        //     drop
+        // if not ARP IPv4
+        //   pass
+        // if not ARP IPv4 reply or request
+        //   pass
+        // if unicast ARP reply
+        //   pass
+        // if interface has no IPv4 address
+        //   if target ip is 0.0.0.0
+        //      drop
+        // else
+        //   if target ip is not the interface ip
+        //      drop
         // pass
 
-        if (mIPv4Address != null) {
-            // if it's not an ARP IPv4 request, pass
-            gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_REQUEST_HEADER, gen.PASS_LABEL);
-            // if it's not a request for our IPv4 address, drop
+        final String checkTargetIPv4 = "checkTargetIPv4";
+
+        // Pass if not ARP IPv4.
+        gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
+        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, gen.PASS_LABEL);
+
+        // Pass if unknown ARP opcode.
+        gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
+        gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
+        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, gen.PASS_LABEL);
+
+        // Pass if unicast reply.
+        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
+        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
+
+        // Either a unicast request, a unicast reply, or a broadcast reply.
+        gen.defineLabel(checkTargetIPv4);
+        if (mIPv4Address == null) {
+            // When there is no IPv4 address, drop GARP replies (b/29404209).
+            gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
+            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, gen.DROP_LABEL);
+        } else {
+            // When there is an IPv4 address, drop unicast/broadcast requests
+            // and broadcast replies with a different target IPv4 address.
             gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
             gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, gen.DROP_LABEL);
         }
 
-        // Otherwise, pass
         gen.addJump(gen.PASS_LABEL);
     }
 
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/android/net/apf/ApfTest.java b/services/tests/servicestests/src/android/net/apf/ApfTest.java
index 815133a..bd76118 100644
--- a/services/tests/servicestests/src/android/net/apf/ApfTest.java
+++ b/services/tests/servicestests/src/android/net/apf/ApfTest.java
@@ -580,7 +580,7 @@
 
         public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter,
                 IpConnectivityLog log) throws Exception {
-            super(new ApfCapabilities(2, 1000, ARPHRD_ETHER), NetworkInterface.getByName("lo"),
+            super(new ApfCapabilities(2, 1536, ARPHRD_ETHER), NetworkInterface.getByName("lo"),
                     ipManagerCallback, multicastFilter, log);
         }
 
@@ -618,6 +618,7 @@
     }
 
     private static final int ETH_HEADER_LEN = 14;
+    private static final int ETH_DEST_ADDR_OFFSET = 0;
     private static final int ETH_ETHERTYPE_OFFSET = 12;
     private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{
         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
@@ -676,9 +677,18 @@
             4,    // Protocol size: 4
             0, 1  // Opcode: request (1)
     };
+    private static final byte[] ARP_IPV4_REPLY_HEADER = new byte[]{
+            0, 1, // Hardware type: Ethernet (1)
+            8, 0, // Protocol type: IP (0x0800)
+            6,    // Hardware size: 6
+            4,    // Protocol size: 4
+            0, 2  // Opcode: reply (2)
+    };
     private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
 
     private static final byte[] MOCK_IPV4_ADDR = new byte[]{10, 0, 0, 1};
+    private static final byte[] ANOTHER_IPV4_ADDR = new byte[]{10, 0, 0, 2};
+    private static final byte[] IPV4_ANY_HOST_ADDR = new byte[]{0, 0, 0, 0};
 
     @LargeTest
     public void testApfFilterIPv4() throws Exception {
@@ -801,51 +811,81 @@
         apfFilter.shutdown();
     }
 
-    private void verifyArpFilter(MockIpManagerCallback ipManagerCallback, ApfFilter apfFilter,
-            LinkProperties linkProperties, int filterResult) {
-        ipManagerCallback.resetApfProgramWait();
-        apfFilter.setLinkProperties(linkProperties);
-        byte[] program = ipManagerCallback.getApfProgram();
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        assertPass(program, packet.array(), 0);
-        packet.position(ARP_HEADER_OFFSET);
-        packet.put(ARP_IPV4_REQUEST_HEADER);
-        assertVerdict(filterResult, program, packet.array(), 0);
-        packet.position(ARP_TARGET_IP_ADDRESS_OFFSET);
-        packet.put(MOCK_IPV4_ADDR);
-        assertPass(program, packet.array(), 0);
+    private byte[] getProgram(MockIpManagerCallback cb, ApfFilter filter, LinkProperties lp) {
+        cb.resetApfProgramWait();
+        filter.setLinkProperties(lp);
+        return cb.getApfProgram();
+    }
+
+    private void verifyArpFilter(byte[] program, int filterResult) {
+        // Verify ARP request packet
+        assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR), 0);
+        assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR), 0);
+        assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR), 0);
+
+        // Verify unicast ARP reply packet is always accepted.
+        assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR), 0);
+        assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR), 0);
+        assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR), 0);
+
+        // Verify GARP reply packets are always filtered
+        assertDrop(program, garpReply(), 0);
     }
 
     @LargeTest
     public void testApfFilterArp() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
-        byte[] program = ipManagerCallback.getApfProgram();
 
-        // Verify initially ARP filter is off
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        assertPass(program, packet.array(), 0);
-        packet.position(ARP_HEADER_OFFSET);
-        packet.put(ARP_IPV4_REQUEST_HEADER);
-        assertPass(program, packet.array(), 0);
-        packet.position(ARP_TARGET_IP_ADDRESS_OFFSET);
-        packet.put(MOCK_IPV4_ADDR);
-        assertPass(program, packet.array(), 0);
+        // Verify initially ARP request filter is off, and GARP filter is on.
+        verifyArpFilter(ipManagerCallback.getApfProgram(), PASS);
 
         // Inform ApfFilter of our address and verify ARP filtering is on
+        LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24);
         LinkProperties lp = new LinkProperties();
-        assertTrue(lp.addLinkAddress(
-                new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24)));
-        verifyArpFilter(ipManagerCallback, apfFilter, lp, DROP);
+        assertTrue(lp.addLinkAddress(linkAddress));
+        verifyArpFilter(getProgram(ipManagerCallback, apfFilter, lp), DROP);
 
         // Inform ApfFilter of loss of IP and verify ARP filtering is off
-        verifyArpFilter(ipManagerCallback, apfFilter, new LinkProperties(), PASS);
+        verifyArpFilter(getProgram(ipManagerCallback, apfFilter, new LinkProperties()), PASS);
 
         apfFilter.shutdown();
     }
 
+    private static byte[] arpRequestBroadcast(byte[] tip) {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        packet.position(ETH_DEST_ADDR_OFFSET);
+        packet.put(ETH_BROADCAST_MAC_ADDRESS);
+        packet.position(ARP_HEADER_OFFSET);
+        packet.put(ARP_IPV4_REQUEST_HEADER);
+        packet.position(ARP_TARGET_IP_ADDRESS_OFFSET);
+        packet.put(tip);
+        return packet.array();
+    }
+
+    private static byte[] arpReplyUnicast(byte[] tip) {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        packet.position(ARP_HEADER_OFFSET);
+        packet.put(ARP_IPV4_REPLY_HEADER);
+        packet.position(ARP_TARGET_IP_ADDRESS_OFFSET);
+        packet.put(tip);
+        return packet.array();
+    }
+
+    private static byte[] garpReply() {
+        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
+        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
+        packet.position(ETH_DEST_ADDR_OFFSET);
+        packet.put(ETH_BROADCAST_MAC_ADDRESS);
+        packet.position(ARP_HEADER_OFFSET);
+        packet.put(ARP_IPV4_REPLY_HEADER);
+        packet.position(ARP_TARGET_IP_ADDRESS_OFFSET);
+        packet.put(IPV4_ANY_HOST_ADDR);
+        return packet.array();
+    }
+
     // Verify that the last program pushed to the IpManager.Callback properly filters the
     // given packet for the given lifetime.
     private void verifyRaLifetime(MockIpManagerCallback ipManagerCallback, ByteBuffer packet,
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..2652b8f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -110,13 +110,14 @@
 public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
     protected static final String TAG = "ShortcutManagerTest";
 
+    protected static final boolean DUMP_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true
+
     /**
      * Whether to enable dump or not.  Should be only true when debugging to avoid bugs where
      * dump affecting the behavior.
      */
-    protected static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true
-
-    protected static final boolean DUMP_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true
+    protected static final boolean ENABLE_DUMP = false // DO NOT SUBMIT WITH true
+            || DUMP_IN_TEARDOWN || ShortcutService.DEBUG;
 
     protected static final String[] EMPTY_STRINGS = new String[0]; // Just for readability.
 
@@ -154,6 +155,11 @@
             // ignore.
             return null;
         }
+
+        @Override
+        public void unregisterReceiver(BroadcastReceiver receiver) {
+            // ignore.
+        }
     }
 
     /** Context used in the client side */
@@ -212,6 +218,11 @@
         }
 
         @Override
+        public String injectGetLocaleTagsForUser(@UserIdInt int userId) {
+            return mInjectedLocale.toLanguageTag();
+        }
+
+        @Override
         boolean injectShouldPerformVerification() {
             return true; // Always verify during unit tests.
         }
@@ -404,11 +415,6 @@
             // During tests, WTF is fatal.
             fail(message + "  exception: " + th + "\n" + Log.getStackTraceString(th));
         }
-
-        @Override
-        boolean injectCheckPendingTaskWaitThread() {
-            return true;
-        }
     }
 
     /** ShortcutManager with injection override methods. */
@@ -720,11 +726,6 @@
         // Start the service.
         initService();
         setCaller(CALLING_PACKAGE_1);
-
-        // In order to complicate the situation, we set mLocaleChangeSequenceNumber to 1 by
-        // calling this.  Running test with mLocaleChangeSequenceNumber == 0 might make us miss
-        // some edge cases.
-        mInternal.onSystemLocaleChangedNoLock();
     }
 
     /**
@@ -842,19 +843,11 @@
         // Send boot sequence events.
         mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
 
-        // Make sure a call to onSystemLocaleChangedNoLock() before PHASE_BOOT_COMPLETED will be
-        // ignored.
-        final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
-        mInternal.onSystemLocaleChangedNoLock();
-        assertEquals(origSequenceNumber, mService.getLocaleChangeSequenceNumber());
-
         mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
     }
 
     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..d563185 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,28 +5730,31 @@
         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());
-            assertEmpty(mManager.getPinnedShortcuts());
+            // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
+            // update check.
+            // So look the internal data directly using getCallerShortcuts().
+            assertEmpty(getCallerShortcuts());
         });
 
         // 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());
-            assertEmpty(mManager.getPinnedShortcuts());
+            // Don't use the mManager APIs to get shortcuts, because they'll trigger the package
+            // update check.
+            // So look the internal data directly using getCallerShortcuts().
+            assertEmpty(getCallerShortcuts());
         });
 
         // Unlock the user, now it should work.
         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 +5795,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 +5823,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 +5854,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 +5869,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 +5884,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 +5900,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 +5928,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 +5966,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 +6014,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.
@@ -6107,7 +6111,7 @@
         });
     }
 
-    public void testManifestShortcuts_localeChange() {
+    public void testManifestShortcuts_localeChange() throws InterruptedException {
         mService.handleUnlockUser(USER_0);
 
         // Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -6115,7 +6119,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, () -> {
@@ -6163,8 +6167,15 @@
 
         mInjectedCurrentTimeMillis++;
 
+        // Change the locale and send the broadcast, make sure the launcher gets a callback too.
         mInjectedLocale = Locale.JAPANESE;
-        mInternal.onSystemLocaleChangedNoLock();
+
+        setCaller(LAUNCHER_1, USER_0);
+
+        assertForLauncherCallback(mLauncherApps, () -> {
+            mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
+        }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+                .haveIds("ms1", "ms2", "s1");
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             // check first shortcut.
@@ -6212,7 +6223,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 +6242,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 +6263,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 +6286,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 +6319,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 +6349,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 +6421,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 +6471,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 +6482,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 +6564,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 +6634,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 +6760,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 +6909,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 +6929,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 +6949,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 +6968,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/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index f570ff2..bd413be 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -47,6 +47,8 @@
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutService.ConfigConstants;
 
+import java.util.Locale;
+
 /**
  * Tests for ShortcutService and ShortcutManager.
  *
@@ -130,7 +132,6 @@
         assertExpectException(NullPointerException.class, "action must be set",
                 () -> new ShortcutInfo.Builder(getTestContext(), "id").setIntent(new Intent()));
 
-        // same for add.
         assertExpectException(
                 IllegalArgumentException.class, "Short label must be provided", () -> {
             ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
@@ -139,6 +140,7 @@
             assertTrue(getManager().setDynamicShortcuts(list(si)));
         });
 
+        // same for add.
         assertExpectException(
                 IllegalArgumentException.class, "Short label must be provided", () -> {
             ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
@@ -147,7 +149,6 @@
             assertTrue(getManager().addDynamicShortcuts(list(si)));
         });
 
-        // same for add.
         assertExpectException(NullPointerException.class, "Intent must be provided", () -> {
             ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
                     .setActivity(new ComponentName(getTestContext().getPackageName(), "s"))
@@ -181,6 +182,33 @@
                     .build();
             assertTrue(getManager().addDynamicShortcuts(list(si)));
         });
+
+        // Now all activities are not main.
+        mMainActivityChecker = (component, userId) -> false;
+
+        assertExpectException(
+                IllegalStateException.class, "is not main", () -> {
+                    ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
+                            .setActivity(new ComponentName(getTestContext(), "s"))
+                            .build();
+                    assertTrue(getManager().setDynamicShortcuts(list(si)));
+                });
+        // For add
+        assertExpectException(
+                IllegalStateException.class, "is not main", () -> {
+                    ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
+                            .setActivity(new ComponentName(getTestContext(), "s"))
+                            .build();
+                    assertTrue(getManager().addDynamicShortcuts(list(si)));
+                });
+        // For update
+        assertExpectException(
+                IllegalStateException.class, "is not main", () -> {
+                    ShortcutInfo si = new ShortcutInfo.Builder(getTestContext(), "id")
+                            .setActivity(new ComponentName(getTestContext(), "s"))
+                            .build();
+                    assertTrue(getManager().updateShortcuts(list(si)));
+                });
     }
 
     public void testShortcutInfoParcel() {
@@ -1331,13 +1359,12 @@
         mService.saveDirtyInfo();
         initService();
 
-        final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
-
-        mInternal.onSystemLocaleChangedNoLock();
-        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
+        mInjectedLocale = Locale.CHINA;
+        mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
 
         // Note at this point only user-0 is loaded, and the counters are reset for this user,
-        // but it will work for other users too, because we persist when
+        // but it will work for other users too because we check the locale change at any
+        // API entry point.
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(3, mManager.getRemainingCallCount());
@@ -1358,11 +1385,28 @@
             assertEquals(3, mManager.getRemainingCallCount());
         });
 
+        // Make sure even if we receive ACTION_LOCALE_CHANGED, if the locale hasn't actually
+        // changed, we don't reset throttling.
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            mManager.updateShortcuts(list());
+            assertEquals(2, mManager.getRemainingCallCount());
+        });
+
+        mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertEquals(2, mManager.getRemainingCallCount()); // Still 2.
+        });
+
         mService.saveDirtyInfo();
         initService();
 
-        // Make sure the counter is persisted.
-        assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
+        // The locale should be persisted, so it still shouldn't reset throttling.
+        mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertEquals(2, mManager.getRemainingCallCount()); // Still 2.
+        });
     }
 
     public void testThrottling_foreground() throws Exception {
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/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index f89c4e4..2f64ad7 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -973,6 +973,8 @@
 
         waitOnMainThread();
 
+        launcherApps.unregisterCallback(asserter.getMockCallback());
+
         return asserter;
     }
 }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index eb3c665..69cf1a2 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -838,6 +838,10 @@
                     && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) {
                 return false;
             }
+
+            if (isDeviceProvisioningPackage(packageName)) {
+                return false;
+            }
         }
 
         if (!isAppIdleUnfiltered(packageName, userId, elapsedRealtime)) {
@@ -930,6 +934,16 @@
         return dpm.packageHasActiveAdmins(packageName, userId);
     }
 
+    /**
+     * Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
+     * returns {@code false}.
+     */
+    private boolean isDeviceProvisioningPackage(String packageName) {
+        String deviceProvisioningPackage = getContext().getResources().getString(
+                com.android.internal.R.string.config_deviceProvisioningPackage);
+        return deviceProvisioningPackage != null && deviceProvisioningPackage.equals(packageName);
+    }
+
     private boolean isCarrierApp(String packageName) {
         synchronized (mLock) {
             if (!mHaveCarrierPrivilegedApps) {
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()));
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index ea36e2c..2956d87 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -256,23 +256,33 @@
 
 
 def check_emoji_coverage(all_emoji, equivalent_emoji):
+  emoji_font = get_emoji_font()
+  check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji)
+
+
+def get_emoji_font():
     emoji_fonts = [
         record.font for record in _fallback_chain
         if 'Zsye' in record.scripts]
     assert len(emoji_fonts) == 1, 'There are %d emoji fonts.' % len(emoji_fonts)
-    emoji_font = emoji_fonts[0]
-    coverage = get_emoji_map(emoji_font)
+    return emoji_fonts[0]
 
+
+def check_emoji_font_coverage(emoji_font, all_emoji, equivalent_emoji):
+    coverage = get_emoji_map(emoji_font)
     for sequence in all_emoji:
         assert sequence in coverage, (
             '%s is not supported in the emoji font.' % printable(sequence))
 
+    # disable temporarily - we cover more than this
+    """
     for sequence in coverage:
         if sequence in {0x0000, 0x000D, 0x0020}:
             # The font needs to support a few extra characters, which is OK
             continue
         assert sequence in all_emoji, (
             'Emoji font should not support %s.' % printable(sequence))
+    """
 
     for first, second in sorted(equivalent_emoji.items()):
         assert coverage[first] == coverage[second], (
@@ -280,6 +290,8 @@
                 printable(first),
                 printable(second)))
 
+    # disable temporarily - some equivalent sequences we don't even know about
+    """
     for glyph in set(coverage.values()):
         maps_to_glyph = [seq for seq in coverage if coverage[seq] == glyph]
         if len(maps_to_glyph) > 1:
@@ -295,7 +307,7 @@
                 'The sequences %s should not result in the same glyph %s' % (
                     printable(equivalent_seqs),
                     glyph))
-
+    """
 
 def check_emoji_defaults(default_emoji):
     missing_text_chars = _emoji_properties['Emoji'] - default_emoji
@@ -427,6 +439,11 @@
     _emoji_sequences = dict(
         (t, v) for (t, v) in _emoji_sequences.items() if not contains_excluded(t))
 
+    # add in UN flag
+    UN_seq = flag_sequence('UN')
+    _emoji_sequences[UN_seq] = 'Emoji_Flag_Sequence'
+
+
 def flag_sequence(territory_code):
     return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
 
@@ -483,6 +500,11 @@
     (0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
 }
 
+
+def is_fitzpatrick_modifier(cp):
+  return 0x1f3fb <= cp <= 0x1f3ff
+
+
 def compute_expected_emoji():
     equivalent_emoji = {}
     sequence_pieces = set()
@@ -500,7 +522,15 @@
         sequence_pieces.update(sequence)
         # Add reverse of all emoji ZWJ sequences, which are added to the fonts
         # as a workaround to get the sequences work in RTL text.
-        reversed_seq = tuple(reversed(sequence))
+        reversed_seq = list(reversed(sequence))
+        # if there are fitzpatrick modifiers in the sequence, keep them after
+        # the emoji they modify
+        for i in xrange(1, len(reversed_seq)):
+          if is_fitzpatrick_modifier(reversed_seq[i - 1]):
+            tmp = reversed_seq[i]
+            reversed_seq[i] = reversed_seq[i-1]
+            reversed_seq[i-1] = tmp
+        reversed_seq = tuple(reversed_seq)
         all_sequences.add(reversed_seq)
         equivalent_emoji[reversed_seq] = sequence
 
@@ -536,8 +566,8 @@
 
 
 def main():
-    target_out = sys.argv[1]
     global _fonts_dir
+    target_out = sys.argv[1]
     _fonts_dir = path.join(target_out, 'fonts')
 
     fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml')