Merge "AAPT2: Update --no-version-vector list" into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 6023aab..ac97b54 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26513,7 +26513,6 @@
     method public boolean isTdlsSupported();
     method public boolean isWifiEnabled();
     method public deprecated boolean pingSupplicant();
-    method public void queryPasspointIcon(long, java.lang.String);
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
@@ -26526,29 +26525,17 @@
     method public boolean startScan();
     method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
-    field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
-    field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
-    field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
-    field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
     field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
     field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
     field public static final int ERROR_AUTHENTICATING = 1; // 0x1
-    field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
     field public static final java.lang.String EXTRA_BSSID = "bssid";
-    field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
-    field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-    field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
-    field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-    field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
     field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
     field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
     field public static final java.lang.String EXTRA_NEW_STATE = "newState";
     field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
     field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-    field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
     field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
     field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-    field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
     field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
     field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
     field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -33907,7 +33894,6 @@
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
-    field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
     field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
diff --git a/api/system-current.txt b/api/system-current.txt
index 67b6e82..a2c2771 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -29038,7 +29038,6 @@
     method public boolean isWifiEnabled();
     method public boolean isWifiScannerSupported();
     method public deprecated boolean pingSupplicant();
-    method public void queryPasspointIcon(long, java.lang.String);
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
@@ -29055,10 +29054,6 @@
     method public boolean startScan(android.os.WorkSource);
     method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
-    field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
-    field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
-    field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
-    field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
     field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
     field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
     field public static final int CHANGE_REASON_ADDED = 0; // 0x0
@@ -29066,14 +29061,8 @@
     field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
     field public static final java.lang.String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
     field public static final int ERROR_AUTHENTICATING = 1; // 0x1
-    field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
     field public static final java.lang.String EXTRA_BSSID = "bssid";
-    field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
     field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason";
-    field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-    field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
-    field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-    field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
     field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
     field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
     field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
@@ -29081,10 +29070,8 @@
     field public static final java.lang.String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
     field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
     field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-    field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
     field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
     field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-    field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
     field public static final java.lang.String EXTRA_WIFI_AP_STATE = "wifi_state";
     field public static final java.lang.String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
     field public static final java.lang.String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
@@ -36821,7 +36808,6 @@
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
-    field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
     field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
diff --git a/api/test-current.txt b/api/test-current.txt
index d3cb4c9..1cad48e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -26622,7 +26622,6 @@
     method public boolean isTdlsSupported();
     method public boolean isWifiEnabled();
     method public deprecated boolean pingSupplicant();
-    method public void queryPasspointIcon(long, java.lang.String);
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
@@ -26635,29 +26634,17 @@
     method public boolean startScan();
     method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
-    field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
-    field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
-    field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
-    field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
     field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
     field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
     field public static final int ERROR_AUTHENTICATING = 1; // 0x1
-    field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
     field public static final java.lang.String EXTRA_BSSID = "bssid";
-    field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
-    field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
-    field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
-    field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
-    field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
     field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
     field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
     field public static final java.lang.String EXTRA_NEW_STATE = "newState";
     field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
     field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
-    field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
     field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
     field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
-    field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
     field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
     field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
     field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -34044,7 +34031,6 @@
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
     field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
-    field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
     field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
     field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
@@ -45743,6 +45729,7 @@
     method public boolean isAttachedToWindow();
     method public boolean isClickable();
     method public boolean isContextClickable();
+    method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
     method public boolean isDirty();
     method public boolean isDrawingCacheEnabled();
     method public boolean isDuplicateParentStateEnabled();
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b60aed6..d71573f 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -63,6 +63,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -1471,7 +1472,8 @@
         }
         ClearDataObserver obs = new ClearDataObserver();
         try {
-            mPm.freeStorageAndNotify(volumeUuid, sizeVal, obs);
+            mPm.freeStorageAndNotify(volumeUuid, sizeVal,
+                    StorageManager.FLAG_ALLOCATE_DEFY_RESERVED, obs);
             synchronized (obs) {
                 while (!obs.finished) {
                     try {
diff --git a/core/java/android/animation/AnimationHandler.java b/core/java/android/animation/AnimationHandler.java
index e2e5a8f..260323f 100644
--- a/core/java/android/animation/AnimationHandler.java
+++ b/core/java/android/animation/AnimationHandler.java
@@ -136,7 +136,8 @@
 
     private void doAnimationFrame(long frameTime) {
         long currentTime = SystemClock.uptimeMillis();
-        for (int i = 0; i < mAnimationCallbacks.size(); i++) {
+        final int size = mAnimationCallbacks.size();
+        for (int i = 0; i < size; i++) {
             final AnimationFrameCallback callback = mAnimationCallbacks.get(i);
             if (callback == null) {
                 continue;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b439c1d..b360c82 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6142,6 +6142,7 @@
      *
      * @param action the action to run on the UI thread
      */
+    @Override
     public final void runOnUiThread(Runnable action) {
         if (Thread.currentThread() != mUiThread) {
             mHandler.post(action);
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 53608fb..c4d5116 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -25,6 +25,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -826,7 +828,11 @@
             case ANIM_THUMBNAIL_SCALE_DOWN:
             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
-                mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                // Unpackage the GraphicBuffer from the parceled thumbnail
+                final GraphicBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                if (buffer != null) {
+                    mThumbnail = Bitmap.createHardwareBitmap(buffer);
+                }
                 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
                 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
                 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
@@ -919,9 +925,14 @@
         return mCustomInPlaceResId;
     }
 
-    /** @hide */
-    public Bitmap getThumbnail() {
-        return mThumbnail;
+    /**
+     * The thumbnail is copied into a hardware bitmap when it is bundled and sent to the system, so
+     * it should always be backed by a GraphicBuffer on the other end.
+     *
+     * @hide
+     */
+    public GraphicBuffer getThumbnail() {
+        return mThumbnail.createGraphicBufferHandle();
     }
 
     /** @hide */
@@ -1230,7 +1241,14 @@
             case ANIM_THUMBNAIL_SCALE_DOWN:
             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
-                b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
+                // Once we parcel the thumbnail for transfering over to the system, create a copy of
+                // the bitmap to a hardware bitmap and pass through the GraphicBuffer
+                if (mThumbnail == null) {
+                    b.putParcelable(KEY_ANIM_THUMBNAIL, null);
+                } else {
+                    final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, true /* immutable */);
+                    b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.createGraphicBufferHandle());
+                }
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
                 b.putInt(KEY_ANIM_WIDTH, mWidth);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 525b151..e5c4208 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2108,7 +2108,7 @@
     public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
             IPackageDataObserver observer) {
         try {
-            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
+            mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, 0, observer);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2117,7 +2117,7 @@
     @Override
     public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
         try {
-            mPM.freeStorage(volumeUuid, freeStorageSize, pi);
+            mPM.freeStorage(volumeUuid, freeStorageSize, 0, pi);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3ed174b..31f52db 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1168,7 +1168,7 @@
      */
     public static final int GROUP_ALERT_CHILDREN = 2;
 
-    private int mGroupAlertBehavior = GROUP_ALERT_ALL;
+    private int mGroupAlertBehavior = GROUP_ALERT_CHILDREN;
 
     /**
      * If this notification is being shown as a badge, always show as a number.
@@ -2640,6 +2640,20 @@
     }
 
     /**
+     * @hide
+     */
+    public boolean suppressAlertingDueToGrouping() {
+        if (isGroupSummary()
+                && getGroupAlertBehavior() == Notification.GROUP_ALERT_CHILDREN) {
+            return true;
+        } else if (isGroupChild()
+                && getGroupAlertBehavior() == Notification.GROUP_ALERT_SUMMARY) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Builder class for {@link Notification} objects.
      *
      * Provides a convenient way to set the various fields of a {@link Notification} and generate
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 3cb59f2..87e516c 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -35,6 +35,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -501,7 +502,7 @@
         if (constraintFlags != j.constraintFlags) {
             return false;
         }
-        if (!Objects.deepEquals(triggerContentUris, j.triggerContentUris)) {
+        if (!Arrays.equals(triggerContentUris, j.triggerContentUris)) {
             return false;
         }
         if (triggerContentUpdateDelay != j.triggerContentUpdateDelay) {
@@ -556,37 +557,37 @@
     public int hashCode() {
         int hashCode = jobId;
         if (extras != null) {
-            hashCode = 31*hashCode + extras.hashCode();
+            hashCode = 31 * hashCode + extras.hashCode();
         }
         if (transientExtras != null) {
-            hashCode = 31*hashCode + transientExtras.hashCode();
+            hashCode = 31 * hashCode + transientExtras.hashCode();
         }
         if (clipData != null) {
-            hashCode = 31*hashCode + clipData.hashCode();
+            hashCode = 31 * hashCode + clipData.hashCode();
         }
         hashCode = 31*hashCode + clipGrantFlags;
         if (service != null) {
-            hashCode = 31*hashCode + service.hashCode();
+            hashCode = 31 * hashCode + service.hashCode();
         }
-        hashCode = 31*hashCode + constraintFlags;
+        hashCode = 31 * hashCode + constraintFlags;
         if (triggerContentUris != null) {
-            hashCode = 31*hashCode + triggerContentUris.hashCode();
+            hashCode = 31 * hashCode + Arrays.hashCode(triggerContentUris);
         }
-        hashCode = 31*hashCode + Long.hashCode(triggerContentUpdateDelay);
-        hashCode = 31*hashCode + Long.hashCode(triggerContentMaxDelay);
-        hashCode = 31*hashCode + Boolean.hashCode(hasEarlyConstraint);
-        hashCode = 31*hashCode + Boolean.hashCode(hasLateConstraint);
-        hashCode = 31*hashCode + networkType;
-        hashCode = 31*hashCode + Long.hashCode(minLatencyMillis);
-        hashCode = 31*hashCode + Long.hashCode(maxExecutionDelayMillis);
-        hashCode = 31*hashCode + Boolean.hashCode(isPeriodic);
-        hashCode = 31*hashCode + Boolean.hashCode(isPersisted);
-        hashCode = 31*hashCode + Long.hashCode(intervalMillis);
-        hashCode = 31*hashCode + Long.hashCode(flexMillis);
-        hashCode = 31*hashCode + Long.hashCode(initialBackoffMillis);
-        hashCode = 31*hashCode + backoffPolicy;
-        hashCode = 31*hashCode + priority;
-        hashCode = 31*hashCode + flags;
+        hashCode = 31 * hashCode + Long.hashCode(triggerContentUpdateDelay);
+        hashCode = 31 * hashCode + Long.hashCode(triggerContentMaxDelay);
+        hashCode = 31 * hashCode + Boolean.hashCode(hasEarlyConstraint);
+        hashCode = 31 * hashCode + Boolean.hashCode(hasLateConstraint);
+        hashCode = 31 * hashCode + networkType;
+        hashCode = 31 * hashCode + Long.hashCode(minLatencyMillis);
+        hashCode = 31 * hashCode + Long.hashCode(maxExecutionDelayMillis);
+        hashCode = 31 * hashCode + Boolean.hashCode(isPeriodic);
+        hashCode = 31 * hashCode + Boolean.hashCode(isPersisted);
+        hashCode = 31 * hashCode + Long.hashCode(intervalMillis);
+        hashCode = 31 * hashCode + Long.hashCode(flexMillis);
+        hashCode = 31 * hashCode + Long.hashCode(initialBackoffMillis);
+        hashCode = 31 * hashCode + backoffPolicy;
+        hashCode = 31 * hashCode + priority;
+        hashCode = 31 * hashCode + flags;
         return hashCode;
     }
 
diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java
index b0ec650..ab94da8 100644
--- a/core/java/android/app/job/JobServiceEngine.java
+++ b/core/java/android/app/job/JobServiceEngine.java
@@ -210,6 +210,9 @@
      * information.
      */
     public void jobFinished(JobParameters params, boolean needsReschedule) {
+        if (params == null) {
+            throw new NullPointerException("params");
+        }
         Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
         m.arg2 = needsReschedule ? 1 : 0;
         m.sendToTarget();
diff --git a/core/java/android/app/usage/IStorageStatsManager.aidl b/core/java/android/app/usage/IStorageStatsManager.aidl
index 5d1550f..15e5ea5 100644
--- a/core/java/android/app/usage/IStorageStatsManager.aidl
+++ b/core/java/android/app/usage/IStorageStatsManager.aidl
@@ -24,6 +24,7 @@
     boolean isQuotaSupported(String volumeUuid, String callingPackage);
     long getTotalBytes(String volumeUuid, String callingPackage);
     long getFreeBytes(String volumeUuid, String callingPackage);
+    long getCacheBytes(String volumeUuid, String callingPackage);
     long getCacheQuotaBytes(String volumeUuid, int uid, String callingPackage);
     StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId, String callingPackage);
     StorageStats queryStatsForUid(String volumeUuid, int uid, String callingPackage);
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index d9d958c..0b2b190 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -142,6 +142,24 @@
         return getFreeBytes(convert(uuid));
     }
 
+    /** {@hide} */
+    public @BytesLong long getCacheBytes(@NonNull UUID storageUuid) throws IOException {
+        try {
+            return mService.getCacheBytes(convert(storageUuid), mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    @Deprecated
+    public long getCacheBytes(String uuid) throws IOException {
+        return getCacheBytes(convert(uuid));
+    }
+
     /**
      * Return storage statistics for a specific package on the requested storage
      * volume.
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index f802e8d..914e8fd 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -47,7 +47,9 @@
     private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
     private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
     private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
-    private static final int DATA_TYPE_SERVICE_DATA = 0x16;
+    private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
+    private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
+    private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
     private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
 
     // Flags of the advertising data.
@@ -224,10 +226,16 @@
                     case DATA_TYPE_TX_POWER_LEVEL:
                         txPowerLevel = scanRecord[currentPos];
                         break;
-                    case DATA_TYPE_SERVICE_DATA:
-                        // The first two bytes of the service data are service data UUID in little
-                        // endian. The rest bytes are service data.
+                    case DATA_TYPE_SERVICE_DATA_16_BIT:
+                    case DATA_TYPE_SERVICE_DATA_32_BIT:
+                    case DATA_TYPE_SERVICE_DATA_128_BIT:
                         int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
+                        if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
+                         serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
+                        } else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
+                         serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
+                        }
+
                         byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
                                 serviceUuidLength);
                         ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 7aaf453..2ebfa8f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -360,7 +360,7 @@
      * the operation is completed
      */
      void freeStorageAndNotify(in String volumeUuid, in long freeStorageSize,
-             IPackageDataObserver observer);
+             int storageFlags, IPackageDataObserver observer);
 
     /**
      * Free storage by deleting LRU sorted list of cache files across
@@ -384,7 +384,7 @@
      * to indicate that no call back is desired.
      */
      void freeStorage(in String volumeUuid, in long freeStorageSize,
-             in IntentSender pi);
+             int storageFlags, in IntentSender pi);
 
     /**
      * Delete all the cache files in an applications cache directory
diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
index c027d54..133146d 100644
--- a/core/java/android/nfc/IAppCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -25,6 +25,6 @@
 interface IAppCallback
 {
     BeamShareData createBeamShareData(byte peerLlcpVersion);
-    void onNdefPushComplete(byte peerLlcpVersion);
-    void onTagDiscovered(in Tag tag);
+    oneway void onNdefPushComplete(byte peerLlcpVersion);
+    oneway void onTagDiscovered(in Tag tag);
 }
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 2c9ce3f..093a9b4 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -938,7 +938,7 @@
      */
     void writeToByteBuffer(ByteBuffer buffer, boolean mb, boolean me) {
         boolean sr = mPayload.length < 256;
-        boolean il = mId.length > 0;
+        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
 
         byte flags = (byte)((mb ? FLAG_MB : 0) | (me ? FLAG_ME : 0) |
                 (sr ? FLAG_SR : 0) | (il ? FLAG_IL : 0) | mTnf);
@@ -966,7 +966,7 @@
         int length = 3 + mType.length + mId.length + mPayload.length;
 
         boolean sr = mPayload.length < 256;
-        boolean il = mId.length > 0;
+        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
 
         if (!sr) length += 3;
         if (il) length += 1;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 499d6bb..ecc4dec 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -162,6 +162,11 @@
     public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;
 
     /**
+     * A constant indicating a bluetooth scan timer for unoptimized scans.
+     */
+    public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21;
+
+    /**
      * Include all of the data in the stats, including previously saved data.
      */
     public static final int STATS_SINCE_CHARGED = 0;
@@ -191,8 +196,12 @@
      * New in version 21:
      *   - Actual (not just apportioned) Wakelock time is also recorded.
      *   - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
+     *   - BLE scan result count
+     *   - CPU frequency time per uid
+     * New in version 22:
+     *   - BLE scan result background count, BLE unoptimized scan time
      */
-    static final String CHECKIN_VERSION = "21";
+    static final String CHECKIN_VERSION = "22";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -217,9 +226,10 @@
     private static final String STATE_TIME_DATA = "st";
     // wl line is:
     // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
-    // full totalTime,    'f', count, current duration, max duration, total duration,
-    // partial totalTime, 'p', count, current duration, max duration, total duration,
-    // window totalTime,  'w', count, current duration, max duration, total duration
+    // full        totalTime, 'f',  count, current duration, max duration, total duration,
+    // partial     totalTime, 'p',  count, current duration, max duration, total duration,
+    // bg partial  totalTime, 'bp', count, current duration, max duration, total duration,
+    // window      totalTime, 'w',  count, current duration, max duration, total duration
     // [Currently, full and window wakelocks have durations current = max = total = -1]
     private static final String WAKELOCK_DATA = "wl";
     // awl line is:
@@ -565,7 +575,10 @@
         public abstract Timer getForegroundActivityTimer();
         public abstract Timer getBluetoothScanTimer();
         public abstract Timer getBluetoothScanBackgroundTimer();
+        public abstract Timer getBluetoothUnoptimizedScanTimer();
+        public abstract Timer getBluetoothUnoptimizedScanBackgroundTimer();
         public abstract Counter getBluetoothScanResultCounter();
+        public abstract Counter getBluetoothScanResultBgCounter();
 
         public abstract long[] getCpuFreqTimes(int which);
         public abstract long[] getScreenOffCpuFreqTimes(int which);
@@ -3429,10 +3442,29 @@
                     final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeBg = bleTimerBg != null ?
                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    // Result counters
                     final int resultCount = u.getBluetoothScanResultCounter() != null ?
                             u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
+                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
+                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
+                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
+                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
+                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
+                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
+                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
+                    final Timer unoptimizedScanTimerBg =
+                            u.getBluetoothUnoptimizedScanBackgroundTimer();
+                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
+                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
+                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+
                     dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
-                            countBg, actualTime, actualTimeBg, resultCount);
+                            countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
+                            unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
+                            unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
                 }
             }
 
@@ -3469,8 +3501,11 @@
                 sb.setLength(0);
                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
                         rawRealtime, "f", which, linePrefix);
-                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
+                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+                linePrefix = printWakeLockCheckin(sb, pTimer,
                         rawRealtime, "p", which, linePrefix);
+                linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
+                        rawRealtime, "bp", which, linePrefix);
                 linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
                         rawRealtime, "w", which, linePrefix);
 
@@ -4625,34 +4660,94 @@
                     final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeMsBg = bleTimerBg != null ?
                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    // Result counters
                     final int resultCount = u.getBluetoothScanResultCounter() != null ?
                             u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
+                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
+                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
+                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
+                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
+                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
+                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
+                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
+                    final Timer unoptimizedScanTimerBg =
+                            u.getBluetoothUnoptimizedScanBackgroundTimer();
+                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
+                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
+                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
 
                     sb.setLength(0);
-                    sb.append(prefix);
-                    sb.append("    ");
-                    sb.append("Bluetooth Scan");
-                    sb.append(": ");
                     if (actualTimeMs != totalTimeMs) {
+                        sb.append(prefix);
+                        sb.append("    Bluetooth Scan (total blamed realtime): ");
                         formatTimeMs(sb, totalTimeMs);
-                        sb.append("blamed realtime, ");
+                        sb.append(" (");
+                        sb.append(count);
+                        sb.append(" times)");
+                        if (bleTimer.isRunningLocked()) {
+                            sb.append(" (currently running)");
+                        }
+                        sb.append("\n");
                     }
-                    formatTimeMs(sb, actualTimeMs); // since reset, regardless of 'which'
-                    sb.append("realtime (");
+
+                    sb.append(prefix);
+                    sb.append("    Bluetooth Scan (total actual realtime): ");
+                    formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
+                    sb.append(" (");
                     sb.append(count);
                     sb.append(" times)");
                     if (bleTimer.isRunningLocked()) {
-                            sb.append(" (running)");
+                            sb.append(" (currently running)");
                     }
-                    if (actualTimeMsBg != 0 || countBg > 0) {
-                        sb.append(", ");
-                        formatTimeMs(sb, actualTimeMsBg); // since reset, regardless of 'which'
-                        sb.append("background (");
+                    sb.append("\n");
+                    if (actualTimeMsBg > 0 || countBg > 0) {
+                        sb.append(prefix);
+                        sb.append("    Bluetooth Scan (background realtime): ");
+                        formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
+                        sb.append(" (");
                         sb.append(countBg);
                         sb.append(" times)");
+                        if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
+                            sb.append(" (currently running in background)");
+                        }
+                        sb.append("\n");
                     }
-                    sb.append("; Results count ");
+
+                    sb.append(prefix);
+                    sb.append("    Bluetooth Scan Results: ");
                     sb.append(resultCount);
+                    sb.append(" (");
+                    sb.append(resultCountBg);
+                    sb.append(" in background)");
+
+                    if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
+                        sb.append("\n");
+                        sb.append(prefix);
+                        sb.append("    Unoptimized Bluetooth Scan (realtime): ");
+                        formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
+                        sb.append(" (max ");
+                        formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
+                        sb.append(")");
+                        if (unoptimizedScanTimer != null
+                                && unoptimizedScanTimer.isRunningLocked()) {
+                            sb.append(" (currently running unoptimized)");
+                        }
+                        if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
+                            sb.append("\n");
+                            sb.append(prefix);
+                            sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
+                            formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
+                            sb.append(" (max ");
+                            formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
+                            sb.append(")");
+                            if (unoptimizedScanTimerBg.isRunningLocked()) {
+                                sb.append(" (currently running unoptimized in background)");
+                            }
+                        }
+                    }
                     pw.println(sb.toString());
                     uidActivity = true;
                 }
@@ -4696,8 +4791,11 @@
                 sb.append(wakelocks.keyAt(iw));
                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
                         "full", which, linePrefix);
-                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
+                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+                linePrefix = printWakeLock(sb, pTimer, rawRealtime,
                         "partial", which, linePrefix);
+                linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
+                        rawRealtime, "background partial", which, linePrefix);
                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
                         "window", which, linePrefix);
                 linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f361c54..d81ee4e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1642,11 +1642,20 @@
      */
     @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE)
     @SystemApi
-    public static final int FLAG_ALLOCATE_AGGRESSIVE = 1;
+    public static final int FLAG_ALLOCATE_AGGRESSIVE = 1 << 0;
+
+    /**
+     * Flag indicating that a disk space allocation request should defy any
+     * reserved disk space.
+     *
+     * @hide
+     */
+    public static final int FLAG_ALLOCATE_DEFY_RESERVED = 1 << 1;
 
     /** @hide */
     @IntDef(flag = true, value = {
             FLAG_ALLOCATE_AGGRESSIVE,
+            FLAG_ALLOCATE_DEFY_RESERVED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface AllocateFlags {}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 5408e13..70ef035 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8915,15 +8915,11 @@
          * ambiguous then the activity should prompt the user for the recipient to send the message
          * to.
          * <p>
-         * Voice Assistant may provide additional information to messaging app about which account
-         * to use for sending a message by populating {@link #EXTRA_SENDER_ACCOUNT_HASH}.
-         * <p>
          * Output: nothing
          *
          * @see #EXTRA_RECIPIENT_CONTACT_URI
          * @see #EXTRA_RECIPIENT_CONTACT_CHAT_ID
          * @see #EXTRA_RECIPIENT_CONTACT_NAME
-         * @see #EXTRA_SENDER_ACCOUNT_HASH
          * @see #METADATA_ACCOUNT_TYPE
          * @see #METADATA_MIMETYPE
          */
@@ -8982,21 +8978,6 @@
                 "android.provider.extra.RECIPIENT_CONTACT_NAME";
 
         /**
-         * This optional extra specifies the hash of the account that should be used by messaging
-         * app for sending voice message with {@link #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS}. The
-         * value of this extra is a {@code String} and should be the value of {@link
-         * android.accounts.Account#hashCode()} for some account returned by {@link
-         * android.accounts.AccountManager#getAccounts()}.
-         * <p>
-         * If the extra is not specified, the app can decide which account to use.
-         * <p>
-         * If the account specified in the extra cannot be used for any reason (account missing, not
-         * usable by the app, etc), the message should not be sent.
-         */
-        public static final String EXTRA_SENDER_ACCOUNT_HASH =
-                "android.provider.extra.SENDER_ACCOUNT_HASH";
-
-        /**
          * A string associated with an {@link #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS} activity
          * describing {@link RawContacts#ACCOUNT_TYPE} for the corresponding Contacts Provider
          * implementation.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3cd54b8..6a17ed1 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9817,13 +9817,49 @@
         public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature";
 
         /**
-         * The duration for caching uninstalled instant apps.
+         * The min period for caching installed instant apps in milliseconds.
          * <p>
          * Type: long
          * @hide
          */
-        public static final String UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
-                "uninstalled_instant_app_cache_duration_millis";
+        public static final String INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+                "installed_instant_app_min_cache_period";
+
+        /**
+         * The max period for caching installed instant apps in milliseconds.
+         * <p>
+         * Type: long
+         * @hide
+         */
+        public static final String INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+                "installed_instant_app_max_cache_period";
+
+        /**
+         * The min period for caching uninstalled instant apps in milliseconds.
+         * <p>
+         * Type: long
+         * @hide
+         */
+        public static final String UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+                "uninstalled_instant_app_min_cache_period";
+
+        /**
+         * The max period for caching uninstalled instant apps in milliseconds.
+         * <p>
+         * Type: long
+         * @hide
+         */
+        public static final String UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+                "uninstalled_instant_app_max_cache_period";
+
+        /**
+         * The min period for caching unused static shared libs in milliseconds.
+         * <p>
+         * Type: long
+         * @hide
+         */
+        public static final String UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
+                "unused_static_shared_lib_min_cache_period";
 
         /**
          * Allows switching users when system user is locked.
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index adf4938..480abc1 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -1593,7 +1593,7 @@
         assertNotCompacted();
         final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_FIXED64);
 
-        writeRepeatedFixed64(id, val);
+        writeRepeatedFixed64Impl(id, val);
     }
 
     private void writeRepeatedFixed64Impl(int id, long val) {
@@ -1720,7 +1720,7 @@
         assertNotCompacted();
         final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_SFIXED64);
 
-        writeRepeatedSFixed64(id, val);
+        writeRepeatedSFixed64Impl(id, val);
     }
 
     private void writeRepeatedSFixed64Impl(int id, long val) {
@@ -1785,7 +1785,7 @@
         assertNotCompacted();
         final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_BOOL);
 
-        writeRepeatedBool(id, val);
+        writeRepeatedBoolImpl(id, val);
     }
 
     private void writeRepeatedBoolImpl(int id, boolean val) {
diff --git a/core/java/android/view/AppTransitionAnimationSpec.java b/core/java/android/view/AppTransitionAnimationSpec.java
index c6e1989..86a5fb7 100644
--- a/core/java/android/view/AppTransitionAnimationSpec.java
+++ b/core/java/android/view/AppTransitionAnimationSpec.java
@@ -1,6 +1,6 @@
 package android.view;
 
-import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -15,19 +15,19 @@
  */
 public class AppTransitionAnimationSpec implements Parcelable {
     public final int taskId;
-    public final Bitmap bitmap;
+    public final GraphicBuffer buffer;
     public final Rect rect;
 
-    public AppTransitionAnimationSpec(int taskId, Bitmap bitmap, Rect rect) {
+    public AppTransitionAnimationSpec(int taskId, GraphicBuffer buffer, Rect rect) {
         this.taskId = taskId;
-        this.bitmap = bitmap;
         this.rect = rect;
+        this.buffer = buffer;
     }
 
     public AppTransitionAnimationSpec(Parcel in) {
         taskId = in.readInt();
-        bitmap = in.readParcelable(null);
         rect = in.readParcelable(null);
+        buffer = in.readParcelable(null);
     }
 
     @Override
@@ -38,9 +38,8 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(taskId);
-        dest.writeParcelable(bitmap, 0 /* flags */);
         dest.writeParcelable(rect, 0 /* flags */);
-
+        dest.writeParcelable(buffer, 0);
     }
 
     public static final Parcelable.Creator<AppTransitionAnimationSpec> CREATOR
@@ -56,6 +55,6 @@
 
     @Override
     public String toString() {
-        return "{taskId: " + taskId + ", bitmap: " + bitmap + ", rect: " + rect + "}";
+        return "{taskId: " + taskId + ", buffer: " + buffer + ", rect: " + rect + "}";
     }
 }
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
index dbeb747..d2dcb56 100644
--- a/core/java/android/view/IPinnedStackController.aidl
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -30,6 +30,14 @@
     oneway void setIsMinimized(boolean isMinimized);
 
     /**
+     * Notifies the controller of the current min edge size, this is needed to allow the system to
+     * properly calculate the aspect ratio of the expanded PIP.  The given {@param minEdgeSize} is
+     * always bounded to be larger than the default minEdgeSize, so the caller can call this method
+     * with 0 to reset to the default size.
+     */
+    oneway void setMinEdgeSize(int minEdgeSize);
+
+    /**
      * @return what WM considers to be the current device rotation.
      */
     int getDisplayRotation();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a2ff4f7..58a6a5e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -26,6 +26,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -96,9 +97,9 @@
             int startHeight);
     void overridePendingAppTransitionClipReveal(int startX, int startY,
             int startWidth, int startHeight);
-    void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
+    void overridePendingAppTransitionThumb(in GraphicBuffer srcThumb, int startX, int startY,
             IRemoteCallback startedCallback, boolean scaleUp);
-    void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
+    void overridePendingAppTransitionAspectScaledThumb(in GraphicBuffer srcThumb, int startX,
             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
             boolean scaleUp);
     /**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 2c9b2e4..b57ac66 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -31,7 +31,7 @@
 import android.graphics.Region;
 import android.os.Build;
 import android.os.Handler;
-import android.os.Message;
+import android.os.Looper;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -120,34 +120,11 @@
     final Rect mTmpRect = new Rect();
     final Configuration mConfiguration = new Configuration();
 
-    static final int KEEP_SCREEN_ON_MSG = 1;
-    static final int DRAW_FINISHED_MSG = 2;
-
     int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
 
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
 
-    final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case KEEP_SCREEN_ON_MSG: {
-                    setKeepScreenOn(msg.arg1 != 0);
-                } break;
-                case DRAW_FINISHED_MSG: {
-                    mDrawFinished = true;
-                    if (mAttachedToWindow) {
-                        mParent.requestTransparentRegion(SurfaceView.this);
-
-                        notifyDrawFinished();
-                        invalidate();
-                    }
-                } break;
-            }
-        }
-    };
-
     private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
             = new ViewTreeObserver.OnScrollChangedListener() {
                     @Override
@@ -287,6 +264,22 @@
         updateSurface();
     }
 
+    private void performDrawFinished() {
+        if (mPendingReportDraws > 0) {
+            mDrawFinished = true;
+            if (mAttachedToWindow) {
+                mParent.requestTransparentRegion(SurfaceView.this);
+                
+                notifyDrawFinished();
+                invalidate();
+            }
+        } else {
+            Log.e(TAG, System.identityHashCode(this) + "finished drawing"
+                    + " but no pending report draw (extra call"
+                    + " to draw completion runnable?)");
+        }
+    }
+
     void notifyDrawFinished() {
         ViewRootImpl viewRoot = getViewRootImpl();
         if (viewRoot != null) {
@@ -751,7 +744,9 @@
             mDeferredDestroySurfaceControl = null;
         }
 
-        mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
+        runOnUiThread(() -> {
+            performDrawFinished();
+        });
     }
 
     private void setParentSpaceRectangle(Rect position, long frameNumber) {
@@ -880,6 +875,15 @@
                 + "type=" + type, new Throwable());
     }
 
+    private void runOnUiThread(Runnable runnable) {
+        Handler handler = getHandler();
+        if (handler != null && handler.getLooper() != Looper.myLooper()) {
+            handler.post(runnable);
+        } else {
+            runnable.run();
+        }
+    }
+
     /**
      * Check to see if the surface has fixed size dimensions or if the surface's
      * dimensions are dimensions are dependent on its current layout.
@@ -960,9 +964,7 @@
 
         @Override
         public void setKeepScreenOn(boolean screenOn) {
-            Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
-            msg.arg1 = screenOn ? 1 : 0;
-            mHandler.sendMessage(msg);
+            runOnUiThread(() -> SurfaceView.this.setKeepScreenOn(screenOn));
         }
 
         /**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b51e77c..a69b813 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -964,115 +964,155 @@
     private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
 
     /**
-     * This view contains an email address.
+     * Hint indicating that this view can be autofilled with an email address.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_EMAIL_ADDRESS}"
-     * to <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_EMAIL_ADDRESS}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_EMAIL_ADDRESS = "emailAddress";
 
     /**
-     * The view contains a real name.
+     * Hint indicating that this view can be autofilled with a user's real name.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_NAME}" to
-     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_NAME}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_NAME = "name";
 
     /**
-     * The view contains a user name.
+     * Hint indicating that this view can be autofilled with a username.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_USERNAME}" to
-     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_USERNAME}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_USERNAME = "username";
 
     /**
-     * The view contains a password.
+     * Hint indicating that this view can be autofilled with a password.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_PASSWORD}" to
-     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_PASSWORD}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_PASSWORD = "password";
 
     /**
-     * The view contains a phone number.
+     * Hint indicating that this view can be autofilled with a phone number.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_PHONE}" to
-     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_PHONE}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_PHONE = "phone";
 
     /**
-     * The view contains a postal address.
+     * Hint indicating that this view can be autofilled with a postal address.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_POSTAL_ADDRESS}"
-     * to <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_POSTAL_ADDRESS}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_POSTAL_ADDRESS = "postalAddress";
 
     /**
-     * The view contains a postal code.
+     * Hint indicating that this view can be autofilled with a postal code.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value #AUTOFILL_HINT_POSTAL_CODE}" to
-     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_POSTAL_CODE}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_POSTAL_CODE = "postalCode";
 
     /**
-     * The view contains a credit card number.
+     * Hint indicating that this view can be autofilled with a credit card number.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_NUMBER}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_NUMBER}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_NUMBER = "creditCardNumber";
 
     /**
-     * The view contains a credit card security code.
+     * Hint indicating that this view can be autofilled with a credit card security code.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = "creditCardSecurityCode";
 
     /**
-     * The view contains a credit card expiration date.
+     * Hint indicating that this view can be autofilled with a credit card expiration date.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>It should be used when the credit card expiration date is represented by just one view;
+     * if it is represented by more than one (for example, one view for the month and another view
+     * for the year), then each of these views should use the hint specific for the unit
+     * ({@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY},
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH},
+     * or {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR}).
+     *
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE =
             "creditCardExpirationDate";
 
     /**
-     * The view contains the month a credit card expires.
+     * Hint indicating that this view can be autofilled with a credit card expiration month.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH =
             "creditCardExpirationMonth";
 
     /**
-     * The view contains the year a credit card expires.
+     * Hint indicating that this view can be autofilled with a credit card expiration year.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR =
             "creditCardExpirationYear";
 
     /**
-     * The view contains the day a credit card expires.
+     * Hint indicating that this view can be autofilled with a credit card expiration day.
      *
-     * Use with {@link #setAutofillHints(String[])}, or set "{@value
-     * #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY}" to <a href="#attr_android:autofillHint"> {@code
-     * android:autofillHint}.
+     * <p>Can be used with either {@link #setAutofillHints(String[])} or
+     * <a href="#attr_android:autofillHint"> {@code android:autofillHint}</a> (in which case the
+     * value should be <code>{@value #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY}</code>).
+     *
+     * <p>See {@link #setAutofillHints(String...)} for more info about autofill hints.
      */
     public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = "creditCardExpirationDay";
 
@@ -7583,9 +7623,13 @@
     }
 
     /**
-     * Describes the content of a view so that a autofill service can fill in the appropriate data.
+     * Gets the hints that help an {@link android.service.autofill.AutofillService} determine how
+     * to autofill the view with the user's data.
      *
-     * @return The hints set via the attribute or {@code null} if no hint it set.
+     * <p>See {@link #setAutofillHints(String...)} for more info about these hints.
+     *
+     * @return The hints set via the attribute or {@link #setAutofillHints(String...)}, or
+     * {@code null} if no hints were set.
      *
      * @attr ref android.R.styleable#View_autofillHints
      */
@@ -9250,8 +9294,26 @@
     }
 
     /**
-     * Sets the hints that helps the autofill service to select the appropriate data to fill the
-     * view.
+     * Sets the hints that help an {@link android.service.autofill.AutofillService} determine how
+     * to autofill the view with the user's data.
+     *
+     * <p>Typically, there is only one way to autofill a view, but there could be more than one.
+     * For example, if the application accepts either an username or email address to identify
+     * an user.
+     *
+     * <p>These hints are not validated by the Android System, but passed "as is" to the service.
+     * Hence, they can have any value, but it's recommended to use the {@code AUTOFILL_HINT_}
+     * constants such as:
+     * {@link #AUTOFILL_HINT_USERNAME}, {@link #AUTOFILL_HINT_PASSWORD},
+     * {@link #AUTOFILL_HINT_EMAIL_ADDRESS},
+     * {@link #AUTOFILL_HINT_NAME},
+     * {@link #AUTOFILL_HINT_PHONE},
+     * {@link #AUTOFILL_HINT_POSTAL_ADDRESS}, {@link #AUTOFILL_HINT_POSTAL_CODE},
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_NUMBER}, {@link #AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE},
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE},
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY},
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH} or
+     * {@link #AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR}.
      *
      * @param autofillHints The autofill hints to set. If the array is emtpy, {@code null} is set.
      * @attr ref android.R.styleable#View_autofillHints
@@ -19809,18 +19871,23 @@
      * Check whether we need to draw a default focus highlight when this view gets focused,
      * which requires:
      * <ul>
-     *     <li>In the background, {@link android.R.attr#state_focused} is not defined.</li>
+     *     <li>In both background and foreground, {@link android.R.attr#state_focused}
+     *         is not defined.</li>
      *     <li>This view is not in touch mode.</li>
      *     <li>This view doesn't opt out for a default focus highlight, via
      *         {@link #setDefaultFocusHighlightEnabled(boolean)}.</li>
      *     <li>This view is attached to window.</li>
      * </ul>
      * @return {@code true} if a default focus highlight is needed.
+     * @hide
      */
-    private boolean isDefaultFocusHighlightNeeded(Drawable background) {
-        final boolean hasFocusStateSpecified = background == null || !background.isStateful()
-                || !background.hasFocusStateSpecified();
-        return !isInTouchMode() && getDefaultFocusHighlightEnabled() && hasFocusStateSpecified
+    @TestApi
+    public boolean isDefaultFocusHighlightNeeded(Drawable background, Drawable foreground) {
+        final boolean lackFocusState = (background == null || !background.isStateful()
+                || !background.hasFocusStateSpecified())
+                && (foreground == null || !foreground.isStateful()
+                || !foreground.hasFocusStateSpecified());
+        return !isInTouchMode() && getDefaultFocusHighlightEnabled() && lackFocusState
                 && isAttachedToWindow() && sUseDefaultFocusHighlight;
     }
 
@@ -19832,7 +19899,8 @@
      */
     private void switchDefaultFocusHighlight() {
         if (isFocused()) {
-            final boolean needed = isDefaultFocusHighlightNeeded(mBackground);
+            final boolean needed = isDefaultFocusHighlightNeeded(mBackground,
+                    mForegroundInfo == null ? null : mForegroundInfo.mDrawable);
             final boolean active = mDefaultFocusHighlight != null;
             if (needed && !active) {
                 setDefaultFocusHighlight(getDefaultFocusHighlightDrawable());
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 28ded55..a720aae 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2330,7 +2330,7 @@
 
         // Remember if we must report the next draw.
         if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
-            mReportNextDraw = true;
+            reportNextDraw();
         }
 
         boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
@@ -2731,11 +2731,8 @@
     /**
      * A count of the number of calls to pendingDrawFinished we
      * require to notify the WM drawing is complete.
-     *
-     * This starts at 1, for the ViewRootImpl surface itself.
-     * Subsurfaces may debt the value with drawPending.
      */
-    int mDrawsNeededToReport = 1;
+    int mDrawsNeededToReport = 0;
 
     /**
      * Delay notifying WM of draw finished until
@@ -2761,7 +2758,7 @@
 
     private void reportDrawFinished() {
         try {
-            mDrawsNeededToReport = 1;
+            mDrawsNeededToReport = 0;
             mWindowSession.finishDrawing(mWindow);
         } catch (RemoteException e) {
             // Have fun!
@@ -3772,13 +3769,12 @@
                     args.recycle();
 
                     if (msg.what == MSG_RESIZED_REPORT) {
-                        mReportNextDraw = true;
+                        reportNextDraw();
                     }
 
                     if (mView != null && framesChanged) {
                         forceLayout(mView);
                     }
-
                     requestLayout();
                 }
                 break;
@@ -7343,6 +7339,14 @@
         return false;
     }
 
+
+    private void reportNextDraw() {
+        if (mReportNextDraw == false) {
+            drawPending();
+        }
+        mReportNextDraw = true;
+    }
+
     /**
      * Force the window to report its next draw.
      * <p>
@@ -7352,7 +7356,7 @@
      * @hide
      */
     public void setReportNextDraw() {
-        mReportNextDraw = true;
+        reportNextDraw();
         invalidate();
     }
 
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index bf0e10f..55aed52 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -225,6 +225,9 @@
      */
     public abstract boolean isKeyguardLocked();
 
+    /** @return {@code true} if the keyguard is going away. */
+    public abstract boolean isKeyguardGoingAway();
+
     /**
      * Gets the frame of a window given its token.
      *
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index a2aff93..02ecc50 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -258,6 +258,11 @@
          * @return The view, or {@code null} if not found
          */
         @Nullable View findViewByAccessibilityIdTraversal(int viewId);
+
+        /**
+         * Runs the specified action on the UI thread.
+         */
+        void runOnUiThread(Runnable action);
     }
 
     /**
@@ -1233,6 +1238,15 @@
         return mService != null;
     }
 
+    private void post(Runnable runnable) {
+        final AutofillClient client = getClientLocked();
+        if (client == null) {
+            if (sVerbose) Log.v(TAG, "ignoring post() because client is null");
+            return;
+        }
+        client.runOnUiThread(runnable);
+    }
+
     /**
      * View tracking information. Once all tracked views become invisible the session is finished.
      */
@@ -1516,8 +1530,7 @@
         public void setState(boolean enabled, boolean resetSession, boolean resetClient) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(
-                        () -> afm.setState(enabled, resetSession, resetClient));
+                afm.post(() -> afm.setState(enabled, resetSession, resetClient));
             }
         }
 
@@ -1525,8 +1538,7 @@
         public void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(
-                        () -> afm.autofill(sessionId, ids, values));
+                afm.post(() -> afm.autofill(sessionId, ids, values));
             }
         }
 
@@ -1535,8 +1547,7 @@
                 Intent fillInIntent) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(
-                        () -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
+                afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
             }
         }
 
@@ -1545,9 +1556,8 @@
                 Rect anchorBounds, IAutofillWindowPresenter presenter) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(
-                        () -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds,
-                                presenter));
+                afm.post(() -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds,
+                        presenter));
             }
         }
 
@@ -1555,7 +1565,7 @@
         public void requestHideFillUi(int sessionId, AutofillId id) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(() -> afm.requestHideFillUi(id));
+                afm.post(() -> afm.requestHideFillUi(id));
             }
         }
 
@@ -1563,7 +1573,7 @@
         public void notifyNoFillUi(int sessionId, AutofillId id) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(() -> afm.notifyNoFillUi(sessionId, id));
+                afm.post(() -> afm.notifyNoFillUi(sessionId, id));
             }
         }
 
@@ -1571,7 +1581,7 @@
         public void startIntentSender(IntentSender intentSender) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(() -> {
+                afm.post(() -> {
                     try {
                         afm.mContext.startIntentSender(intentSender, null, 0, 0, 0);
                     } catch (IntentSender.SendIntentException e) {
@@ -1586,7 +1596,7 @@
                 boolean saveOnAllViewsInvisible, AutofillId[] fillableIds) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(() ->
+                afm.post(() ->
                         afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible, fillableIds)
                 );
             }
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index cd16a24..5f47638 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -16,6 +16,8 @@
 
 package android.view.autofill;
 
+import static android.view.autofill.Helper.sVerbose;
+
 import android.annotation.NonNull;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -186,6 +188,10 @@
 
     @Override
     public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
+        if (sVerbose) {
+            Log.v(TAG, "showAsDropDown(): anchor=" + anchor + ", xoff=" + xoff + ", yoff=" + yoff
+                    + ", isShowing(): " + isShowing());
+        }
         if (isShowing()) {
             return;
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 57818e2..1dc5b44 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -19,6 +19,7 @@
 import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -1640,4 +1641,13 @@
         super.encodeProperties(stream);
         stream.addProperty("layout:baseline", getBaseline());
     }
+
+    /** @hide */
+    @Override
+    @TestApi
+    public boolean isDefaultFocusHighlightNeeded(Drawable background, Drawable foreground) {
+        final boolean lackFocusState = mDrawable == null || !mDrawable.isStateful()
+                || !mDrawable.hasFocusStateSpecified();
+        return super.isDefaultFocusHighlightNeeded(background, foreground) && lackFocusState;
+    }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2f1f890..de56092 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8257,6 +8257,7 @@
      * Automatically computes and sets the text size.
      */
     private void autoSizeText() {
+        if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) return;
         final int maxWidth = getWidth() - getTotalPaddingLeft() - getTotalPaddingRight();
         final int maxHeight = getHeight() - getExtendedPaddingBottom() - getExtendedPaddingTop();
 
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 78566df..04f7c76 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -129,7 +129,7 @@
     long getAwakeTimeBattery();
     long getAwakeTimePlugged();
 
-    void noteBleScanStarted(in WorkSource ws);
+    void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
     void noteBleScanStopped(in WorkSource ws);
     void noteResetBleScan();
     void noteBleScanResults(in WorkSource ws, int numNewResults);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 31064ac..3f7e6be 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -116,7 +116,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 159 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -862,21 +862,19 @@
         final AtomicInteger mCount = new AtomicInteger();
         final TimeBase mTimeBase;
         int mLoadedCount;
-        int mLastCount;
         int mUnpluggedCount;
         int mPluggedCount;
 
-        Counter(TimeBase timeBase, Parcel in) {
+        public Counter(TimeBase timeBase, Parcel in) {
             mTimeBase = timeBase;
             mPluggedCount = in.readInt();
             mCount.set(mPluggedCount);
             mLoadedCount = in.readInt();
-            mLastCount = 0;
             mUnpluggedCount = in.readInt();
             timeBase.add(this);
         }
 
-        Counter(TimeBase timeBase) {
+        public Counter(TimeBase timeBase) {
             mTimeBase = timeBase;
             timeBase.add(this);
         }
@@ -887,11 +885,12 @@
             out.writeInt(mUnpluggedCount);
         }
 
+        @Override
         public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mUnpluggedCount = mPluggedCount;
-            mCount.set(mPluggedCount);
         }
 
+        @Override
         public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mPluggedCount = mCount.get();
         }
@@ -926,17 +925,22 @@
 
         public void logState(Printer pw, String prefix) {
             pw.println(prefix + "mCount=" + mCount.get()
-                    + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+                    + " mLoadedCount=" + mLoadedCount
                     + " mUnpluggedCount=" + mUnpluggedCount
                     + " mPluggedCount=" + mPluggedCount);
         }
 
-        void stepAtomic() {
-            mCount.incrementAndGet();
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public void stepAtomic() {
+            if (mTimeBase.isRunning()) {
+                mCount.incrementAndGet();
+            }
         }
 
         void addAtomic(int delta) {
-            mCount.addAndGet(delta);
+            if (mTimeBase.isRunning()) {
+                mCount.addAndGet(delta);
+            }
         }
 
         /**
@@ -944,7 +948,7 @@
          */
         void reset(boolean detachIfReset) {
             mCount.set(0);
-            mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
+            mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
             if (detachIfReset) {
                 detach();
             }
@@ -954,15 +958,16 @@
             mTimeBase.remove(this);
         }
 
-        void writeSummaryFromParcelLocked(Parcel out) {
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public void writeSummaryFromParcelLocked(Parcel out) {
             int count = mCount.get();
             out.writeInt(count);
         }
 
-        void readSummaryFromParcelLocked(Parcel in) {
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public void readSummaryFromParcelLocked(Parcel in) {
             mLoadedCount = in.readInt();
             mCount.set(mLoadedCount);
-            mLastCount = 0;
             mUnpluggedCount = mPluggedCount = mLoadedCount;
         }
     }
@@ -998,7 +1003,6 @@
         @Override
         public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
             mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
-            mCounts = copyArray(mPluggedCounts, mCounts);
         }
 
         @Override
@@ -1029,11 +1033,13 @@
             if (counts == null) {
                 return;
             }
-            if (mCounts == null) {
-                mCounts = new long[counts.length];
-            }
-            for (int i = 0; i < counts.length; ++i) {
-                mCounts[i] += counts[i];
+            if (mTimeBase.isRunning()) {
+                if (mCounts == null) {
+                    mCounts = new long[counts.length];
+                }
+                for (int i = 0; i < counts.length; ++i) {
+                    mCounts[i] += counts[i];
+                }
             }
         }
 
@@ -1104,13 +1110,13 @@
             }
         }
 
-        private void fillArray(long[] a, long val) {
+        private static void fillArray(long[] a, long val) {
             if (a != null) {
                 Arrays.fill(a, val);
             }
         }
 
-        private void subtract(@NonNull long[] val, long[] toSubtract) {
+        private static void subtract(@NonNull long[] val, long[] toSubtract) {
             if (toSubtract == null) {
                 return;
             }
@@ -1119,7 +1125,7 @@
             }
         }
 
-        private long[] copyArray(long[] src, long[] dest) {
+        private static long[] copyArray(long[] src, long[] dest) {
             if (src == null) {
                 return null;
             } else {
@@ -1162,7 +1168,6 @@
         @Override
         public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mUnpluggedCount = mPluggedCount;
-            mCount = mPluggedCount;
         }
 
         @Override
@@ -1189,7 +1194,9 @@
         }
 
         void addCountLocked(long count) {
-            mCount += count;
+            if (mTimeBase.isRunning()) {
+                mCount += count;
+            }
         }
 
         /**
@@ -4821,7 +4828,7 @@
         }
     }
 
-    private void noteBluetoothScanStartedLocked(int uid) {
+    private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) {
         uid = mapUid(uid);
         final long elapsedRealtime = mClocks.elapsedRealtime();
         final long uptime = mClocks.uptimeMillis();
@@ -4833,13 +4840,13 @@
             mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
         }
         mBluetoothScanNesting++;
-        getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime);
+        getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
     }
 
-    public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws) {
+    public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
         final int N = ws.size();
         for (int i = 0; i < N; i++) {
-            noteBluetoothScanStartedLocked(ws.get(i));
+            noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized);
         }
     }
 
@@ -5611,7 +5618,9 @@
         /** Total time spent by the uid holding any partial wakelocks. */
         DualTimer mAggregatedPartialWakelockTimer;
         DualTimer mBluetoothScanTimer;
+        DualTimer mBluetoothUnoptimizedScanTimer;
         Counter mBluetoothScanResultCounter;
+        Counter mBluetoothScanResultBgCounter;
 
         int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
         StopwatchTimer[] mProcessStateTimer;
@@ -6096,20 +6105,41 @@
             return mBluetoothScanTimer;
         }
 
-        public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) {
+        public DualTimer createBluetoothUnoptimizedScanTimerLocked() {
+            if (mBluetoothUnoptimizedScanTimer == null) {
+                mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
+                        BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
+                        mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
+            }
+            return mBluetoothUnoptimizedScanTimer;
+        }
+
+        public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
             createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
+            if (isUnoptimized) {
+                createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
+            }
         }
 
         public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) {
             if (mBluetoothScanTimer != null) {
                 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
+            // In the ble code, a scan cannot change types and nested starts are not possible.
+            // So if an unoptimizedScan is running, it is now being stopped.
+            if (mBluetoothUnoptimizedScanTimer != null
+                    && mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
+                mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
+            }
         }
 
         public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
             if (mBluetoothScanTimer != null) {
                 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
             }
+            if (mBluetoothUnoptimizedScanTimer != null) {
+                mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
+            }
         }
 
         public Counter createBluetoothScanResultCounterLocked() {
@@ -6119,8 +6149,17 @@
             return mBluetoothScanResultCounter;
         }
 
+        public Counter createBluetoothScanResultBgCounterLocked() {
+            if (mBluetoothScanResultBgCounter == null) {
+                mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase);
+            }
+            return mBluetoothScanResultBgCounter;
+        }
+
         public void noteBluetoothScanResultsLocked(int numNewResults) {
             createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
+            // Uses background timebase, so the count will only be incremented if uid in background.
+            createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
         }
 
         @Override
@@ -6277,10 +6316,28 @@
         }
 
         @Override
+        public Timer getBluetoothUnoptimizedScanTimer() {
+            return mBluetoothUnoptimizedScanTimer;
+        }
+
+        @Override
+        public Timer getBluetoothUnoptimizedScanBackgroundTimer() {
+            if (mBluetoothUnoptimizedScanTimer == null) {
+                return null;
+            }
+            return mBluetoothUnoptimizedScanTimer.getSubTimer();
+        }
+
+        @Override
         public Counter getBluetoothScanResultCounter() {
             return mBluetoothScanResultCounter;
         }
 
+        @Override
+        public Counter getBluetoothScanResultBgCounter() {
+            return mBluetoothScanResultBgCounter;
+        }
+
         void makeProcessState(int i, Parcel in) {
             if (i < 0 || i >= NUM_PROCESS_STATE) return;
 
@@ -6531,9 +6588,13 @@
             active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
             active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
             active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
+            active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
             if (mBluetoothScanResultCounter != null) {
                 mBluetoothScanResultCounter.reset(false);
             }
+            if (mBluetoothScanResultBgCounter != null) {
+                mBluetoothScanResultBgCounter.reset(false);
+            }
 
             if (mProcessStateTimer != null) {
                 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
@@ -6731,10 +6792,18 @@
                     mBluetoothScanTimer.detach();
                     mBluetoothScanTimer = null;
                 }
+                if (mBluetoothUnoptimizedScanTimer != null) {
+                    mBluetoothUnoptimizedScanTimer.detach();
+                    mBluetoothUnoptimizedScanTimer = null;
+                }
                 if (mBluetoothScanResultCounter != null) {
                     mBluetoothScanResultCounter.detach();
                     mBluetoothScanResultCounter = null;
                 }
+                if (mBluetoothScanResultBgCounter != null) {
+                    mBluetoothScanResultBgCounter.detach();
+                    mBluetoothScanResultBgCounter = null;
+                }
                 if (mUserActivityCounters != null) {
                     for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
                         mUserActivityCounters[i].detach();
@@ -6919,12 +6988,24 @@
             } else {
                 out.writeInt(0);
             }
+            if (mBluetoothUnoptimizedScanTimer != null) {
+                out.writeInt(1);
+                mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
+            } else {
+                out.writeInt(0);
+            }
             if (mBluetoothScanResultCounter != null) {
                 out.writeInt(1);
                 mBluetoothScanResultCounter.writeToParcel(out);
             } else {
                 out.writeInt(0);
             }
+            if (mBluetoothScanResultBgCounter != null) {
+                out.writeInt(1);
+                mBluetoothScanResultBgCounter.writeToParcel(out);
+            } else {
+                out.writeInt(0);
+            }
             for (int i = 0; i < NUM_PROCESS_STATE; i++) {
                 if (mProcessStateTimer[i] != null) {
                     out.writeInt(1);
@@ -7033,7 +7114,8 @@
             for (int j = 0; j < numWakelocks; j++) {
                 String wakelockName = in.readString();
                 Uid.Wakelock wakelock = new Wakelock(mBsi, this);
-                wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
+                wakelock.readFromParcelLocked(
+                        timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
                 mWakelockStats.add(wakelockName, wakelock);
             }
 
@@ -7168,10 +7250,22 @@
                 mBluetoothScanTimer = null;
             }
             if (in.readInt() != 0) {
+                mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
+                        BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
+                        mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
+            } else {
+                mBluetoothUnoptimizedScanTimer = null;
+            }
+            if (in.readInt() != 0) {
                 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
             } else {
                 mBluetoothScanResultCounter = null;
             }
+            if (in.readInt() != 0) {
+                mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
+            } else {
+                mBluetoothScanResultBgCounter = null;
+            }
             mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
             for (int i = 0; i < NUM_PROCESS_STATE; i++) {
                 if (in.readInt() != 0) {
@@ -7298,8 +7392,9 @@
 
             /**
              * How long (in ms) this uid has been keeping the device partially awake.
+             * Tracks both the total time and the time while the app was in the background.
              */
-            DurationTimer mTimerPartial;
+            DualTimer mTimerPartial;
 
             /**
              * How long (in ms) this uid has been keeping the device fully awake.
@@ -7344,13 +7439,13 @@
              * @param in the Parcel to be read from.
              * return a new Timer, or null.
              */
-            private DurationTimer readDurationTimerFromParcel(int type,
-                    ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) {
+            private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
+                    TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
                 if (in.readInt() == 0) {
                     return null;
                 }
 
-                return new DurationTimer(mBsi.mClocks, mUid, type, pool, timeBase, in);
+                return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
             }
 
             boolean reset() {
@@ -7388,9 +7483,10 @@
                 return !wlactive;
             }
 
-            void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
-                mTimerPartial = readDurationTimerFromParcel(WAKE_TYPE_PARTIAL,
-                        mBsi.mPartialTimers, screenOffTimeBase, in);
+            void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase,
+                    TimeBase screenOffBgTimeBase, Parcel in) {
+                mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL,
+                        mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in);
                 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL,
                         mBsi.mFullTimers, timeBase, in);
                 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW,
@@ -7416,49 +7512,6 @@
                 default: throw new IllegalArgumentException("type = " + type);
                 }
             }
-
-            public StopwatchTimer getStopwatchTimer(int type) {
-                switch (type) {
-                    case WAKE_TYPE_PARTIAL: {
-                        DurationTimer t = mTimerPartial;
-                        if (t == null) {
-                            t = new DurationTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL,
-                                    mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase);
-                            mTimerPartial = t;
-                        }
-                        return t;
-                    }
-                    case WAKE_TYPE_FULL: {
-                        StopwatchTimer t = mTimerFull;
-                        if (t == null) {
-                            t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL,
-                                    mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
-                            mTimerFull = t;
-                        }
-                        return t;
-                    }
-                    case WAKE_TYPE_WINDOW: {
-                        StopwatchTimer t = mTimerWindow;
-                        if (t == null) {
-                            t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW,
-                                    mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
-                            mTimerWindow = t;
-                        }
-                        return t;
-                    }
-                    case WAKE_TYPE_DRAW: {
-                        StopwatchTimer t = mTimerDraw;
-                        if (t == null) {
-                            t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW,
-                                    mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
-                            mTimerDraw = t;
-                        }
-                        return t;
-                    }
-                    default:
-                        throw new IllegalArgumentException("type=" + type);
-                }
-            }
         }
 
         public static class Sensor extends BatteryStats.Uid.Sensor {
@@ -8351,16 +8404,16 @@
             Wakelock wl = new Wakelock(mBsi, this);
             mWakelockStats.add(wlName, wl);
             if (in.readInt() != 0) {
-                wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
+                getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
-                wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
+                getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
-                wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
+                getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
-                wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
+                getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
             }
         }
 
@@ -8416,10 +8469,57 @@
             }
         }
 
+        public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) {
+            if (wl == null) {
+                return null;
+            }
+            switch (type) {
+                case WAKE_TYPE_PARTIAL: {
+                    DualTimer t = wl.mTimerPartial;
+                    if (t == null) {
+                        t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL,
+                                mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase,
+                                mOnBatteryScreenOffBackgroundTimeBase);
+                        wl.mTimerPartial = t;
+                    }
+                    return t;
+                }
+                case WAKE_TYPE_FULL: {
+                    StopwatchTimer t = wl.mTimerFull;
+                    if (t == null) {
+                        t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL,
+                                mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
+                        wl.mTimerFull = t;
+                    }
+                    return t;
+                }
+                case WAKE_TYPE_WINDOW: {
+                    StopwatchTimer t = wl.mTimerWindow;
+                    if (t == null) {
+                        t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW,
+                                mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
+                        wl.mTimerWindow = t;
+                    }
+                    return t;
+                }
+                case WAKE_TYPE_DRAW: {
+                    StopwatchTimer t = wl.mTimerDraw;
+                    if (t == null) {
+                        t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW,
+                                mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
+                        wl.mTimerDraw = t;
+                    }
+                    return t;
+                }
+                default:
+                    throw new IllegalArgumentException("type=" + type);
+            }
+        }
+
         public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
             Wakelock wl = mWakelockStats.startObject(name);
             if (wl != null) {
-                wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
+                getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
             }
             if (type == WAKE_TYPE_PARTIAL) {
                 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
@@ -8435,7 +8535,7 @@
         public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
             Wakelock wl = mWakelockStats.stopObject(name);
             if (wl != null) {
-                wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
+                getWakelockTimerLocked(wl, type).stopRunningLocked(elapsedRealtimeMs);
             }
             if (type == WAKE_TYPE_PARTIAL) {
                 if (mAggregatedPartialWakelockTimer != null) {
@@ -11380,8 +11480,14 @@
                 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
+                u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in);
+            }
+            if (in.readInt() != 0) {
                 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
             }
+            if (in.readInt() != 0) {
+                u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in);
+            }
             u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
             for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
                 if (in.readInt() != 0) {
@@ -11789,12 +11895,24 @@
             } else {
                 out.writeInt(0);
             }
+            if (u.mBluetoothUnoptimizedScanTimer != null) {
+                out.writeInt(1);
+                u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+            } else {
+                out.writeInt(0);
+            }
             if (u.mBluetoothScanResultCounter != null) {
                 out.writeInt(1);
                 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
             } else {
                 out.writeInt(0);
             }
+            if (u.mBluetoothScanResultBgCounter != null) {
+                out.writeInt(1);
+                u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out);
+            } else {
+                out.writeInt(0);
+            }
             for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
                 if (u.mProcessStateTimer[i] != null) {
                     out.writeInt(1);
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index ce89501..66b777e 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -31,7 +31,7 @@
  */
 public final class DumpUtils {
     private static final String TAG = "DumpUtils";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private DumpUtils() {
     }
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 369bb7f..785fd2c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -16,7 +16,7 @@
 
 #define ATRACE_TAG ATRACE_TAG_DALVIK
 #define LOG_TAG "AndroidRuntime"
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 1
 
 #include <android_runtime/AndroidRuntime.h>
 #include <binder/IBinder.h>
@@ -661,7 +661,7 @@
             checkJni = true;
         }
     }
-    ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
+    ALOGV("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
     if (checkJni) {
         /* extended JNI checking */
         addOption("-Xcheck:jni");
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index b6b1ac7..18cf8ca 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -15,7 +15,7 @@
 ** limitations under the License.
 */
 
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 1
 #define LOG_TAG "Radio-JNI"
 #include <utils/Log.h>
 
@@ -955,7 +955,7 @@
 
     int ret = RegisterMethodsOrDie(env, kRadioModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
 
-    ALOGI("%s DONE", __FUNCTION__);
+    ALOGV("%s DONE", __FUNCTION__);
 
     return ret;
 }
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 8b73daf..e212c43 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -310,7 +310,7 @@
     SettingProto lte_service_forced = 265;
     SettingProto ephemeral_cookie_max_size_bytes = 266;
     SettingProto enable_ephemeral_feature = 267;
-    SettingProto uninstalled_ephemeral_app_cache_duration_millis = 268;
+    SettingProto installed_instant_app_min_cache_period = 268;
     SettingProto allow_user_switching_when_system_user_locked = 269;
     SettingProto boot_count = 270;
     SettingProto safe_boot_disallowed = 271;
@@ -331,6 +331,10 @@
     SettingProto network_recommendations_package = 286;
     SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
     SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
+    SettingProto installed_instant_app_max_cache_period = 289;
+    SettingProto uninstalled_instant_app_min_cache_period = 290;
+    SettingProto uninstalled_instant_app_max_cache_period = 291;
+    SettingProto unused_static_shared_lib_min_cache_period = 292;
 }
 
 message SecureSettingsProto {
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3c42334..7e5a081 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -703,7 +703,7 @@
     <string name="relationTypeFriend" msgid="7313106762483391262">"صديق"</string>
     <string name="relationTypeManager" msgid="6365677861610137895">"مدير"</string>
     <string name="relationTypeMother" msgid="4578571352962758304">"أم"</string>
-    <string name="relationTypeParent" msgid="4755635567562925226">"الأبوان"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"الوالدان"</string>
     <string name="relationTypePartner" msgid="7266490285120262781">"شريك"</string>
     <string name="relationTypeReferredBy" msgid="101573059844135524">"جهة الإحالة"</string>
     <string name="relationTypeRelative" msgid="1799819930085610271">"قريب"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 649cadd..06e6020 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -28,15 +28,15 @@
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sati"</string>
-    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sat"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
     <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
-    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
-    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
     <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
-    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
-    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
     <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c644866..c5774cf 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1116,7 +1116,7 @@
     <string name="wifi_no_internet" msgid="8451173622563841546">"La Wi-Fi no té accés a Internet"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toca per veure les opcions"</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
-    <string name="network_switch_metered_detail" msgid="5325661434777870353">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'apliquin càrrecs."</string>
+    <string name="network_switch_metered_detail" msgid="5325661434777870353">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"dades mòbils"</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index e7f9a7f..d2f8ecf 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -291,7 +291,7 @@
     <string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 및 동영상 촬영"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
-    <string name="permgrouplab_sensors" msgid="416037179223226722">"신체 센서"</string>
+    <string name="permgrouplab_sensors" msgid="416037179223226722">"인체 감지 센서"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
@@ -381,7 +381,7 @@
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"앱에서 수신 및 발신 통화 데이터를 포함하여 TV의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 삭제하거나 수정할 수도 있습니다."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"신체 센서(예: 심박수 모니터)에 액세스"</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"인체 감지 센서(예: 심박수 모니터)에 액세스"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"앱이 심박수와 같은 신체 상태를 확인하는 센서의 데이터에 접근하도록 허용합니다."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"캘린더 일정 및 세부정보 읽기"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"이 앱은 태블릿에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 69fe42f..0d5f04a 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -213,7 +213,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Подготовка обновлений…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Обработка обновлений…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Перезагрузка…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сбросить все данные"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сброс к заводским настройкам"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Перезагрузка…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 51d932d..eb9994a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -152,8 +152,8 @@
     <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> หลังผ่านไป <xliff:g id="TIME_DELAY">{2}</xliff:g> วินาที"</string>
     <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ไม่ได้โอนสาย"</string>
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ไม่ได้โอนสาย"</string>
-    <string name="fcComplete" msgid="3118848230966886575">"รหัสคุณลักษณะเสร็จสมบูรณ์"</string>
-    <string name="fcError" msgid="3327560126588500777">"พบปัญหาในการเชื่อมต่อหรือรหัสคุณลักษณะไม่ถูกต้อง"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"รหัสฟีเจอร์เสร็จสมบูรณ์"</string>
+    <string name="fcError" msgid="3327560126588500777">"พบปัญหาในการเชื่อมต่อหรือรหัสฟีเจอร์ไม่ถูกต้อง"</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ตกลง"</string>
     <string name="httpError" msgid="7956392511146698522">"เกิดข้อผิดพลาดของเครือข่าย"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"ไม่พบ URL"</string>
@@ -414,7 +414,7 @@
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"เข้าถึงบริการโทร IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"อนุญาตให้แอปใช้บริการ IMS เพื่อโทรออกโดยคุณไม่ต้องดำเนินการใดๆ เลย"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"อ่านสถานะและข้อมูลระบุตัวตนของโทรศัพท์"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงคุณลักษณะโทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงฟีเจอร์โทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"กำหนดเส้นทางการโทรผ่านระบบ"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"อนุญาตให้แอปกำหนดเส้นทางการโทรของแอปผ่านระบบเพื่อปรับปรุงประสบการณ์ในการโทร"</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"อ่านหมายเลขโทรศัพท์"</string>
@@ -586,8 +586,8 @@
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ข้อมูลของแอปพลิเคชันที่จัดเก็บต้องมีการเข้ารหัส"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"ปิดใช้งานกล้องถ่ายรูป"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"ป้องกันการใช้กล้องถ่ายรูปของอุปกรณ์ทั้งหมด"</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ปิดคุณลักษณะล็อกหน้าจอบางอย่าง"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ป้องกันการใช้คุณลักษณะบางอย่างของการล็อกหน้าจอ"</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ปิดฟีเจอร์ล็อกหน้าจอบางอย่าง"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ป้องกันการใช้ฟีเจอร์บางอย่างของการล็อกหน้าจอ"</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"บ้าน"</item>
     <item msgid="869923650527136615">"มือถือ"</item>
@@ -722,7 +722,7 @@
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"ถูกต้อง!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"ลองอีกครั้ง"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"ลองอีกครั้ง"</string>
-    <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ปลดล็อกคุณลักษณะและข้อมูลทั้งหมด"</string>
+    <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ปลดล็อกฟีเจอร์และข้อมูลทั้งหมด"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"มีความพยายามที่จะใช้ Face Unlock เกินขีดจำกัด"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ไม่มีซิมการ์ด"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ไม่มีซิมการ์ดในแท็บเล็ต"</string>
@@ -842,7 +842,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"อนุญาตให้แอปแก้ไขประวัติของเบราว์เซอร์หรือบุ๊กมาร์กที่เก็บไว้ในทีวี ซึ่งอาจอนุญาตให้แอปลบหรือแก้ไขข้อมูลเบราว์เซอร์ หมายเหตุ: สิทธิ์นี้ไม่สามารถใช้ได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นที่สามารถท่องเว็บได้"</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงประวัติหรือบุ๊กมาร์กของเบราว์เซอร์ที่จัดเก็บไว้ในโทรศัพท์ ซึ่งทำให้แอปพลิเคชันสามารถลบหรือเปลี่ยนข้อมูลเบราว์เซอร์ได้ หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นๆ ที่มีความสามารถในการเรียกดูบนเว็บ"</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"ตั้งปลุก"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้คุณลักษณะนี้"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้ฟีเจอร์นี้"</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"เพิ่มข้อวามเสียง"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"อนุญาตให้แอปพลิเคชันเพิ่มข้อความลงในกล่องข้อความเสียงของคุณ"</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"แก้ไขการอนุญาตเกี่ยวกับการระบุตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์"</string>
@@ -1206,7 +1206,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> แสดงทับแอปอื่นๆ"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> กำลังแสดงทับแอปอื่นๆ"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้คุณลักษณะนี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดคุณลักษณะ"</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ปิด"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"กำลังเตรียม <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"กำลังตรวจหาข้อผิดพลาด"</string>
@@ -1480,13 +1480,13 @@
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ลบ"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"ใช้ทางลัดการเข้าถึงพิเศษไหม"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มคุณลักษณะการเข้าถึงพิเศษ\n\n คุณลักษณะการเข้าถึงพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนคุณลักษณะในการตั้งค่า &gt; การเข้าถึงพิเศษ"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มฟีเจอร์การเข้าถึงพิเศษ\n\n ฟีเจอร์การเข้าถึงพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนฟีเจอร์ในการตั้งค่า &gt; การเข้าถึงพิเศษ"</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"ปิดทางลัด"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"ใช้ทางลัด"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ทางลัดการเข้าถึงเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ทางลัดการเข้าถึงปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกคุณลักษณะที่จะใช้เมื่อคุณแตะปุ่ม \"การเข้าถึงพิเศษ\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนคุณลักษณะ ให้แตะปุ่ม \"การเข้าถึงพิเศษ\" ค้างไว้"</string>
+    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่ม \"การเข้าถึงพิเศษ\":"</string>
+    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนฟีเจอร์ ให้แตะปุ่ม \"การเข้าถึงพิเศษ\" ค้างไว้"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"การขยาย"</string>
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1708,7 +1708,7 @@
     <string name="region_picker_section_all" msgid="8966316787153001779">"ภูมิภาคทั้งหมด"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"ค้นหา"</string>
     <string name="work_mode_off_title" msgid="2615362773958585967">"เปิดโหมดงานไหม"</string>
-    <string name="work_mode_off_message" msgid="2961559609199223594">"การดำเนินการนี้จะเปิดโปรไฟล์งานของคุณ รวมถึงแอป การซิงค์ในพื้นหลัง และคุณลักษณะที่เกี่ยวข้อง"</string>
+    <string name="work_mode_off_message" msgid="2961559609199223594">"การดำเนินการนี้จะเปิดโปรไฟล์งานของคุณ รวมถึงแอป การซิงค์ในพื้นหลัง และฟีเจอร์ที่เกี่ยวข้อง"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"เปิด"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"คุณมีข้อความใหม่"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"เปิดแอป SMS เพื่อดู"</string>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 7517946..8755e37 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -758,6 +758,14 @@
         <item name="colorControlNormal">?attr/textColorPrimary</item>
     </style>
 
+    <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
+        <!-- Color palette -->
+        <item name="colorPrimary">@color/primary_device_default_settings_light</item>
+        <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
+        <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
+        <item name="colorAccent">@color/accent_device_default_light</item>
+    </style>
+
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
     <style name="Theme.DeviceDefault.Settings.Dark.NoActionBar" parent="Theme.Material.NoActionBar">
         <!-- Color palette -->
diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
index 15dbddf..59aa50a 100644
--- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
@@ -492,7 +492,7 @@
             PackageDataObserver observer = new PackageDataObserver();
             //wait on observer
             synchronized(observer) {
-                getPm().freeStorageAndNotify(null, idealStorageSize, observer);
+                getPm().freeStorageAndNotify(null, idealStorageSize, 0, observer);
                 long waitTime = 0;
                 while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
                     observer.wait(WAIT_TIME_INCR);
@@ -517,7 +517,7 @@
         try {
             // Spin lock waiting for call back
             synchronized(r) {
-                getPm().freeStorage(null, idealStorageSize, pi.getIntentSender());
+                getPm().freeStorage(null, idealStorageSize, 0, pi.getIntentSender());
                 long waitTime = 0;
                 while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) {
                     r.wait(WAIT_TIME_INCR);
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 54d5285..d875ed4 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -334,7 +334,11 @@
                     Settings.Global.TRUSTED_SOUND,
                     Settings.Global.TZINFO_UPDATE_CONTENT_URL,
                     Settings.Global.TZINFO_UPDATE_METADATA_URL,
-                    Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
+                    Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                    Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                    Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                    Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                    Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
                     Settings.Global.UNLOCK_SOUND,
                     Settings.Global.USE_GOOGLE_MAIL,
                     Settings.Global.VT_IMS_ENABLED,
diff --git a/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java b/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
index fd57baa..115af5e 100644
--- a/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
@@ -180,7 +180,9 @@
 
         try {
             table.getValue(key);
-            throw new Exception("Exception not thrown after mismatched reset calls.");
+            // Turn off this assertion because the check in SparseMappingTable.assertConsistency
+            // is also turned off.
+            //throw new Exception("Exception not thrown after mismatched reset calls.");
         } catch (RuntimeException ex) {
             // Good
         }
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index 9aabdbb..c539f78 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -205,9 +205,9 @@
         // App in foreground
         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
 
-        // Start timer
+        // Start timer (optimized)
         curr = 1000 * (clocks.realtime = clocks.uptime = 202);
-        bi.noteBluetoothScanStartedFromSourceLocked(ws);
+        bi.noteBluetoothScanStartedFromSourceLocked(ws, false);
 
         // Move to background
         curr = 1000 * (clocks.realtime = clocks.uptime = 254);
@@ -221,21 +221,44 @@
         curr = 1000 * (clocks.realtime = clocks.uptime = 409);
         bi.noteBluetoothScanStoppedFromSourceLocked(ws);
 
+        // Start timer (unoptimized)
+        curr = 1000 * (clocks.realtime = clocks.uptime = 1000);
+        bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
+
+        // On battery
+        curr = 1000 * (clocks.realtime = clocks.uptime = 2001);
+        bi.updateTimeBasesLocked(true, false, curr, curr); // on battery
+
+        // Move to foreground
+        curr = 1000 * (clocks.realtime = clocks.uptime = 3004);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+
+        // Stop timer
+        curr = 1000 * (clocks.realtime = clocks.uptime = 4008);
+        bi.noteBluetoothScanStoppedFromSourceLocked(ws);
+
         // Test
-        curr = 1000 * (clocks.realtime = clocks.uptime = 657);
+        curr = 1000 * (clocks.realtime = clocks.uptime = 5000);
         BatteryStats.Timer timer = bi.getUidStats().get(UID).getBluetoothScanTimer();
         BatteryStats.Timer bgTimer = bi.getUidStats().get(UID).getBluetoothScanBackgroundTimer();
+        BatteryStats.Timer badTimer = bi.getUidStats().get(UID).getBluetoothUnoptimizedScanTimer();
+        BatteryStats.Timer badBgTimer = bi.getUidStats().get(UID)
+                .getBluetoothUnoptimizedScanBackgroundTimer();
 
         long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED);
         int count = timer.getCountLocked(STATS_SINCE_CHARGED);
         int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED);
         long actualTime = timer.getTotalDurationMsLocked(clocks.realtime) * 1000;
         long bgTime = bgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
-        assertEquals((305 - 202) * 1000, time);
-        assertEquals(1, count);
-        assertEquals(0, bgCount);
-        assertEquals((305 - 202) * 1000, actualTime);
-        assertEquals((305 - 254) * 1000, bgTime);
+        long badTime = badTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
+        long badBgTime = badBgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
+        assertEquals((305 - 202 + 4008 - 2001) * 1000, time);
+        assertEquals(1, count); // second scan starts off-battery
+        assertEquals(0, bgCount); // first scan starts in fg, second starts off-battery
+        assertEquals((305 - 202 + 4008 - 2001) * 1000, actualTime);
+        assertEquals((305 - 254 + 3004 - 2001) * 1000, bgTime);
+        assertEquals((4008 - 2001) * 1000, badTime);
+        assertEquals((3004 - 2001) * 1000, badBgTime);
     }
 
     @SmallTest
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java
new file mode 100644
index 0000000..08f8dd1
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.internal.os;
+
+import android.os.BatteryStats;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Test BatteryStatsImpl.Counter.
+ */
+public class BatteryStatsCounterTest extends TestCase {
+
+    @SmallTest
+    public void testCounter() throws Exception {
+        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+        final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
+        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+        final BatteryStatsImpl.Counter counter = new BatteryStatsImpl.Counter(timeBase);
+
+        // timeBase off (i.e. plugged in)
+        timeBase.setRunning(false, 1, 1);
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase on (i.e. unplugged)
+        timeBase.setRunning(true, 2, 2);
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase off (i.e. plugged in)
+        timeBase.setRunning(false, 3, 3);
+        counter.stepAtomic();
+        counter.stepAtomic();
+        counter.stepAtomic();
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase on (i.e. unplugged)
+        timeBase.setRunning(true, 4, 4);
+        counter.stepAtomic();
+        counter.stepAtomic();
+        assertEquals(6, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(6, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(2, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+    }
+
+
+    @SmallTest
+    public void testParceling() throws Exception {
+        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+        final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
+        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+        final BatteryStatsImpl.Counter origCounter = new BatteryStatsImpl.Counter(timeBase);
+
+        // timeBase on (i.e. unplugged)
+        timeBase.setRunning(true, 1, 1);
+        origCounter.stepAtomic(); origCounter.stepAtomic(); origCounter.stepAtomic(); // three times
+        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // Test summary parcelling (from origCounter)
+        final Parcel summaryParcel = Parcel.obtain();
+        origCounter.writeSummaryFromParcelLocked(summaryParcel);
+        summaryParcel.setDataPosition(0);
+        final BatteryStatsImpl.Counter summaryCounter = new BatteryStatsImpl.Counter(timeBase);
+        summaryCounter.stepAtomic(); // occurs before reading the summary, so must not count later
+        summaryCounter.readSummaryFromParcelLocked(summaryParcel);
+
+        // timeBase still on (i.e. unplugged)
+        summaryCounter.stepAtomic(); // once
+        assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase off (i.e. plugged in)
+        timeBase.setRunning(false, 3, 3);
+        summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
+        assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase on (i.e. unplugged)
+        timeBase.setRunning(true, 4, 4);
+        summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
+        assertEquals(6, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(3, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(2, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+
+        // Test full parcelling (from summaryCounter)
+        final Parcel fullParcel = Parcel.obtain();
+        summaryCounter.writeToParcel(fullParcel);
+        fullParcel.setDataPosition(0);
+        final BatteryStatsImpl.Counter fullParcelCounter
+                = new BatteryStatsImpl.Counter(timeBase, fullParcel);
+
+        // timeBase still on (i.e. unplugged)
+        fullParcelCounter.stepAtomic(); // once
+        assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase off (i.e. plugged in)
+        timeBase.setRunning(false, 5, 5);
+        fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
+        assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+        // timeBase on (i.e. unplugged)
+        timeBase.setRunning(true, 6, 6);
+        fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
+        assertEquals(9, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+        assertEquals(6, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+        assertEquals(2, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 06ca18d..4e8ab31 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -37,12 +37,28 @@
     public void testNoteBluetoothScanResultLocked() throws Exception {
         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
         bi.updateTimeBasesLocked(true, true, 0, 0);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
 
         bi.noteBluetoothScanResultsFromSourceLocked(WS, 1);
         bi.noteBluetoothScanResultsFromSourceLocked(WS, 100);
         assertEquals(101,
                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
                         .getCountLocked(STATS_SINCE_CHARGED));
+        // TODO: remove next line when Counter misreporting values when plugged-in bug is fixed.
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter();
+        if (bgCntr != null) {
+            assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED));
+        }
+
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        bi.noteBluetoothScanResultsFromSourceLocked(WS, 17);
+        assertEquals(101 + 17,
+                bi.getUidStats().get(UID).getBluetoothScanResultCounter()
+                        .getCountLocked(STATS_SINCE_CHARGED));
+        assertEquals(17,
+                bi.getUidStats().get(UID).getBluetoothScanResultBgCounter()
+                        .getCountLocked(STATS_SINCE_CHARGED));
     }
 
     /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 3a16fcf..1412d3e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -5,17 +5,18 @@
 
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
+        BatteryStatsBackgroundStatsTest.class,
+        BatteryStatsCounterTest.class,
         BatteryStatsDualTimerTest.class,
         BatteryStatsDurationTimerTest.class,
+        BatteryStatsNoteTest.class,
         BatteryStatsSamplingTimerTest.class,
+        BatteryStatsSensorTest.class,
         BatteryStatsServTest.class,
         BatteryStatsStopwatchTimerTest.class,
         BatteryStatsTimeBaseTest.class,
         BatteryStatsTimerTest.class,
         BatteryStatsUidTest.class,
-        BatteryStatsSensorTest.class,
-        BatteryStatsBackgroundStatsTest.class,
-        BatteryStatsNoteTest.class,
     })
 public class BatteryStatsTests {
 }
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index e62df8f..e3b4740 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -529,6 +529,7 @@
         setTextLocales(LocaleList.getAdjustedDefault());
         setElegantTextHeight(false);
         mFontFeatureSettings = null;
+        mFontVariationSettings = null;
     }
 
     /**
@@ -565,6 +566,7 @@
         mBidiFlags = paint.mBidiFlags;
         mLocales = paint.mLocales;
         mFontFeatureSettings = paint.mFontFeatureSettings;
+        mFontVariationSettings = paint.mFontVariationSettings;
     }
 
     /** @hide */
@@ -1594,10 +1596,13 @@
             return true;
         }
 
+        // The null typeface is valid and it is equivalent to Typeface.DEFAULT.
+        // To call isSupportedAxes method, use Typeface.DEFAULT instance.
+        Typeface targetTypeface = mTypeface == null ? Typeface.DEFAULT : mTypeface;
         FontVariationAxis[] axes = FontVariationAxis.fromFontVariationSettings(settings);
         final ArrayList<FontVariationAxis> filteredAxes = new ArrayList<FontVariationAxis>();
         for (final FontVariationAxis axis : axes) {
-            if (mTypeface.isSupportedAxes(axis.getOpenTypeTagValue())) {
+            if (targetTypeface.isSupportedAxes(axis.getOpenTypeTagValue())) {
                 filteredAxes.add(axis);
             }
         }
@@ -1605,7 +1610,7 @@
             return false;
         }
         mFontVariationSettings = settings;
-        setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface, filteredAxes));
+        setTypeface(Typeface.createFromTypefaceWithVariation(targetTypeface, filteredAxes));
         return true;
     }
 
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5a56f53..c4b56c3 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -725,8 +725,8 @@
     }
 
     /** @hide */
-    public static Typeface createFromTypefaceWithVariation(Typeface family,
-            List<FontVariationAxis> axes) {
+    public static Typeface createFromTypefaceWithVariation(@Nullable Typeface family,
+            @NonNull List<FontVariationAxis> axes) {
         final long ni = family == null ? 0 : family.native_instance;
         return new Typeface(nativeCreateFromTypefaceWithVariation(ni, axes));
     }
@@ -1056,7 +1056,7 @@
                 }
             }
         }
-        return Arrays.binarySearch(mSupportedAxes, axis) > 0;
+        return Arrays.binarySearch(mSupportedAxes, axis) >= 0;
     }
 
     private static native long nativeCreateFromTypeface(long native_instance, int style);
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 39f11b8..4ee47af 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -61,8 +61,17 @@
 static void clipOutline(const Outline& outline, SkCanvas* canvas, const SkRect* pendingClip) {
     Rect possibleRect;
     float radius;
-    LOG_ALWAYS_FATAL_IF(!outline.getAsRoundRect(&possibleRect, &radius),
-            "clipping outlines should be at most roundedRects");
+
+    /* To match the existing HWUI behavior we only supports rectangles or
+     * rounded rectangles; passing in a more complicated outline fails silently.
+     */
+    if (!outline.getAsRoundRect(&possibleRect, &radius)) {
+        if (pendingClip) {
+            canvas->clipRect(*pendingClip);
+        }
+        return;
+    }
+
     SkRect rect = possibleRect.toSkRect();
     if (radius != 0.0f) {
         if (pendingClip && !pendingClip->contains(rect)) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index 34fdc9d..a8f6f02 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -63,15 +63,17 @@
         public long audioBytes;
         public long videoBytes;
         public long imageBytes;
+        public long appBytes;
 
         /** Convenience method for testing. */
         @VisibleForTesting
         public ExternalStorageStats(
-                long totalBytes, long audioBytes, long videoBytes, long imageBytes) {
+                long totalBytes, long audioBytes, long videoBytes, long imageBytes, long appBytes) {
             this.totalBytes = totalBytes;
             this.audioBytes = audioBytes;
             this.videoBytes = videoBytes;
             this.imageBytes = imageBytes;
+            this.appBytes = appBytes;
         }
 
         /**
@@ -84,6 +86,7 @@
             audioBytes = stats.getAudioBytes();
             videoBytes = stats.getVideoBytes();
             imageBytes = stats.getImageBytes();
+            appBytes = stats.getAppBytes();
         }
     }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 9309359..b328933 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -888,8 +888,20 @@
                 Settings.Global.ENABLE_EPHEMERAL_FEATURE,
                 GlobalSettingsProto.ENABLE_EPHEMERAL_FEATURE);
         dumpSetting(s, p,
-                Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
-                GlobalSettingsProto.UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS);
+                Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
+        dumpSetting(s, p,
+                Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+        dumpSetting(s, p,
+                Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                GlobalSettingsProto.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
+        dumpSetting(s, p,
+                Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                GlobalSettingsProto.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+        dumpSetting(s, p,
+                Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
+                GlobalSettingsProto.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD);
         dumpSetting(s, p,
                 Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED,
                 GlobalSettingsProto.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED);
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 1ddbcad..348b02a 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -966,17 +966,24 @@
         }
 
         final Intent notifIntent;
+        boolean useChooser = true;
 
         // Send through warning dialog by default
         if (getWarningState(mContext, STATE_UNKNOWN) != STATE_HIDE) {
             notifIntent = buildWarningIntent(mContext, sendIntent);
+            // No need to show a chooser in this case.
+            useChooser = false;
         } else {
             notifIntent = sendIntent;
         }
         notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
         // Send the share intent...
-        sendShareIntent(mContext, notifIntent);
+        if (useChooser) {
+            sendShareIntent(mContext, notifIntent);
+        } else {
+            mContext.startActivity(notifIntent);
+        }
 
         // ... and stop watching this process.
         stopProgress(id);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 79b02a5..c4e134b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -531,7 +531,7 @@
         <activity
             android:name=".settings.BrightnessDialog"
             android:label="@string/quick_settings_brightness_dialog_title"
-            android:theme="@android:style/Theme.DeviceDefault.Light.Dialog"
+            android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
             android:finishOnCloseSystemDialogs="true"
             android:launchMode="singleInstance"
             android:excludeFromRecents="true"
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
deleted file mode 100644
index 195849a..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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="32.0dp"
-        android:height="32dp"
-        android:viewportWidth="12.0"
-        android:viewportHeight="12.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M8.600000,5.500000l1.200000,-3.000000l1.900000,0.000000L9.700000,6.700000l2.200000,4.300000L9.900000,11.000000L8.700000,7.900000L7.400000,11.000000L5.500000,11.000000l2.100000,-4.300000L5.600000,2.500000l1.900000,0.000000L8.600000,5.500000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
deleted file mode 100644
index 68c4307..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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="32dp"
-        android:height="32dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.700000,9.000000 6.700000,7.900000L6.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.400000,5.000000 8.400000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.799999,7.800000L9.600000,7.800000L9.600000,6.600000l2.900000,0.000000L12.500000,9.900000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
deleted file mode 100644
index 61ecc9c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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="32.0dp"
-        android:height="32dp"
-        android:viewportWidth="12.0"
-        android:viewportHeight="12.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M11.900000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.100000,9.000000 6.100000,7.900000L6.100000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000S8.100000,2.400000 9.000000,2.400000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S9.500000,3.700000 9.000000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S7.700000,5.000000 7.700000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.099999,7.800000L9.000000,7.800000L9.000000,6.600000l2.900000,0.000000L11.900000,9.900000z"/>
-</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
deleted file mode 100644
index 782fbe4..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
+++ /dev/null
@@ -1,30 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="32.0dp"
-        android:viewportWidth="19.0"
-        android:viewportHeight="19.0">
-    <path
-        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="#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="#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_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
deleted file mode 100644
index dd5843d..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 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:autoMirrored="true"
-        android:width="32dp"
-        android:height="32dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.799999,22.299999l-1.199999,-1.299999 0.000000,0.000000 -9.600000,-10.000000 0.000000,0.000000 -6.400000,-6.700000 -1.300000,1.300000 6.400000,6.700000 -8.700000,8.700000 16.900000,0.000000 2.600000,2.700001z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M21.000000,1.000000l-8.600000,8.600000 8.600000,9.100000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
deleted file mode 100644
index 4232126..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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="32dp"
-        android:height="32dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
-  <group
-    android:translateX="3.5" >
-    <path
-      android:fillColor="#FFFFFFFF"
-      android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
-  </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
deleted file mode 100644
index 0c512d7..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 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="32dp"
-        android:height="32dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
-    <group android:translateX="3.5" >
-      <path
-          android:fillColor="#FFFFFFFF"
-          android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
deleted file mode 100644
index b9572b2..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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="32dp"
-        android:height="32dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
-      <group
-        android:translateX="3.5" >
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
-      </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
deleted file mode 100644
index a381d03e..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-Copyright (C) 2014 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="32dp"
-        android:height="32dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="13.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M2.000000,9.700000l2.000000,0.000000L4.000000,11.000000L0.300000,11.000000L0.300000,2.500000L2.000000,2.500000L2.000000,9.700000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M8.300000,3.800000L7.000000,3.800000L7.000000,11.000000L5.300000,11.000000L5.300000,3.800000L4.000000,3.800000L4.000000,2.500000l4.300000,0.000000L8.300000,3.800000z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.400000,7.300000l-1.700000,0.000000l0.000000,2.400000l2.100000,0.000000L12.799999,11.000000L9.000000,11.000000L9.000000,2.500000l3.700000,0.000000l0.000000,1.300000l-2.100000,0.000000l0.000000,2.100000l1.700000,0.000000L12.300000,7.300000z"/>
-</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
deleted file mode 100644
index 3bed28a..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
+++ /dev/null
@@ -1,33 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="32.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/qs_footer.xml b/packages/SystemUI/res/layout/qs_footer.xml
index 577be2f..871d1f3 100644
--- a/packages/SystemUI/res/layout/qs_footer.xml
+++ b/packages/SystemUI/res/layout/qs_footer.xml
@@ -27,6 +27,7 @@
     android:clipChildren="false"
     android:clipToPadding="false"
     android:paddingTop="0dp"
+    android:background="#00000000"
     android:gravity="center_vertical"
     android:orientation="horizontal">
 
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 005e955..66c5dd5 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -29,7 +29,6 @@
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:paddingBottom="48dp"
     android:paddingTop="0dp"
     android:paddingEnd="0dp"
     android:paddingStart="0dp">
@@ -83,10 +82,9 @@
     <com.android.systemui.qs.QuickQSPanel
         android:id="@+id/quick_qs_panel"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_alignParentEnd="true"
-        android:layout_marginTop="36dp"
-        android:layout_marginBottom="8dp"
+        android:layout_marginTop="31dp"
         android:layout_alignParentTop="true"
         android:accessibilityTraversalAfter="@+id/date_time_group"
         android:accessibilityTraversalBefore="@id/expand_indicator"
@@ -95,8 +93,7 @@
         android:layout_marginStart="8dp"
         android:layout_marginEnd="8dp"
         android:focusable="true"
-        android:importantForAccessibility="yes"
-        android:paddingTop="0dp"/>
+        android:importantForAccessibility="yes" />
 
     <com.android.systemui.statusbar.AlphaOptimizedImageView
         android:id="@+id/qs_detail_header_progress"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 36ceff5..3fce776 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minute"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ONTDOEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Sluimer vir <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batterygebruik"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index f9edd7c..a217d3c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ደቂቃዎች"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 ደቂቃዎች"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ሰዓት"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ቀልብስ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ለ<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> አሸልቧል"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"የባትሪ አጠቃቀም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4ab49a0..1c1fbbc 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -589,6 +589,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"١٥ دقيقة"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"٣۰ دقيقة"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"ساعة واحدة"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"تراجع"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"تم تأجيل الإشعار لمدة <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"استخدام البطارية"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index aca6a3b..24b71e7 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dəqiqə"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 dəqiqə"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ QAYTARIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> üçün təxirə salınıb"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya istifadəsi"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 29a5e19..f460730 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -577,6 +577,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 15f1d86..dfad96c 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвілін"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвілін"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 гадзіна"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"АДРАБІЦЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Адкладзена на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Выкарыстанне зараду"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b77cc9e..be327135 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЯНА"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ползв. на батерията"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index b9fa325..822652b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"১৫ মিনিট"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"৩০ মিনিট"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"১ ঘণ্টা"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"পূর্বাবস্থায় ফিরুন"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 11450ae..e4e02d7 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -579,6 +579,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 16f2a32..c9254ef 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuts"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuts"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESFÉS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ús de la bateria"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index f4a45c2..2ad9dba 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hodina"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"VRÁTIT ZPĚT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo o <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Využití baterie"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 55b39d5..e2852dd 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"FORTRYD"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Udsat i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriforbrug"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index bc7f1d5..b0b4323 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 Minuten"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 Minuten"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 Stunde"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"RÜCKGÄNGIG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Erinnerung in <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkunutzung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bbefef4..5d87034 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 λεπτά"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 λεπτά"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ώρα"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ΑΝΑΙΡΕΣΗ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Σε αφύπνιση για <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Χρήση της μπαταρίας"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 2561d29..05c4130 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 2561d29..05c4130 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 2561d29..05c4130 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 64a4bfe..07b564d 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posponer <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8d9f8a5..3bf6a8c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Volverá a mostrarse en <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 604d266..26b4603 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutit"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutit"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"Üks tund"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"VÕTA TAGASI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Edasi lükatud <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akukasutus"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2c83e5b..86fd3b2 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutu"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutu"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ordu"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESEGIN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>z atzeratu da"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Bateriaren erabilera"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 1f49e98..5570f9e 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"۱۵ دقیقه"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"۳۰ دقیقه"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"۱ ساعت"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"واگرد"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> به تعویق افتاد"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"مصرف باتری"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f5b0b6b..c60c4c4 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuuttia"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuuttia"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 tunti"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"KUMOA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Torkku: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akun käyttö"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e615ff4..10b0cba 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Reporté pour <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation de la pile"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 811b16c..862d13f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Répétée après <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilisation batterie"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 7481d1a..0cb91b4 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESFACER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiouse <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso de batería"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index ca7a779..7f718d9 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 મિનિટ"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 મિનિટ"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 કલાક"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"પૂર્વવત્ કરો"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"બૅટરી વપરાશ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 92bc82e..613d8d3 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनट"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनट"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 घंटा"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"पहले जैसा करें"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"बैटरी उपयोग"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2065b8c..e716f5d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -577,6 +577,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"PONIŠTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d1e85d9..fe1b12b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 perc"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 perc"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 óra"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"VISSZAVONÁS"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Elhalasztva: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akkumulátorhasználat"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1189b05..bdceafe 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 րոպե"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 րոպե"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ժամ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ՀԵՏԱՐԿԵԼ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Հետաձգվել է <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ով"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Մարտկոցի օգտագործում"</string>
diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml
index ac7711b..0493584 100644
--- a/packages/SystemUI/res/values-hy/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy/strings_tv.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Նկարը նկարի մեջ"</string>
+    <string name="notification_channel_tv_pip" msgid="134047986446577723">"Նկար նկարի մեջ"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Առանց վերնագրի ծրագիր)"</string>
     <string name="pip_close" msgid="3480680679023423574">"Փակել PIP-ն"</string>
     <string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 25a2a14..2853d9d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 menit"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 menit"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"URUNG"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Pemakaian baterai"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index d2b9787..f56720a 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 mínútur"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 mínútur"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 klukkustund"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"AFTURKALLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Rafhlöðunotkun"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 01b2464..cfe5deb 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuti"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuti"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANNULLA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Posticipato di <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizzo batteria"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b7e9508..4b1236e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -581,6 +581,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 דקות"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 דקות"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"שעה אחת"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ביטול"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"נדחה לטיפול בעוד <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"שימוש בסוללה"</string>
@@ -638,7 +640,7 @@
     <string name="headset" msgid="4534219457597457353">"אוזניות"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"אוזניות מחוברות"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"אוזניות מחוברות"</string>
-    <string name="data_saver" msgid="5037565123367048522">"‏חוסך הנתונים&lt;br&gt;(Data Saver)"</string>
+    <string name="data_saver" msgid="5037565123367048522">"‏חוסך הנתונים (Data Saver)"</string>
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"‏חוסך הנתונים (Data Saver) פועל"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"‏חוסך הנתונים (Data Saver) כבוי"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"פועל"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 15fccc6..4c7c85e 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15分"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30分"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1時間"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"元に戻す"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"スヌーズ: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池の使用状況"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 17320ef..d8cbc19 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 წუთი"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 წუთი"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 საათი"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"მოქმედების გაუქმება"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ჩაჩუმებული იქნება <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ბატარეის მოხმარება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 724af88..f71601e 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сағат"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"КЕРІ ҚАЙТАРУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> кідіртілді"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Батареяны пайдалану"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 229e345..9aed689 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 នាទី"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 នាទី"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ម៉ោង"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"មិន​ធ្វើវិញ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"បាន​ផ្អាក​រយៈពេល <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ការប្រើប្រាស់ថ្ម"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 9c87cf7..cd85f74 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ನಿಮಿಷಗಳು"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 ನಿಮಿಷಗಳು"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ಗಂಟೆ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ರದ್ದುಮಾಡಿ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ಬ್ಯಾಟರಿ ಬಳಕೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 273b390..a237ba9 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15분"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30분"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1시간"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"실행취소"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> 동안 일시 중지됨"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"배터리 사용량"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 209d38d..1127c24 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 мүнөт"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 мүнөт"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 саат"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"КАЙТАРУУ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> тындырылды"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Батарея колдонулушу"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 5369583..42baec6 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ນາທີ"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 ນາທີ"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ຊົ່ວໂມງ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ຍົກເລີກ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ເລື່ອນໄປ <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ນາທີແລ້ວ"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ການໃຊ້ແບັດເຕີຣີ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index cc123cf..ce403ef 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -581,6 +581,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min."</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 min."</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 val."</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANULIUOTI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Nustatyta snausti <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akum. energ. vartoj."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 9bd3c65..28758ca 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -577,6 +577,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minūtes"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minūtes"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 stunda"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ATSAUKT"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Atlikts: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Akumulatora lietojums"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 519cfac..3355090 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ВРАТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Користење батерија"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index a7aa20a..a41e305 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 മിനിറ്റ്"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 മിനിറ്റ്"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"ഒരു മണിക്കൂർ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"പഴയപടിയാക്കുക"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്‌നൂസ് ‌ചെയ്‌തു"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ബാറ്ററി ഉപയോഗം"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 7144c28..3a33cd6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 цаг"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"БУЦААХ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>-д түр хойшлуулсан"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Тэжээл ашиглалт"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f7360c9..ad107d8 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनिटे"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनिटे"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 तास"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"पूर्ववत करा"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> साठी स्नूझ करा"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"बॅटरी वापर"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index a05dd2b..898cdfc 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minit"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minit"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"BUAT ASAL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Penggunaan bateri"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 797aa97..346bbe2 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"၁၅ မိနစ်"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"၃၀ မိနစ်"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"၁ နာရီ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"တစ်ဆင့် နောက်ပြန်ပြန်ပါ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ဆိုင်းငံ့ရန်"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ဘက်ထရီ အသုံးပြုမှု"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f59367f..a13c097 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANGRE"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Slumrer i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteribruk"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index fb49b17..c8cd383 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"१५ मिनेट"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"३० मिनेट"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"१ घन्टा"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"अनडू गर्नुहोस्"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> का लागि स्नुज गरियो"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ब्याट्री उपयोग"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b708e66..78077e9 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuten"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuten"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ONGEDAAN MAKEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 1039e34..07a0e82 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 ਮਿੰਟ"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 ਮਿੰਟ"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ਘੰਟਾ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ਲਈ ਸਨੂਜ਼ ਕੀਤਾ ਗਿਆ"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"ਬੈਟਰੀ ਵਰਤੋਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 91a7c09..03b5ed9 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -581,6 +581,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 min"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 min"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 godz."</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"COFNIJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odłożono na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Wykorzystanie baterii"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ab705e7..8ef330b 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 74089b2..49f1480 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -444,29 +444,29 @@
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"A sua entidade instalou uma autoridade de certificação no seu perfil de trabalho. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
     <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"Está instalada uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
     <string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"O administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo."</string>
-    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Está ligado às redes <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>, que podem monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"O seu perfil de trabalho está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"O seu perfil pessoal está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
+    <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Está ligado às redes <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>, que podem monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"O seu perfil de trabalho está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"O seu perfil pessoal está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"O seu dispositivo é gerido pelo <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> utiliza o <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> para gerir o seu dispositivo."</string>
     <string name="monitoring_description_do_body" msgid="3639594537660975895">"O administ. pode monitorizar e gerir definições, acesso empresarial, aplic. e dados associados ao dispositivo, bem como inf. de localiz. do disp."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"Saiba mais"</string>
-    <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
+    <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Abrir as definições de VPN"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Abrir credenciais fidedignas"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"O seu administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo.\n\nPara obter mais informações, contacte o administrador."</string>
-    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Concedeu autorização a uma aplicação para configurar uma ligação VPN.\n\nEsta aplicação pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu administrador tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Websites.\n\nPara obter mais informações, contacte o administrador.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Concedeu autorização a uma aplicação para configurar uma ligação VPN.\n\nEsta aplicação pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu administrador tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Sites.\n\nPara obter mais informações, contacte o administrador.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
-    <string name="monitoring_description_app" msgid="1828472472674709532">"Está associado à aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Websites."</string>
-    <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Websites."</string>
-    <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Websites.\n\nContacte o administrador para obter mais informações."</string>
-    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Websites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
+    <string name="monitoring_description_app" msgid="1828472472674709532">"Está associado à aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
+    <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
+    <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o administrador para obter mais informações."</string>
+    <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
     <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até ser desbloqueado manualmente"</string>
     <string name="hidden_notifications_title" msgid="7139628534207443290">"Receber notificações mais rapidamente"</string>
     <string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAR"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Suspensa por <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utiliz. da bateria"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ab705e7..8ef330b 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index cadce25..29bc5bf 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -579,6 +579,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 de minute"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oră"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ANULAȚI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Amânată <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Utilizarea bateriei"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 34939b5..e593f89 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ОТМЕНИТЬ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Отложено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Уровень заряда"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 7065c83..991be52 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"මිනිත්තු 15"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"මිනිත්තු 30"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"පැය 1"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"අස් කරන්න"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ක් මදක් නතර කරන ලදී"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"බැටරි භාවිතය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6e4c33b..33793ce 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minút"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minút"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hod."</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"SPÄŤ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Stlmené na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Využitie batérie"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b0e770f..9e03e42 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ura"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"RAZVELJAVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Preloženo za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Poraba akumulatorja"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a68ec87..cbdb5b2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 orë"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ZHBËJ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"U shty për <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Përdorimi i baterisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f4b488422..5c47907 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -577,6 +577,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 минута"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 минута"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сат"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ОПОЗОВИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Потрошња батерије"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 685c0a4..967e3a5 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuter"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuter"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 timme"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ÅNGRA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozad i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batteriförbrukning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9a52d9b..8222074 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"Dakika 15"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"Dakika 30"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"Saa 1"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"TENDUA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Imeahirishwa kwa <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Matumizi ya betri"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 1c4b7de..eb672e1 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 நிமிடங்கள்"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 நிமிடங்கள்"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 மணிநேரம்"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"செயல்தவிர்"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"உறக்கநிலையில் வைத்திருந்த நேரம்: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"பேட்டரி உபயோகம்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2bdabd2..b5470e7 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 నిమిషాలు"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 నిమిషాలు"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 గంట"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"చర్య రద్దు చేయి"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> వరకు తాత్కాలికంగా ఆపివేయబడింది"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"బ్యాటరీ వినియోగం"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8077d14..f47cfa9 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -64,7 +64,7 @@
     <string name="usb_debugging_message" msgid="2220143855912376496">"ลายนิ้วมือหลัก RSA ของคอมพิวเตอร์คือ:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"อนุญาตจากคอมพิวเตอร์เครื่องนี้เสมอ"</string>
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน USB"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์นี้อยู่ในขณะนี้ไม่สามารถเปิดการแก้ปัญหาผ่าน USB ได้ หากต้องการใช้คุณลักษณะนี้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่เป็นผู้ดูแลระบบ"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์นี้อยู่ในขณะนี้ไม่สามารถเปิดการแก้ปัญหาผ่าน USB ได้ หากต้องการใช้ฟีเจอร์นี้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่เป็นผู้ดูแลระบบ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"กำลังบันทึกภาพหน้าจอ..."</string>
@@ -524,12 +524,12 @@
     <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ฮอตสปอต"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"โปรไฟล์งาน"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string>
-    <string name="tuner_warning" msgid="8730648121973575701">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
-    <string name="tuner_persistent_warning" msgid="8597333795565621795">"คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
+    <string name="tuner_persistent_warning" msgid="8597333795565621795">"ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
     <string name="got_it" msgid="2239653834387972602">"รับทราบ"</string>
     <string name="tuner_toast" msgid="603429811084428439">"ยินดีด้วย! เพิ่มตัวรับสัญญาณ UI ระบบไปยังการตั้งค่าแล้ว"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"นำออกจากการตั้งค่า"</string>
-    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้คุณลักษณะทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้ฟีเจอร์ทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
     <string name="activity_not_found" msgid="348423244327799974">"ยังไม่ได้ติดตั้งแอปพลิเคชันบนอุปกรณ์ของคุณ"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"แสดงวินาทีของนาฬิกา"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string>
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 นาที"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 นาที"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ชั่วโมง"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"เลิกทำ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"ปิดเสียงเตือนชั่วคราวไว้เป็นเวลา <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"การใช้งานแบตเตอรี่"</string>
@@ -719,7 +721,7 @@
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ลากลงเพื่อปิด"</string>
     <string name="pip_menu_title" msgid="3328510504196964712">"เมนูการแสดงผลหลายแหล่งพร้อมกัน"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงผลหลายแหล่งพร้อมกัน"</string>
-    <string name="pip_notification_message" msgid="4171698133469539591">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้คุณลักษณะนี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดคุณลักษณะ"</string>
+    <string name="pip_notification_message" msgid="4171698133469539591">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
     <string name="pip_play" msgid="1417176722760265888">"เล่น"</string>
     <string name="pip_pause" msgid="8881063404466476571">"หยุดชั่วคราว"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"ข้ามไปรายการถัดไป"</string>
@@ -728,7 +730,7 @@
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"ขณะนี้โทรศัพท์ทำงานเป็นปกติ"</string>
     <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"โทรศัพท์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้โทรศัพท์ทำงานเป็นปกติ\n\nโทรศัพท์อาจร้อนเกินไปหากคุณ\n	• ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n	• ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n	• ใช้โทรศัพท์ในอุณหภูมิที่สูง"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"โทรศัพท์เริ่มเครื่องร้อน"</string>
-    <string name="high_temp_notif_message" msgid="5642466103153429279">"คุณลักษณะบางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์ลดอุณหภูมิลง"</string>
+    <string name="high_temp_notif_message" msgid="5642466103153429279">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์ลดอุณหภูมิลง"</string>
     <string name="high_temp_dialog_message" msgid="6840700639374113553">"โทรศัพท์จะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้โทรศัพท์ได้ แต่โทรศัพท์อาจทำงานช้าลง\n\nโทรศัพท์จะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
     <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"ทางลัดทางซ้าย"</string>
     <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"ทางลัดทางขวา"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 194b161..3304ab7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuto"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 minuto"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oras"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"I-UNDO"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Na-snooze ng <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Paggamit ng baterya"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7f1d8ff..944316c 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 dakika"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 dakika"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"GERİ AL"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> süreyle ertelendi"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Pil kullanımı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 1006eae..5636a87 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -583,6 +583,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвилин"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 хвилин"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 годину"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"ВІДМІНИТИ"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Відкладено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Використання заряду"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 9f28494..7a5f1c7 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 منٹ"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 منٹ"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 گھنٹہ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"کالعدم کریں"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"بیٹری کا استعمال"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 02f7c43..262225c 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -201,7 +201,7 @@
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Parvoz rejimi o‘chirildi."</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Parvoz rejimi yoqildi."</string>
     <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"“Bezovta qilinmasin” funksiyasi yoqilgan, faqat muhim bildirishnomalar ko‘rsatiladi."</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Bezovta qilinmasin, tinchlik saqlansin"</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Bezovta qilinmasin, jimjitlik."</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"Bezovta qilinmasin, faqat signallar"</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Bezovta qilinmasin."</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"“Bezovta qilinmasin” funksiyasi o‘chirilgan."</string>
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 daqiqa"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 daqiqa"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 soat"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"BEKOR QILISH"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> muddatga kechiktirildi"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Batareya sarfi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 167d0a1..1d125f6 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 phút"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 phút"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 giờ"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"HOÀN TÁC"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Báo lại sau <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Mức sử dụng pin"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cf9b7d2..600e17d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分钟"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 分钟"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小时"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"撤消"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延后 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"电池使用情况"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index d123c93..109c33e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -575,6 +575,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index af7ed48..353d985 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -268,7 +268,7 @@
     <string name="ethernet_label" msgid="7967563676324087464">"乙太網路"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"零打擾"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"僅限優先通知"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅允許鬧鐘"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅限鬧鐘"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"完全靜音"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"藍牙"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"藍牙 (<xliff:g id="NUMBER">%d</xliff:g> 個裝置)"</string>
@@ -369,7 +369,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"完全靜音。這也會關閉螢幕閱讀器的音訊。"</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"完全靜音"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"僅限優先通知"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"僅允許鬧鐘"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"僅限鬧鐘"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅允許\n優先通知"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅允許\n鬧鐘"</string>
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index c1765c6..d81c320 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -573,6 +573,8 @@
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 amaminithi"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 amaminithi"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ihora"</string>
+    <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+    <skip />
     <string name="snooze_undo" msgid="6074877317002985129">"HLEHLISA"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Kusnuzwe u-<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Ukusetshenziswa kwebhethri"</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f0ff22d..db1e8a9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -147,8 +147,10 @@
         mClockView.setLayoutParams(layoutParams);
         mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
-        mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
+        if (mOwnerInfo != null) {
+            mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
+        }
     }
 
     public void refreshTime() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index c35fdd5..854696e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -716,9 +716,15 @@
      * Updates the current movement bounds based on whether the menu is currently visible.
      */
     private void updateMovementBounds(int menuState) {
-        mMovementBounds = menuState == MENU_STATE_FULL
+        boolean isMenuExpanded = menuState == MENU_STATE_FULL;
+        mMovementBounds = isMenuExpanded
                 ? mExpandedMovementBounds
                 : mNormalMovementBounds;
+        try {
+            mPinnedStackController.setMinEdgeSize(isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not set minimized state", e);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 149b5cc..0d74b7a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -58,6 +58,16 @@
         mBackground = findViewById(R.id.qs_background);
         mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
         mFullElevation = mQSPanel.getElevation();
+
+        setClickable(true);
+        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+    }
+
+    @Override
+    public boolean performClick() {
+        // Want to receive clicks so missing QQS tiles doesn't cause collapse, but
+        // don't want to do anything with them.
+        return true;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 87b042d..682c56c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -101,6 +101,8 @@
     private boolean mShowEditIcon;
     private TouchAnimator mAnimator;
     private View mDateTimeGroup;
+    private boolean mKeyguardShowing;
+    private TouchAnimator mAlarmAnimator;
 
     public QSFooter(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -163,13 +165,14 @@
         int remaining = (width - numTiles * size) / (numTiles - 1);
         int defSpace = mContext.getResources().getDimensionPixelOffset(R.dimen.default_gear_space);
 
-        final Builder builder = new Builder()
+        mAnimator = new Builder()
                 .addFloat(mSettingsContainer, "translationX", -(remaining - defSpace), 0)
                 .addFloat(mSettingsButton, "rotation", -120, 0)
-                .addFloat(mAlarmStatus, "alpha", 0, 1);
+                .build();
         if (mAlarmShowing) {
-            builder.addFloat(mDate, "alpha", 1, 0)
+            mAlarmAnimator = new Builder().addFloat(mDate, "alpha", 1, 0)
                     .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth())
+                    .addFloat(mAlarmStatus, "alpha", 0, 1)
                     .setListener(new ListenerAdapter() {
                         @Override
                         public void onAnimationAtStart() {
@@ -180,13 +183,13 @@
                         public void onAnimationStarted() {
                             mAlarmStatus.setVisibility(View.VISIBLE);
                         }
-                    });
+                    }).build();
         } else {
+            mAlarmAnimator = null;
             mAlarmStatus.setVisibility(View.GONE);
             mDate.setAlpha(1);
             mDateTimeGroup.setTranslationX(0);
         }
-        mAnimator = builder.build();
         setExpansion(mExpansionAmount);
     }
 
@@ -248,6 +251,11 @@
         return animatorBuilder.build();
     }
 
+    public void setKeyguardShowing(boolean keyguardShowing) {
+        mKeyguardShowing = keyguardShowing;
+        setExpansion(mExpansionAmount);
+    }
+
     public void setExpanded(boolean expanded) {
         if (mExpanded == expanded) return;
         mExpanded = expanded;
@@ -275,6 +283,8 @@
     public void setExpansion(float headerExpansionFraction) {
         mExpansionAmount = headerExpansionFraction;
         if (mAnimator != null) mAnimator.setPosition(headerExpansionFraction);
+        if (mAlarmAnimator != null) mAlarmAnimator.setPosition(
+                mKeyguardShowing ? 0 : headerExpansionFraction);
 
         if (mSettingsAlpha != null) {
             mSettingsAlpha.setPosition(headerExpansionFraction);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 61fd624..c9c3a7f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -222,6 +222,7 @@
             mQSAnimator.setOnKeyguard(keyguardShowing);
         }
 
+        mFooter.setKeyguardShowing(keyguardShowing);
         updateQsState();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 8539cb9..00b883a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -60,6 +60,12 @@
         mTileLayout = new HeaderTileLayout(context);
         mTileLayout.setListening(mListening);
         addView((View) mTileLayout, 0 /* Between brightness and footer */);
+        super.setPadding(0, 0, 0, 0);
+    }
+
+    @Override
+    public void setPadding(int left, int top, int right, int bottom) {
+        // Always have no padding.
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index e457d72..abafd64 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -23,13 +23,11 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.RelativeLayout;
-import android.widget.TextClock;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.R.id;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSDetail.Callback;
 import com.android.systemui.statusbar.SignalClusterView;
@@ -79,7 +77,7 @@
         battery.setForceShowPercent(true);
         // Don't show the Wi-Fi indicator here, because it is shown just below in the tile.
         SignalClusterView signalCluster = findViewById(R.id.signal_cluster);
-        signalCluster.setForceBlockWifi();
+        signalCluster.setQsSignalCluster();
 
         mActivityStarter = Dependency.get(ActivityStarter.class);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 1afce64..76f6e7d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -353,13 +353,20 @@
 
         private void updateItems() {
             if (mItems == null) return;
-            if (mSignalCallback.mInfo.enabled) {
-                mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
-                        R.string.quick_settings_wifi_detail_empty_text);
-            } else {
+
+            // Wi-Fi is off
+            if (!mSignalCallback.mInfo.enabled) {
                 mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
                         R.string.wifi_is_off);
+                mItems.setItems(null);
+                return;
             }
+
+            // No available access points
+            mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
+                    R.string.quick_settings_wifi_detail_empty_text);
+
+            // Build the list
             Item[] items = null;
             if (mAccessPoints != null) {
                 items = new Item[mAccessPoints.length];
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index e2e9b1b..611169f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -30,6 +30,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
@@ -239,8 +240,6 @@
         }
     });
 
-    protected Bitmap mThumbTransitionBitmapCache;
-
     public RecentsImpl(Context context) {
         mContext = context;
         mHandler = new Handler();
@@ -775,14 +774,6 @@
                 }
                 mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
             }
-
-            // Update the transition bitmap to match the new header bar height
-            if (mThumbTransitionBitmapCache == null ||
-                    (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
-                    (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
-                mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
-                        mTaskBarHeight, Bitmap.Config.ARGB_8888);
-            }
         }
     }
 
@@ -864,8 +855,7 @@
                     mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
                             stackScroller.getStackScroll(), mTmpTransform, null,
                             windowOverrideRect);
-                    Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
-                            mThumbTransitionBitmapCache);
+                    GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform);
                     Rect toTaskRect = new Rect();
                     mTmpTransform.rect.round(toTaskRect);
                     specs.add(new AppTransitionAnimationSpec(task.key.id, thumbnail, toTaskRect));
@@ -887,8 +877,8 @@
                             () -> {
                         Rect rect = new Rect();
                         toTaskRect.round(rect);
-                        Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
-                                mThumbTransitionBitmapCache);
+                        GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(toTask,
+                                toTransform);
                         return Lists.newArrayList(new AppTransitionAnimationSpec(
                                 toTask.key.id, thumbnail, rect));
                     });
@@ -924,19 +914,19 @@
     /**
      * Draws the header of a task used for the window animation into a bitmap.
      */
-    private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform,
-            Bitmap thumbnail) {
+    private GraphicBuffer drawThumbnailTransitionBitmap(Task toTask,
+            TaskViewTransform toTransform) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (toTransform != null && toTask.key != null) {
             synchronized (mHeaderBarLock) {
                 boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
-                mHeaderBar.onTaskViewSizeChanged((int) toTransform.rect.width(),
-                        (int) toTransform.rect.height());
+                int width = (int) toTransform.rect.width();
+                int height = (int) toTransform.rect.height();
+                mHeaderBar.onTaskViewSizeChanged(width, height);
                 if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-                    thumbnail.eraseColor(0xFFff0000);
+                    return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
+                            null, 1f, 0xFFff0000);
                 } else {
-                    thumbnail.eraseColor(0);
-                    Canvas c = new Canvas(thumbnail);
                     // Workaround for b/27815919, reset the callback so that we do not trigger an
                     // invalidate on the header bar as a result of updating the icon
                     Drawable icon = mHeaderBar.getIconView().getDrawable();
@@ -947,11 +937,10 @@
                             disabledInSafeMode);
                     mHeaderBar.onTaskDataLoaded();
                     mHeaderBar.setDimAlpha(toTransform.dimAlpha);
-                    mHeaderBar.draw(c);
-                    c.setBitmap(null);
+                    return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
+                            mHeaderBar, 1f, 0);
                 }
             }
-            return thumbnail.createAshmemBitmap();
         }
         return null;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index d7d264e..21dfe8c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -30,6 +30,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -37,7 +38,11 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.AppTransitionAnimationSpec;
+import android.view.DisplayListCanvas;
 import android.view.IAppTransitionAnimationSpecsFuture;
+import android.view.RenderNode;
+import android.view.ThreadedRenderer;
+import android.view.View;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.recents.Recents;
@@ -264,8 +269,8 @@
             Rect bounds) {
         mTmpTransform.fillIn(taskView);
         Task task = taskView.getTask();
-        Bitmap thumbnail = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
-        return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, thumbnail,
+        GraphicBuffer buffer = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
+        return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, buffer,
                 bounds));
     }
 
@@ -346,7 +351,7 @@
         return new AppTransitionAnimationSpec(task.key.id, null, taskRect);
     }
 
-    public static Bitmap composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
+    public static GraphicBuffer composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
         float scale = transform.scale;
         int fromWidth = (int) (transform.rect.width() * scale);
         int fromHeight = (int) (transform.rect.height() * scale);
@@ -354,26 +359,17 @@
             Log.e(TAG, "Could not compose thumbnail for task: " + taskView.getTask() +
                     " at transform: " + transform);
 
-            Bitmap b = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
-            b.eraseColor(Color.TRANSPARENT);
-            return b;
+            return drawViewIntoGraphicBuffer(1, 1, null, 1f, 0x00ffffff);
         } else {
-            Bitmap b = Bitmap.createBitmap(fromWidth, fromHeight,
-                    Bitmap.Config.ARGB_8888);
-
             if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-                b.eraseColor(0xFFff0000);
+                return drawViewIntoGraphicBuffer(fromWidth, fromHeight, null, 1f, 0xFFff0000);
             } else {
-                Canvas c = new Canvas(b);
-                c.scale(scale, scale);
-                taskView.draw(c);
-                c.setBitmap(null);
+                return drawViewIntoGraphicBuffer(fromWidth, fromHeight, taskView, scale, 0);
             }
-            return b.createAshmemBitmap();
         }
     }
 
-    private static Bitmap composeHeaderBitmap(TaskView taskView,
+    private static GraphicBuffer composeHeaderBitmap(TaskView taskView,
             TaskViewTransform transform) {
         float scale = transform.scale;
         int headerWidth = (int) (transform.rect.width());
@@ -382,16 +378,30 @@
             return null;
         }
 
-        Bitmap b = Bitmap.createBitmap(headerWidth, headerHeight, Bitmap.Config.ARGB_8888);
         if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
-            b.eraseColor(0xFFff0000);
+            return drawViewIntoGraphicBuffer(headerWidth, headerHeight, null, 1f, 0xFFff0000);
         } else {
-            Canvas c = new Canvas(b);
-            c.scale(scale, scale);
-            taskView.mHeaderView.draw(c);
-            c.setBitmap(null);
+            return drawViewIntoGraphicBuffer(headerWidth, headerHeight, taskView.mHeaderView,
+                    scale, 0);
         }
-        return b.createAshmemBitmap();
+    }
+
+    public static GraphicBuffer drawViewIntoGraphicBuffer(int bufferWidth, int bufferHeight,
+            View view, float scale, int eraseColor) {
+        RenderNode node = RenderNode.create("RecentsTransition", null);
+        node.setLeftTopRightBottom(0, 0, bufferWidth, bufferHeight);
+        node.setClipToBounds(false);
+        DisplayListCanvas c = node.start(bufferWidth, bufferHeight);
+        c.scale(scale, scale);
+        if (eraseColor != 0) {
+            c.drawColor(eraseColor);
+        }
+        if (view != null) {
+            view.draw(c);
+        }
+        node.end(c);
+        return ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight)
+                .createGraphicBufferHandle();
     }
 
     /**
@@ -399,7 +409,7 @@
      */
     private static AppTransitionAnimationSpec composeAnimationSpec(TaskStackView stackView,
             TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
-        Bitmap b = null;
+        GraphicBuffer b = null;
         if (addHeaderBitmap) {
             b = composeHeaderBitmap(taskView, transform);
             if (b == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 012accd..9e2ec57 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -160,7 +160,7 @@
     private boolean mHomeStackResizable;
     private boolean mAdjustedForIme;
     private DividerState mState;
-    private SurfaceFlingerVsyncChoreographer mSfChoreographer;
+    private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -250,20 +250,22 @@
     };
 
     public DividerView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public DividerView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
     public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(),
+                Choreographer.getInstance());
     }
 
     @Override
@@ -313,8 +315,6 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         EventBus.getDefault().register(this);
-        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, getDisplay(),
-                Choreographer.getInstance());
     }
 
     @Override
@@ -832,7 +832,10 @@
                 .setDuration(animDuration)
                 .start();
         mAdjustedForIme = adjustedForIme;
-        if (mHomeStackResizable && adjustedForIme) {
+
+        // Only get new position if home stack is resizable, ime is open and not minimized
+        // (including the animation)
+        if (mHomeStackResizable && adjustedForIme && !mIsInMinimizeInteraction) {
             mDividerPositionBeforeMinimized = getCurrentPosition();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 3542500..a81b140 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -91,6 +91,7 @@
     }
 
     private LayoutListener mLayoutListener;
+    private boolean mLowPriorityStateUpdated;
     private final NotificationInflater mNotificationInflater;
     private int mIconTransformContentShift;
     private int mIconTransformContentShiftNoIcon;
@@ -1121,6 +1122,15 @@
         }
     }
 
+
+    public void setLowPriorityStateUpdated(boolean lowPriorityStateUpdated) {
+        mLowPriorityStateUpdated = lowPriorityStateUpdated;
+    }
+
+    public boolean hasLowPriorityStateUpdated() {
+        return mLowPriorityStateUpdated;
+    }
+
     public boolean isLowPriority() {
         return mIsLowPriority;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 28a858c..ab41485 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -121,6 +121,7 @@
     private boolean mBlockEthernet;
     private boolean mActivityEnabled;
     private boolean mForceBlockWifi;
+    private boolean mQsSignal;
 
     public SignalClusterView(Context context) {
         this(context, null);
@@ -152,9 +153,10 @@
         updateActivityEnabled();
     }
 
-    public void setForceBlockWifi() {
+    public void setQsSignalCluster() {
         mForceBlockWifi = true;
         mBlockWifi = true;
+        mQsSignal = true;
         if (isAttachedToWindow()) {
             // Re-register to get new callbacks.
             mNetworkController.removeCallback(this);
@@ -292,26 +294,30 @@
         mWifiStrengthId = statusIcon.icon;
         mWifiBadgeId = statusIcon.iconOverlay;
         mWifiDescription = statusIcon.contentDescription;
-        mWifiIn = activityIn && mActivityEnabled;
-        mWifiOut = activityOut && mActivityEnabled;
+        mWifiIn = activityIn && mActivityEnabled && mWifiVisible;
+        mWifiOut = activityOut && mActivityEnabled && mWifiVisible;
 
         apply();
     }
 
     @Override
-    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+    public void setMobileDataIndicators(IconState icon, IconState qsIcon, int type,
             int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
             String description, boolean isWide, int subId, boolean roaming) {
         PhoneState state = getState(subId);
         if (state == null) {
             return;
         }
-        state.mMobileVisible = statusIcon.visible && !mBlockMobile;
-        state.mMobileStrengthId = statusIcon.icon;
-        state.mMobileTypeId = statusType;
-        state.mMobileDescription = statusIcon.contentDescription;
+        if (mQsSignal) {
+            icon = qsIcon;
+            type = qsType;
+        }
+        state.mMobileVisible = icon.visible && !mBlockMobile;
+        state.mMobileStrengthId = icon.icon;
+        state.mMobileTypeId = type;
+        state.mMobileDescription = icon.contentDescription;
         state.mMobileTypeDescription = typeContentDescription;
-        state.mIsMobileTypeIconWide = statusType != 0 && isWide;
+        state.mIsMobileTypeIconWide = type != 0 && isWide;
         state.mRoaming = roaming;
         state.mActivityIn = activityIn && mActivityEnabled;
         state.mActivityOut = activityOut && mActivityEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index c7fbbf9..85475b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -179,6 +179,10 @@
         mIconScale = (float)imageBounds / (float)outerBounds;
     }
 
+    public float getIconScaleFullyDark() {
+        return (float) mStatusBarIconDrawingSizeDark / mStatusBarIconDrawingSize;
+    }
+
     public float getIconScale() {
         return mIconScale;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 8dab069..09aff1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -38,6 +38,7 @@
     private boolean mReorderingAllowed;
     private VisibilityLocationProvider mVisibilityLocationProvider;
     private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
+    private ArraySet<View> mLowPriorityReorderingViews = new ArraySet<>();
     private ArraySet<View> mAddedChildren = new ArraySet<>();
     private boolean mPulsing;
 
@@ -115,6 +116,9 @@
         if (mAddedChildren.contains(row)) {
             return true;
         }
+        if (mLowPriorityReorderingViews.contains(row)) {
+            return true;
+        }
         if (mAllowedReorderViews.contains(row)
                 && !mVisibilityLocationProvider.isInVisibleLocation(row)) {
             return true;
@@ -130,6 +134,7 @@
     public void onReorderingFinished() {
         mAllowedReorderViews.clear();
         mAddedChildren.clear();
+        mLowPriorityReorderingViews.clear();
     }
 
     @Override
@@ -141,6 +146,10 @@
         }
     }
 
+    public void onLowPriorityUpdated(NotificationData.Entry entry) {
+        mLowPriorityReorderingViews.add(entry.row);
+    }
+
     /**
      * Notify the visual stability manager that a new view was added and should be allowed to
      * reorder next time.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 9000eb4..f94bb0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -267,6 +267,9 @@
             boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
                     && iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
             boolean noOverflowAfter = i == childCount - 1;
+            float drawingScale = mDark && view instanceof StatusBarIconView
+                    ? ((StatusBarIconView) view).getIconScaleFullyDark()
+                    : 1f;
             if (mOpenedAmount != 0.0f) {
                 noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
             }
@@ -303,7 +306,7 @@
                     visualOverflowStart += mVisualOverflowAdaption * (1f - mOpenedAmount);
                 }
             }
-            translationX += iconState.iconAppearAmount * view.getWidth();
+            translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
         }
         if (firstOverflowIndex != -1) {
             int numDots = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index ccb6438..07ab6876 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -759,6 +759,7 @@
         mBatteryController = Dependency.get(BatteryController.class);
         mAssistManager = Dependency.get(AssistManager.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+        mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
 
         mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mDisplay = mWindowManager.getDefaultDisplay();
@@ -1614,9 +1615,14 @@
         mPendingNotifications.remove(entry.key);
         // If there was an async task started after the removal, we don't want to add it back to
         // the list, otherwise we might get leaks.
-        if (mNotificationData.get(entry.key) == null && !entry.row.isRemoved()) {
+        boolean isNew = mNotificationData.get(entry.key) == null;
+        if (isNew && !entry.row.isRemoved()) {
             addEntry(entry);
+        } else if (!isNew && entry.row.hasLowPriorityStateUpdated()) {
+            mVisualStabilityManager.onLowPriorityUpdated(entry);
+            updateNotificationShade();
         }
+        entry.row.setLowPriorityStateUpdated(false);
     }
 
     private boolean shouldSuppressFullScreenIntent(String key) {
@@ -5187,6 +5193,7 @@
     protected KeyguardManager mKeyguardManager;
     private LockPatternUtils mLockPatternUtils;
     private DeviceProvisionedController mDeviceProvisionedController;
+    protected SystemServicesProxy mSystemServicesProxy;
 
     // UI-specific methods
 
@@ -6244,7 +6251,10 @@
             StatusBarNotification sbn, ExpandableNotificationRow row) {
         row.setNeedsRedaction(needsRedaction(entry));
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
+        boolean isUpdate = mNotificationData.get(entry.key) != null;
+        boolean wasLowPriority = row.isLowPriority();
         row.setIsLowPriority(isLowPriority);
+        row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority));
         // bind the click event to the content area
         mNotificationClicker.register(row, sbn);
 
@@ -6808,6 +6818,7 @@
 
     protected boolean shouldPeek(Entry entry, StatusBarNotification sbn) {
         if (!mUseHeadsUp || isDeviceInVrMode()) {
+            if (DEBUG) Log.d(TAG, "No peeking: no huns or vr mode");
             return false;
         }
 
@@ -6816,8 +6827,7 @@
             return false;
         }
 
-        boolean inUse = mPowerManager.isScreenOn()
-                && !SystemServicesProxy.getInstance(mContext).isDreaming();
+        boolean inUse = mPowerManager.isScreenOn() && !mSystemServicesProxy.isDreaming();
 
         if (!inUse && !isDozing()) {
             if (DEBUG) {
@@ -6860,6 +6870,12 @@
             }
         }
 
+        // Don't peek notifications that are suppressed due to group alert behavior
+        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
+            if (DEBUG) Log.d(TAG, "No peeking: suppressed due to group alert behavior");
+            return false;
+        }
+
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
index 8e51ddb..cc7943b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -194,6 +194,11 @@
         return true;
     }
 
+    @Override
+    public boolean hasFocusStateSpecified() {
+        return true;
+    }
+
     public void setPressed(boolean pressed) {
         if (mDark != mLastDark && pressed) {
             mRipplePaint = null;
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 67b5596..03a50a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -253,11 +253,6 @@
     }
 
     @Override
-    public int getQsCurrentIconId() {
-        return getCurrentIconId();
-    }
-
-    @Override
     public void notifyListeners(SignalCallback callback) {
         MobileIconGroup icons = getIcons();
 
@@ -276,9 +271,9 @@
         String description = null;
         // Only send data sim callbacks to QS.
         if (mCurrentState.dataSim) {
-            qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
+            qsTypeIcon = showDataIcon ? icons.mDataType : 0;
             qsIcon = new IconState(mCurrentState.enabled
-                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
+                    && !mCurrentState.isEmergency, getCurrentIconId(), contentDescription);
             description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
         }
         boolean activityIn = mCurrentState.dataConnected
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 aaa0568..d91ae39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -22,16 +22,6 @@
 class TelephonyIcons {
     //***** Data connection icons
 
-    static final int QS_DATA_G = R.drawable.ic_qs_signal_g;
-    static final int QS_DATA_3G = R.drawable.ic_qs_signal_3g;
-    static final int QS_DATA_E = R.drawable.ic_qs_signal_e;
-    static final int QS_DATA_H = R.drawable.ic_qs_signal_h;
-    static final int QS_DATA_1X = R.drawable.ic_qs_signal_1x;
-    static final int QS_DATA_4G = R.drawable.ic_qs_signal_4g;
-    static final int QS_DATA_4G_PLUS = R.drawable.ic_qs_signal_4g_plus;
-    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 ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
@@ -46,8 +36,6 @@
 
     static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
 
-    static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
-
     static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
             "CARRIER_NETWORK_CHANGE",
             null,
@@ -75,7 +63,7 @@
             R.string.accessibility_data_connection_3g,
             TelephonyIcons.ICON_3G,
             true,
-            TelephonyIcons.QS_DATA_3G
+            TelephonyIcons.ICON_3G
             );
 
     static final MobileIconGroup WFC = new MobileIconGroup(
@@ -114,7 +102,7 @@
             R.string.accessibility_data_connection_edge,
             TelephonyIcons.ICON_E,
             false,
-            TelephonyIcons.QS_DATA_E
+            TelephonyIcons.ICON_E
             );
 
     static final MobileIconGroup ONE_X = new MobileIconGroup(
@@ -129,7 +117,7 @@
             R.string.accessibility_data_connection_cdma,
             TelephonyIcons.ICON_1X,
             true,
-            TelephonyIcons.QS_DATA_1X
+            TelephonyIcons.ICON_1X
             );
 
     static final MobileIconGroup G = new MobileIconGroup(
@@ -144,7 +132,7 @@
             R.string.accessibility_data_connection_gprs,
             TelephonyIcons.ICON_G,
             false,
-            TelephonyIcons.QS_DATA_G
+            TelephonyIcons.ICON_G
             );
 
     static final MobileIconGroup H = new MobileIconGroup(
@@ -159,7 +147,7 @@
             R.string.accessibility_data_connection_3_5g,
             TelephonyIcons.ICON_H,
             false,
-            TelephonyIcons.QS_DATA_H
+            TelephonyIcons.ICON_H
             );
 
     static final MobileIconGroup FOUR_G = new MobileIconGroup(
@@ -174,7 +162,7 @@
             R.string.accessibility_data_connection_4g,
             TelephonyIcons.ICON_4G,
             true,
-            TelephonyIcons.QS_DATA_4G
+            TelephonyIcons.ICON_4G
             );
 
     static final MobileIconGroup FOUR_G_PLUS = new MobileIconGroup(
@@ -189,7 +177,7 @@
             R.string.accessibility_data_connection_4g_plus,
             TelephonyIcons.ICON_4G_PLUS,
             true,
-            TelephonyIcons.QS_DATA_4G_PLUS
+            TelephonyIcons.ICON_4G_PLUS
             );
 
     static final MobileIconGroup LTE = new MobileIconGroup(
@@ -204,7 +192,7 @@
             R.string.accessibility_data_connection_lte,
             TelephonyIcons.ICON_LTE,
             true,
-            TelephonyIcons.QS_DATA_LTE
+            TelephonyIcons.ICON_LTE
             );
 
     static final MobileIconGroup LTE_PLUS = new MobileIconGroup(
@@ -219,7 +207,7 @@
             R.string.accessibility_data_connection_lte_plus,
             TelephonyIcons.ICON_LTE_PLUS,
             true,
-            TelephonyIcons.QS_DATA_LTE_PLUS
+            TelephonyIcons.ICON_LTE_PLUS
             );
 
     static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
@@ -234,7 +222,7 @@
             R.string.accessibility_cell_data_off,
             TelephonyIcons.ICON_DATA_DISABLED,
             false,
-            TelephonyIcons.QS_ICON_DATA_DISABLED
+            TelephonyIcons.ICON_DATA_DISABLED
             );
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index e80d3b3..0fd2445 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -36,11 +36,13 @@
 import android.service.notification.IConditionListener;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ZenRule;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.util.Utils;
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
@@ -169,45 +171,32 @@
     }
 
     private void fireNextAlarmChanged() {
-        for (Callback cb : mCallbacks) {
-            cb.onNextAlarmChanged();
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
     }
 
     private void fireEffectsSuppressorChanged() {
-        for (Callback cb : mCallbacks) {
-            cb.onEffectsSupressorChanged();
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
     }
 
     private void fireZenChanged(int zen) {
-        for (Callback cb : mCallbacks) {
-            cb.onZenChanged(zen);
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
     }
 
     private void fireZenAvailableChanged(boolean available) {
-        for (Callback cb : mCallbacks) {
-            cb.onZenAvailableChanged(available);
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
     }
 
     private void fireConditionsChanged(Condition[] conditions) {
-        for (Callback cb : mCallbacks) {
-            cb.onConditionsChanged(conditions);
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onConditionsChanged(conditions));
     }
 
     private void fireManualRuleChanged(ZenRule rule) {
-        for (Callback cb : mCallbacks) {
-            cb.onManualRuleChanged(rule);
-        }
+        Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
     }
 
-    private void fireConfigChanged(ZenModeConfig config) {
-        for (Callback cb : mCallbacks) {
-            cb.onConfigChanged(config);
-        }
+    @VisibleForTesting
+    protected void fireConfigChanged(ZenModeConfig config) {
+        Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
     }
 
     private void updateConditions(Condition[] conditions) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 0dbd1d6..ff06b5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -300,7 +300,7 @@
         mNotificationHeaderWrapper.notifyContentUpdated(mContainingNotification);
         recreateLowPriorityHeader(builder);
         recreateAmbientHeader(builder);
-        resetHeaderVisibilityIfNeeded(mNotificationHeader, calculateDesiredHeader());
+        updateHeaderVisibility(false /* animate */);
         updateChildrenHeaderAppearance();
     }
 
@@ -833,6 +833,11 @@
         return mNotificationHeaderLowPriority;
     }
 
+    @VisibleForTesting
+    public ViewGroup getCurrentHeaderView() {
+        return mCurrentHeader;
+    }
+
     public void notifyShowAmbientChanged() {
         updateHeaderVisibility(false);
     }
@@ -869,7 +874,12 @@
                 desiredHeader.setVisibility(VISIBLE);
             }
             if (currentHeader != null) {
-                getWrapperForView(currentHeader).setVisible(false);
+                // Wrapper can be null if we were a low priority notification
+                // and just destroyed it by calling setIsLowPriority(false)
+                NotificationViewWrapper wrapper = getWrapperForView(currentHeader);
+                if (wrapper != null) {
+                    wrapper.setVisible(false);
+                }
                 currentHeader.setVisibility(INVISIBLE);
             }
         }
@@ -878,7 +888,7 @@
         resetHeaderVisibilityIfNeeded(mNotificationHeaderAmbient, desiredHeader);
         resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, desiredHeader);
 
-        mCurrentHeader = currentHeader;
+        mCurrentHeader = desiredHeader;
     }
 
     private void resetHeaderVisibilityIfNeeded(View header, View desiredHeader) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
new file mode 100644
index 0000000..f4aebae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.util;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+public class Utils {
+
+    /**
+     * Allows lambda iteration over a list. It is done in reverse order so it is safe
+     * to add or remove items during the iteration.
+     */
+    public static <T> void safeForeach(List<T> list, Consumer<T> c) {
+        for (int i = list.size() - 1; i >= 0; i--) {
+            c.accept(list.get(i));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 51fcdbb..ecdea4f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -57,7 +57,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.R.string;
 import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.FileDescriptor;
@@ -294,11 +293,6 @@
     private void onAttach() {
         setExpanded(true);
         mAttached = true;
-        for (int i = 0; i < mZenRadioGroupContent.getChildCount(); i++) {
-            ConditionTag tag = getConditionTagAt(i);
-            if (tag != null) tag.rb.setChecked(false);
-            mZenRadioGroupContent.getChildAt(i).setTag(null);
-        }
         mAttachedZen = mController.getZen();
         ZenRule manualRule = mController.getManualRule();
         mExitCondition = manualRule != null ? manualRule.condition : null;
@@ -311,6 +305,7 @@
         setSessionExitCondition(copy(mExitCondition));
         updateWidgets();
         setRequestingConditions(!mHidden);
+        ensureSelection();
     }
 
     private void onDetach() {
@@ -366,9 +361,6 @@
         if (expanded == mExpanded) return;
         if (DEBUG) Log.d(mTag, "setExpanded " + expanded);
         mExpanded = expanded;
-        if (mExpanded) {
-            ensureSelection();
-        }
         updateWidgets();
         fireExpanded();
     }
@@ -464,7 +456,8 @@
                     ActivityManager.getCurrentUser(), false);
             return c;
         }
-        return null;
+        // If there is a manual rule, but it has no condition listed then it is forever.
+        return forever();
     }
 
     private void handleUpdateZen(int zen) {
@@ -491,6 +484,7 @@
             final ConditionTag tag = getConditionTagAt(i);
             if (tag != null && sameConditionId(tag.condition, mExitCondition)) {
                 bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
+                tag.rb.setChecked(true);
                 return;
             }
         }
@@ -498,6 +492,7 @@
                 exitCondition.id)) {
             bind(exitCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
                     COUNTDOWN_CONDITION_INDEX);
+            getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index bf6b394..55ec307 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -16,13 +16,27 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.Notification;
 import android.metrics.LogMaker;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IPowerManager;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.support.test.metricshelper.MetricsAsserts;
 import android.support.test.runner.AndroidJUnit4;
@@ -33,9 +47,11 @@
 import com.android.internal.logging.testing.FakeMetricsLogger;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
@@ -52,19 +68,34 @@
     NotificationStackScrollLayout mStackScroller;
     StatusBar mStatusBar;
     FakeMetricsLogger mMetricsLogger;
+    HeadsUpManager mHeadsUpManager;
+    NotificationData mNotificationData;
+    PowerManager mPowerManager;
+    SystemServicesProxy mSystemServicesProxy;
 
     private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
 
     @Before
-    public void setup() {
+    public void setup() throws Exception {
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
         mUnlockMethodCache = mock(UnlockMethodCache.class);
         mKeyguardIndicationController = mock(KeyguardIndicationController.class);
         mStackScroller = mock(NotificationStackScrollLayout.class);
         mMetricsLogger = new FakeMetricsLogger();
+        mHeadsUpManager = mock(HeadsUpManager.class);
+        mNotificationData = mock(NotificationData.class);
+        mSystemServicesProxy = mock(SystemServicesProxy.class);
+        IPowerManager powerManagerService = mock(IPowerManager.class);
+        HandlerThread handlerThread = new HandlerThread("TestThread");
+        handlerThread.start();
+        mPowerManager = new PowerManager(mContext, powerManagerService,
+                new Handler(handlerThread.getLooper()));
+        when(powerManagerService.isInteractive()).thenReturn(true);
+
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
         mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
-                mKeyguardIndicationController, mStackScroller);
+                mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
+                mNotificationData, mPowerManager, mSystemServicesProxy);
 
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -210,14 +241,62 @@
                         .setType(MetricsEvent.TYPE_ACTION));
     }
 
+    @Test
+    public void testShouldPeek_nonSuppressedGroupSummary() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setGroup("a")
+                .setGroupSummary(true)
+                .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+
+        assertTrue(mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testShouldPeek_suppressedGroupSummary() {
+        when(mPowerManager.isScreenOn()).thenReturn(true);
+        when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+        when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+        when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+        when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+        when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+        Notification n = new Notification.Builder(getContext(), "a")
+                .setGroup("a")
+                .setGroupSummary(true)
+                .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+
+        assertFalse(mStatusBar.shouldPeek(entry, sbn));
+    }
+
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
-                NotificationStackScrollLayout stack) {
+                NotificationStackScrollLayout stack, HeadsUpManager hum, NotificationData nd,
+                PowerManager pm, SystemServicesProxy ssp) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
             mKeyguardIndicationController = key;
             mStackScroller = stack;
+            mHeadsUpManager = hum;
+            mNotificationData = nd;
+            mUseHeadsUp = true;
+            mPowerManager = pm;
+            mSystemServicesProxy = ssp;
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index cb20639..6157d44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -111,7 +111,7 @@
         String typeDescription = "Test 1";
         String description = "Test 2";
         int type = R.drawable.stat_sys_data_fully_connected_1x;
-        int qsType = R.drawable.ic_qs_signal_1x;
+        int qsType = type;
         boolean wide = true;
         int subId = 5;
         boolean roaming = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 505e1d8..c233fea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -70,7 +70,7 @@
     protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
-    protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_DATA_3G;
+    protected static final int DEFAULT_QS_ICON = DEFAULT_ICON;
 
     protected NetworkControllerImpl mNetworkController;
     protected MobileSignalController mMobileSignalController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index dfe00f9..ac64263 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -25,7 +25,7 @@
         setupDefaultSignal();
 
         verifyDataIndicators(TelephonyIcons.ICON_3G,
-                TelephonyIcons.QS_DATA_3G);
+                TelephonyIcons.ICON_3G);
     }
 
     @Test
@@ -35,7 +35,7 @@
                 TelephonyManager.NETWORK_TYPE_GSM);
 
         verifyDataIndicators(TelephonyIcons.ICON_G,
-                TelephonyIcons.QS_DATA_G);
+                TelephonyIcons.ICON_G);
     }
 
     @Test
@@ -45,7 +45,7 @@
                 TelephonyManager.NETWORK_TYPE_CDMA);
 
         verifyDataIndicators(TelephonyIcons.ICON_1X,
-                TelephonyIcons.QS_DATA_1X);
+                TelephonyIcons.ICON_1X);
     }
 
     @Test
@@ -55,7 +55,7 @@
                 TelephonyManager.NETWORK_TYPE_EDGE);
 
         verifyDataIndicators(TelephonyIcons.ICON_E,
-                TelephonyIcons.QS_DATA_E);
+                TelephonyIcons.ICON_E);
     }
 
     @Test
@@ -65,7 +65,7 @@
                 TelephonyManager.NETWORK_TYPE_LTE);
 
         verifyDataIndicators(TelephonyIcons.ICON_LTE,
-                TelephonyIcons.QS_DATA_LTE);
+                TelephonyIcons.ICON_LTE);
     }
 
     @Test
@@ -75,7 +75,7 @@
                 TelephonyManager.NETWORK_TYPE_HSPA);
 
         verifyDataIndicators(TelephonyIcons.ICON_H,
-                TelephonyIcons.QS_DATA_H);
+                TelephonyIcons.ICON_H);
     }
 
     @Test
@@ -104,7 +104,7 @@
                 TelephonyManager.NETWORK_TYPE_LTE);
 
         verifyDataIndicators(TelephonyIcons.ICON_4G,
-                TelephonyIcons.QS_DATA_4G);
+                TelephonyIcons.ICON_4G);
     }
 
     @Ignore("Flaky")
@@ -117,7 +117,7 @@
         setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
 
         verifyDataIndicators(TelephonyIcons.ICON_DATA_DISABLED,
-                TelephonyIcons.QS_ICON_DATA_DISABLED);
+                TelephonyIcons.ICON_DATA_DISABLED);
     }
 
     @Test
@@ -148,7 +148,7 @@
         mNetworkController.handleConfigurationChanged();
 
         verifyDataIndicators(TelephonyIcons.ICON_4G,
-                TelephonyIcons.QS_DATA_4G);
+                TelephonyIcons.ICON_4G);
     }
 
     @Test
@@ -158,13 +158,13 @@
                 TelephonyManager.NETWORK_TYPE_LTE);
 
         verifyDataIndicators(TelephonyIcons.ICON_LTE,
-                TelephonyIcons.QS_DATA_LTE);
+                TelephonyIcons.ICON_LTE);
 
         when(mServiceState.getDataNetworkType())
                 .thenReturn(TelephonyManager.NETWORK_TYPE_HSPA);
         updateServiceState();
         verifyDataIndicators(TelephonyIcons.ICON_H,
-                TelephonyIcons.QS_DATA_H);
+                TelephonyIcons.ICON_H);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 1627925..aa62075 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -214,7 +214,7 @@
 
             verifyLastQsMobileDataIndicators(true,
                     testStrength,
-                    TelephonyIcons.QS_DATA_1X, false, false);
+                    TelephonyIcons.ICON_1X, false, false);
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
new file mode 100644
index 0000000..8124bf3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.statusbar.policy;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.service.notification.ZenModeConfig;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class ZenModeControllerImplTest extends SysuiTestCase {
+
+    private Callback mCallback;
+
+    @Test
+    public void testRemoveDuringCallback() {
+        ZenModeControllerImpl controller = new ZenModeControllerImpl(mContext, new Handler());
+        mCallback = new Callback() {
+            @Override
+            public void onConfigChanged(ZenModeConfig config) {
+                controller.removeCallback(mCallback);
+            }
+        };
+        controller.addCallback(mCallback);
+        Callback mockCallback = mock(Callback.class);
+        controller.addCallback(mockCallback);
+        controller.fireConfigChanged(null);
+        verify(mockCallback).onConfigChanged(eq(null));
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index e6c8815..2dd96b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -60,4 +60,12 @@
         Assert.assertTrue(lowPriorityHeaderView.getParent() == null);
         Assert.assertTrue(childrenContainer.getLowPriorityHeaderView() == null);
     }
+
+    @Test
+    public void testRecreateNotificationHeader_hasHeader() {
+        NotificationChildrenContainer childrenContainer = mGroup.getChildrenContainer();
+        childrenContainer.recreateNotificationHeader(null);
+        Assert.assertNotNull("Children container must have a header after recreation",
+                childrenContainer.getCurrentHeaderView());
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 7abaf7f..38b796b 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -51,6 +51,7 @@
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -465,10 +466,17 @@
         if (sVerbose) Slog.v(TAG, "destroyLocked()");
 
         final int numSessions = mSessions.size();
+        final ArraySet<RemoteFillService> remoteFillServices = new ArraySet<>(numSessions);
         for (int i = 0; i < numSessions; i++) {
-            mSessions.valueAt(i).destroyLocked();
+            final RemoteFillService remoteFillService = mSessions.valueAt(i).destroyLocked();
+            if (remoteFillService != null) {
+                remoteFillServices.add(remoteFillService);
+            }
         }
         mSessions.clear();
+        for (int i = 0; i < remoteFillServices.size(); i++) {
+            remoteFillServices.valueAt(i).destroy();
+        }
 
         sendStateToClients(true);
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index bad8dcf..980a7d4 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -419,7 +419,7 @@
             notifyUnavailableToClient();
         }
         synchronized (mLock) {
-            processResponseLocked(response);
+            processResponseLocked(response, requestFlags);
         }
 
         final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
@@ -1026,7 +1026,7 @@
             case ACTION_START_SESSION:
                 // View is triggering autofill.
                 mCurrentViewId = viewState.id;
-                viewState.update(value, virtualBounds);
+                viewState.update(value, virtualBounds, flags);
                 viewState.setState(ViewState.STATE_STARTED_SESSION);
                 requestNewFillResponseLocked(flags);
                 break;
@@ -1065,7 +1065,7 @@
                 }
 
                 // If the ViewState is ready to be displayed, onReady() will be called.
-                viewState.update(value, virtualBounds);
+                viewState.update(value, virtualBounds, flags);
                 break;
             case ACTION_VIEW_EXITED:
                 if (mCurrentViewId == viewState.id) {
@@ -1204,10 +1204,10 @@
         // Replace the old response
         mResponses.put(newResponse.getRequestId(), newResponse);
         // Now process the new response
-        processResponseLocked(newResponse);
+        processResponseLocked(newResponse, 0);
     }
 
-    private void processResponseLocked(@NonNull FillResponse newResponse) {
+    private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
         // Make sure we are hiding the UI which will be shown
         // only if handling the current response requires it.
         hideAllUiIfOwnedByMe();
@@ -1215,7 +1215,7 @@
         final int requestId = newResponse.getRequestId();
         if (sVerbose) {
             Slog.v(TAG, "processResponseLocked(): mCurrentViewId=" + mCurrentViewId
-                    + ", reqId=" + requestId + ", resp=" + newResponse);
+                    + ",flags=" + flags + ", reqId=" + requestId + ", resp=" + newResponse);
         }
 
         if (mResponses == null) {
@@ -1231,21 +1231,9 @@
             return;
         }
 
-        final ArrayList<Dataset> datasets = newResponse.getDatasets();
-
-        if (datasets != null && datasets.size() == 1) {
-            // Check if it its a single response for a manual request, in which case it should
-            // be automatically filled
-            final FillContext context = getFillContextByRequestIdLocked(requestId);
-            if (context != null && (context.getStructure().getFlags() & FLAG_MANUAL_REQUEST) != 0) {
-                Slog.d(TAG, "autofilling manual request directly");
-                autoFill(requestId, 0, datasets.get(0));
-                return;
-            }
-        }
         // Updates the UI, if necessary.
         final ViewState currentView = mViewStates.get(mCurrentViewId);
-        currentView.maybeCallOnFillReady();
+        currentView.maybeCallOnFillReady(flags);
     }
 
     /**
@@ -1331,20 +1319,6 @@
         return viewState;
     }
 
-    /**
-     * Resets the given state from all existing views in the given dataset.
-     */
-    private void resetViewStatesLocked(@NonNull Dataset dataset, int state) {
-        final ArrayList<AutofillId> ids = dataset.getFieldIds();
-        for (int j = 0; j < ids.size(); j++) {
-            final AutofillId id = ids.get(j);
-            final ViewState viewState = mViewStates.get(id);
-            if (viewState != null)  {
-                viewState.resetState(state);
-            }
-        }
-    }
-
     void autoFill(int requestId, int datasetIndex, Dataset dataset) {
         synchronized (mLock) {
             if (mDestroyed) {
@@ -1452,8 +1426,6 @@
                 return;
             }
             try {
-                if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
-
                 // Skip null values as a null values means no change
                 final int entryCount = dataset.getFieldIds().size();
                 final List<AutofillId> ids = new ArrayList<>(entryCount);
@@ -1480,6 +1452,8 @@
                     if (waitingDatasetAuth) {
                         hideFillUiIfOwnedByMe();
                     }
+                    if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
+
                     mClient.autofill(id, ids, values);
                     setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED, false);
                 }
@@ -1496,15 +1470,15 @@
         }
     }
 
-    void destroyLocked() {
+    RemoteFillService destroyLocked() {
         if (mDestroyed) {
-            return;
+            return null;
         }
-        mRemoteFillService.destroy();
         hideAllUiIfOwnedByMe();
         mUi.clearCallback(this);
         mDestroyed = true;
         mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
+        return mRemoteFillService;
     }
 
     private void hideAllUiIfOwnedByMe() {
@@ -1528,8 +1502,11 @@
                     + id + " destroyed");
             return;
         }
-        destroyLocked();
+        final RemoteFillService remoteFillService = destroyLocked();
         mService.removeSessionLocked(id);
+        if (remoteFillService != null) {
+            remoteFillService.destroy();
+        }
     }
 
     private int getLastResponseIndex() {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 8a52c96..cd8f4a5 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -16,6 +16,7 @@
 
 package com.android.server.autofill;
 
+import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
@@ -157,7 +158,7 @@
     // TODO: refactor / rename / document this method (and maybeCallOnFillReady) to make it clear
     // that it can change the value and update the UI; similarly, should replace code that
     // directly sets mAutofillValue to use encapsulation.
-    void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) {
+    void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds, int flags) {
         if (autofillValue != null) {
             mCurrentValue = autofillValue;
         }
@@ -165,7 +166,7 @@
             mVirtualBounds = virtualBounds;
         }
 
-        maybeCallOnFillReady();
+        maybeCallOnFillReady(flags);
     }
 
     /**
@@ -173,8 +174,8 @@
      * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the
      * fill UI is ready to be displayed (i.e. when response and bounds are set).
      */
-    void maybeCallOnFillReady() {
-        if ((mState & STATE_AUTOFILLED) != 0) {
+    void maybeCallOnFillReady(int flags) {
+        if ((mState & STATE_AUTOFILLED) != 0 && (flags & FLAG_MANUAL_REQUEST) == 0) {
             if (sDebug) Slog.d(TAG, "Ignoring UI for " + id + " on " + getStateAsString());
             return;
         }
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d315b3d..d566d3d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -158,6 +158,7 @@
                     final RemoteViews presentation = dataset.getFieldPresentation(index);
                     final View view;
                     try {
+                        if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
                         view = presentation.apply(context, null, interceptionHandler);
                     } catch (RuntimeException e) {
                         Slog.e(TAG, "Error inflating remote views", e);
@@ -203,6 +204,7 @@
                 return;
             }
             if (count <= 0) {
+                if (sDebug) Slog.d(TAG, "No dataset matches filter: " + mFilterText);
                 mCallback.requestHideFillUi();
             } else {
                 if (updateContentSize()) {
@@ -382,6 +384,7 @@
          * Shows the window.
          */
         public void show(WindowManager.LayoutParams params) {
+            if (sVerbose) Slog.v(TAG, "show(): showing=" + mShowing + ", params="+  params);
             try {
                 if (!mShowing) {
                     params.accessibilityTitle = mContentView.getContext()
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 6502c01..68f8c1b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -41,14 +41,10 @@
 # ---------------------------
 # DeviceStorageMonitorService.java
 # ---------------------------
-# The disk space free on the /data partition, in bytes
-2744 free_storage_changed (data|2|2)
-# Device low memory notification and disk space free on the /data partition, in bytes at that time
-2745 low_storage (data|2|2)
-# disk space free on the /data, /system, and /cache partitions in bytes
-2746 free_storage_left (data|2|2),(system|2|2),(cache|2|2)
-# file on cache partition was deleted
+# File on cache partition was deleted
 2748 cache_file_deleted (path|3)
+# Storage volume state and usable space in bytes
+2749 storage_state (uuid|3),(old_state|1),(new_state|1),(usable|2),(total|2)
 
 
 # ---------------------------
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index cffb158..35b452a 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3296,6 +3296,9 @@
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
 
+        // Apps can't defy reserved space
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
+
         final boolean aggressive = (flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
         if (aggressive) {
             mContext.enforceCallingOrSelfPermission(
@@ -3306,24 +3309,31 @@
         try {
             // In general, apps can allocate as much space as they want, except
             // we never let them eat into either the minimum cache space or into
-            // the low disk warning space.
+            // the low disk warning space. To avoid user confusion, this logic
+            // should be kept in sync with getFreeBytes().
             final File path = storage.findPathForUuid(volumeUuid);
+
+            final long usable = path.getUsableSpace();
+            final long lowReserved = storage.getStorageLowBytes(path);
+            final long fullReserved = storage.getStorageFullBytes(path);
+
             if (stats.isQuotaSupported(volumeUuid)) {
+                final long cacheTotal = stats.getCacheBytes(volumeUuid);
+                final long cacheReserved = storage.getStorageCacheBytes(path);
+                final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
+
                 if (aggressive) {
-                    return Math.max(0,
-                            stats.getFreeBytes(volumeUuid) - storage.getStorageFullBytes(path));
+                    return Math.max(0, (usable + cacheTotal) - fullReserved);
                 } else {
-                    return Math.max(0,
-                            stats.getFreeBytes(volumeUuid) - storage.getStorageLowBytes(path)
-                                    - storage.getStorageCacheBytes(path));
+                    return Math.max(0, (usable + cacheClearable) - lowReserved);
                 }
             } else {
                 // When we don't have fast quota information, we ignore cached
                 // data and only consider unused bytes.
                 if (aggressive) {
-                    return Math.max(0, path.getUsableSpace() - storage.getStorageFullBytes(path));
+                    return Math.max(0, usable - fullReserved);
                 } else {
-                    return Math.max(0, path.getUsableSpace() - storage.getStorageLowBytes(path));
+                    return Math.max(0, usable - lowReserved);
                 }
             }
         } catch (IOException e) {
@@ -3337,6 +3347,9 @@
     public void allocateBytes(String volumeUuid, long bytes, int flags) {
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
 
+        // Apps can't defy reserved space
+        flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
+
         // This method call will enforce FLAG_ALLOCATE_AGGRESSIVE permissions so
         // we don't have to enforce them locally
         final long allocatableBytes = getAllocatableBytes(volumeUuid, flags);
@@ -3350,7 +3363,11 @@
             // Free up enough disk space to satisfy both the requested allocation
             // and our low disk warning space.
             final File path = storage.findPathForUuid(volumeUuid);
-            bytes += storage.getStorageLowBytes(path);
+            if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+                bytes += storage.getStorageFullBytes(path);
+            } else {
+                bytes += storage.getStorageLowBytes(path);
+            }
 
             mPms.freeStorage(volumeUuid, bytes, flags);
         } catch (IOException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fbab26a..68c92a8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8447,8 +8447,8 @@
                         synchronized (mPidsSelfLocked) {
                             proc = mPidsSelfLocked.get(callingPid);
                         }
-                        if (proc != null && proc.curProcState
-                                < ActivityManager.PROCESS_STATE_RECEIVER) {
+                        if (proc != null &&
+                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
                             // Whoever is instigating this is in the foreground, so we will allow it
                             // to go through.
                             return ActivityManager.APP_START_MODE_NORMAL;
@@ -13545,7 +13545,9 @@
                         return;
                     }
                     if (pr.hasTopUi != hasTopUi) {
-                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
+                        if (DEBUG_OOM_ADJ) {
+                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
+                        }
                         pr.hasTopUi = hasTopUi;
                         changed = true;
                     }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 5636e19..9698a8f 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -130,6 +130,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
@@ -1419,19 +1420,17 @@
                     break;
                 case ANIM_THUMBNAIL_SCALE_UP:
                 case ANIM_THUMBNAIL_SCALE_DOWN:
-                    boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
-                    service.mWindowManager.overridePendingAppTransitionThumb(
-                            pendingOptions.getThumbnail(),
+                    final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
+                    final GraphicBuffer buffer = pendingOptions.getThumbnail();
+                    service.mWindowManager.overridePendingAppTransitionThumb(buffer,
                             pendingOptions.getStartX(), pendingOptions.getStartY(),
                             pendingOptions.getOnAnimationStartListener(),
                             scaleUp);
                     if (intent.getSourceBounds() == null) {
                         intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
                                 pendingOptions.getStartY(),
-                                pendingOptions.getStartX()
-                                        + pendingOptions.getThumbnail().getWidth(),
-                                pendingOptions.getStartY()
-                                        + pendingOptions.getThumbnail().getHeight()));
+                                pendingOptions.getStartX() + buffer.getWidth(),
+                                pendingOptions.getStartY() + buffer.getHeight()));
                     }
                     break;
                 case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 93e1ab4..9db957c 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -244,7 +244,7 @@
     static final int REMOVE_TASK_MODE_MOVING = 1;
     // Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new
     // stack and the new stack will be on top of all stacks.
-    private static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
+    static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
 
     // The height/width divide used when fitting a task within a bounds with method
     // {@link #fitWithinBounds}.
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e180aef..e828d38 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2989,8 +2989,8 @@
         // Calculate the default bounds (don't use existing stack bounds as we may have just created
         // the stack, and schedule the start of the animation into PiP (the bounds animator that
         // is triggered by this is posted on another thread)
-        final Rect destBounds = stack.getPictureInPictureBounds(aspectRatio,
-                false /* useExistingStackBounds */);
+        final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio);
+
         stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
                 true /* fromFullscreen */);
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 7ed07e0..07caf9e 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1432,7 +1432,13 @@
                     + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
             mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
             mNewTaskInfo = mSourceRecord.info;
-            mNewTaskIntent = mSourceRecord.getTask().intent;
+
+            // It is not guaranteed that the source record will have a task associated with it. For,
+            // example, if this method is being called for processing a pending activity launch, it
+            // is possible that the activity has been removed from the task after the launch was
+            // enqueued.
+            final TaskRecord sourceTask = mSourceRecord.getTask();
+            mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
         }
         mSourceRecord = null;
         mSourceStack = null;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2439062..9f29296 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -87,6 +87,7 @@
         implements PowerManagerInternal.LowPowerModeListener,
         BatteryStatsImpl.PlatformIdleStateCallback {
     static final String TAG = "BatteryStatsService";
+    static final boolean DBG = false;
 
     /**
      * How long to wait on an individual subsystem to return its stats.
@@ -152,11 +153,11 @@
 
                 case MSG_WRITE_TO_DISK:
                     updateExternalStatsSync("write", UPDATE_ALL);
-                    Slog.d(TAG, "begin writeAsyncLocked");
+                    if (DBG) Slog.d(TAG, "begin writeAsyncLocked");
                     synchronized (mStats) {
                         mStats.writeAsyncLocked();
                     }
-                    Slog.d(TAG, "end writeAsyncLocked");
+                    if (DBG) Slog.d(TAG, "end writeAsyncLocked");
                     break;
             }
         }
@@ -196,7 +197,7 @@
 
     @Override
     public String getPlatformLowPowerStats() {
-        Slog.d(TAG, "begin getPlatformLowPowerStats");
+        if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats");
         try {
             mUtf8BufferStat.clear();
             mUtf16BufferStat.clear();
@@ -212,7 +213,7 @@
             mUtf16BufferStat.flip();
             return mUtf16BufferStat.toString();
         } finally {
-            Slog.d(TAG, "end getPlatformLowPowerStats");
+            if (DBG) Slog.d(TAG, "end getPlatformLowPowerStats");
         }
     }
 
@@ -561,11 +562,11 @@
         
     public void noteScreenState(int state) {
         enforceCallingPermission();
-        Slog.d(TAG, "begin noteScreenState");
+        if (DBG) Slog.d(TAG, "begin noteScreenState");
         synchronized (mStats) {
             mStats.noteScreenStateLocked(state);
         }
-        Slog.d(TAG, "end noteScreenState");
+        if (DBG) Slog.d(TAG, "end noteScreenState");
     }
     
     public void noteScreenBrightness(int brightness) {
@@ -718,11 +719,11 @@
 
     public void noteStartCamera(int uid) {
         enforceCallingPermission();
-        Slog.d(TAG, "begin noteStartCamera");
+        if (DBG) Slog.d(TAG, "begin noteStartCamera");
         synchronized (mStats) {
             mStats.noteCameraOnLocked(uid);
         }
-        Slog.d(TAG, "end noteStartCamera");
+        if (DBG) Slog.d(TAG, "end noteStartCamera");
     }
 
     public void noteStopCamera(int uid) {
@@ -944,10 +945,10 @@
     }
 
     @Override
-    public void noteBleScanStarted(WorkSource ws) {
+    public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteBluetoothScanStartedFromSourceLocked(ws);
+            mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized);
         }
     }
 
@@ -1342,23 +1343,23 @@
                     }
                 }
             }
-            Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
+            if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
             synchronized (mStats) {
                 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
                 if (writeData) {
                     mStats.writeAsyncLocked();
                 }
             }
-            Slog.d(TAG, "end dumpCheckinLocked");
+            if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
         } else {
-            Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
+            if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
             synchronized (mStats) {
                 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
                 if (writeData) {
                     mStats.writeAsyncLocked();
                 }
             }
-            Slog.d(TAG, "end dumpLocked");
+            if (DBG) Slog.d(TAG, "end dumpLocked");
         }
     }
 
@@ -1480,11 +1481,11 @@
         SynchronousResultReceiver bluetoothReceiver = null;
         SynchronousResultReceiver modemReceiver = null;
 
-        Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
+        if (DBG) Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
         synchronized (mExternalStatsLock) {
             if (mContext == null) {
                 // Don't do any work yet.
-                Slog.d(TAG, "end updateExternalStatsSync");
+                if (DBG) Slog.d(TAG, "end updateExternalStatsSync");
                 return;
             }
 
@@ -1583,7 +1584,7 @@
                 }
             }
         }
-        Slog.d(TAG, "end updateExternalStatsSync");
+        if (DBG) Slog.d(TAG, "end updateExternalStatsSync");
     }
 
     /**
@@ -1603,7 +1604,7 @@
                 return getHealthStatsForUidLocked(requestUid);
             }
         } catch (Exception ex) {
-            Slog.d(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
+            Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
             throw ex;
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -1633,7 +1634,7 @@
                 return results;
             }
         } catch (Exception ex) {
-            Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
+            if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
                     + Arrays.toString(requestUids) + ") i=" + i, ex);
             throw ex;
         } finally {
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 144eb11..2e0ec0b 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -97,7 +97,7 @@
         mKeyguardShowing = showing;
         dismissDockedStackIfNeeded();
         if (showing) {
-            mKeyguardGoingAway = false;
+            setKeyguardGoingAway(false);
             mDismissalRequested = false;
         }
         mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
@@ -114,7 +114,7 @@
         if (mKeyguardShowing) {
             mWindowManager.deferSurfaceLayout();
             try {
-                mKeyguardGoingAway = true;
+                setKeyguardGoingAway(true);
                 mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
                         false /* alwaysKeepCurrent */, convertTransitFlags(flags),
                         false /* forceOverride */);
@@ -139,6 +139,11 @@
         mWindowManager.dismissKeyguard(callback);
     }
 
+    private void setKeyguardGoingAway(boolean keyguardGoingAway) {
+        mKeyguardGoingAway = keyguardGoingAway;
+        mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
+    }
+
     private void failCallback(IKeyguardDismissCallback callback) {
         try {
             callback.onDismissError();
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 702bf92..2010c24 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -44,9 +44,9 @@
         return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
     }
 
-    Rect getPictureInPictureBounds(float aspectRatio, boolean useExistingStackBounds) {
+    Rect getDefaultPictureInPictureBounds(float aspectRatio) {
         return getWindowContainerController().getPictureInPictureBounds(aspectRatio,
-                useExistingStackBounds);
+                null /* currentStackBounds */);
     }
 
     void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index deb3b28..39aed7c 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -233,7 +233,8 @@
                 updateFile();
             }
             mLastWriteTime = SystemClock.uptimeMillis();
-            Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms");
+            if (DEBUG) Slog.d(TAG, "Prepared write state in "
+                    + (SystemClock.uptimeMillis()-now) + "ms");
             if (!sync) {
                 BackgroundThread.getHandler().post(new Runnable() {
                     @Override public void run() {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7eec945..e81e6d7 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -115,6 +115,7 @@
 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
 import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 
@@ -673,8 +674,11 @@
             mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
                     moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
 
+            final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
+                    || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
             // Move the task
-            sourceStack.removeTask(this, reason, REMOVE_TASK_MODE_MOVING);
+            sourceStack.removeTask(this, reason, moveStackToFront
+                    ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
             toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
 
             if (schedulePictureInPictureModeChange) {
@@ -693,8 +697,6 @@
 
             // If the task had focus before (or we're requested to move focus), move focus to the
             // new stack by moving the stack to the front.
-            final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
-                    || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
             if (r != null) {
                 toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
                         wasPaused, reason);
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index b8d633f..73a365b 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -221,7 +221,9 @@
                         restoredSettingName(element),
                         newValue,
                         userid);
-                updateSettingsAccordingToInstalledServices(element, userid);
+                if (mConfig.secureSettingName.equals(element)) {
+                    updateSettingsAccordingToInstalledServices(element, userid);
+                }
                 rebuildRestoredPackages();
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e377d57..3667e16 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3225,7 +3225,7 @@
                 Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
         if (warningEnabled) {
             Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
-                    Toast.LENGTH_LONG);
+                    Toast.LENGTH_SHORT);
             toast.show();
         }
     }
@@ -3759,13 +3759,7 @@
             return true;
         }
         if (record.sbn.isGroup()) {
-            if (notification.isGroupSummary()
-                    && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_CHILDREN) {
-                return true;
-            } else if (notification.isGroupChild()
-                    && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_SUMMARY) {
-                return true;
-            }
+            return notification.suppressAlertingDueToGrouping();
         }
         return false;
     }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 4c3efce..2c0cc95 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -447,7 +447,9 @@
                 boolean isGroupSummary = record.getNotification().isGroupSummary();
                 record.setGlobalSortKey(
                         String.format("intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
-                        record.isRecentlyIntrusive() ? '0' : '1',
+                        record.isRecentlyIntrusive()
+                                && record.getImportance() > NotificationManager.IMPORTANCE_MIN
+                                ? '0' : '1',
                         groupProxy.getAuthoritativeRank(),
                         isGroupSummary ? '0' : '1',
                         groupSortKeyPortion,
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index e6e4617..c95b5c5 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -395,10 +395,11 @@
         }
     }
 
-    public void freeCache(String uuid, long freeStorageSize, int flags) throws InstallerException {
+    public void freeCache(String uuid, long targetFreeBytes, long cacheReservedBytes, int flags)
+            throws InstallerException {
         if (!checkBeforeRemote()) return;
         try {
-            mInstalld.freeCache(uuid, freeStorageSize, flags);
+            mInstalld.freeCache(uuid, targetFreeBytes, cacheReservedBytes, flags);
         } catch (Exception e) {
             throw InstallerException.from(e);
         }
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index b165984..211a1c9 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -21,6 +21,7 @@
 import android.annotation.UserIdInt;
 import android.content.Intent;
 import android.content.pm.InstantAppInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -32,6 +33,8 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
@@ -76,7 +79,16 @@
 
     private static final String LOG_TAG = "InstantAppRegistry";
 
-    private static final long DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
+    static final long DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+            DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
+
+    private static final long DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+            DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
+
+    static final long DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+            DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
+
+    private static final long DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
             DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
 
     private static final String INSTANT_APPS_FOLDER = "instant";
@@ -535,46 +547,195 @@
         }
     }
 
-    public void pruneInstantAppsLPw() {
-        // For now we prune only state for uninstalled instant apps
-        final long maxCacheDurationMillis = Settings.Global.getLong(
+    void pruneInstantApps() {
+        final long maxInstalledCacheDuration = Settings.Global.getLong(
                 mService.mContext.getContentResolver(),
-                Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
-                DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS);
+                Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
 
-        for (int userId : UserManagerService.getInstance().getUserIds()) {
-            // Prune in-memory state
-            removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
-                final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
-                return (elapsedCachingMillis > maxCacheDurationMillis);
-            }, userId);
+        final long maxUninstalledCacheDuration = Settings.Global.getLong(
+                mService.mContext.getContentResolver(),
+                Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
 
-            // Prune on-disk state
-            File instantAppsDir = getInstantApplicationsDir(userId);
-            if (!instantAppsDir.exists()) {
-                continue;
-            }
-            File[] files = instantAppsDir.listFiles();
-            if (files == null) {
-                continue;
-            }
-            for (File instantDir : files) {
-                if (!instantDir.isDirectory()) {
+        try {
+            pruneInstantApps(Long.MAX_VALUE,
+                    maxInstalledCacheDuration, maxUninstalledCacheDuration);
+        } catch (IOException e) {
+            Slog.e(LOG_TAG, "Error pruning installed and uninstalled instant apps", e);
+        }
+    }
+
+    boolean pruneInstalledInstantApps(long neededSpace, long maxInstalledCacheDuration) {
+        try {
+            return pruneInstantApps(neededSpace, maxInstalledCacheDuration, Long.MAX_VALUE);
+        } catch (IOException e) {
+            Slog.e(LOG_TAG, "Error pruning installed instant apps", e);
+            return false;
+        }
+    }
+
+    boolean pruneUninstalledInstantApps(long neededSpace, long maxUninstalledCacheDuration) {
+        try {
+            return pruneInstantApps(neededSpace, Long.MAX_VALUE, maxUninstalledCacheDuration);
+        } catch (IOException e) {
+            Slog.e(LOG_TAG, "Error pruning uninstalled instant apps", e);
+            return false;
+        }
+    }
+
+    /**
+     * Prunes instant apps until there is enough <code>neededSpace</code>. Both
+     * installed and uninstalled instant apps are pruned that are older than
+     * <code>maxInstalledCacheDuration</code> and <code>maxUninstalledCacheDuration</code>
+     * respectively. All times are in milliseconds.
+     *
+     * @param neededSpace The space to ensure is free.
+     * @param maxInstalledCacheDuration The max duration for caching installed apps in millis.
+     * @param maxUninstalledCacheDuration The max duration for caching uninstalled apps in millis.
+     * @return Whether enough space was freed.
+     *
+     * @throws IOException
+     */
+    private boolean pruneInstantApps(long neededSpace, long maxInstalledCacheDuration,
+            long maxUninstalledCacheDuration) throws IOException {
+        final StorageManager storage = mService.mContext.getSystemService(StorageManager.class);
+        final File file = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
+
+        if (file.getUsableSpace() >= neededSpace) {
+            return true;
+        }
+
+        List<String> packagesToDelete = null;
+
+        final int[] allUsers;
+        final long now = System.currentTimeMillis();
+
+        // Prune first installed instant apps
+        synchronized (mService.mPackages) {
+            allUsers = PackageManagerService.sUserManager.getUserIds();
+
+            final int packageCount = mService.mPackages.size();
+            for (int i = 0; i < packageCount; i++) {
+                final PackageParser.Package pkg = mService.mPackages.valueAt(i);
+                if (now - pkg.getLatestPackageUseTimeInMills() < maxInstalledCacheDuration) {
                     continue;
                 }
-
-                File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
-                if (!metadataFile.exists()) {
+                if (!(pkg.mExtras instanceof PackageSetting)) {
                     continue;
                 }
+                final PackageSetting  ps = (PackageSetting) pkg.mExtras;
+                boolean installedOnlyAsInstantApp = false;
+                for (int userId : allUsers) {
+                    if (ps.getInstalled(userId)) {
+                        if (ps.getInstantApp(userId)) {
+                            installedOnlyAsInstantApp = true;
+                        } else {
+                            installedOnlyAsInstantApp = false;
+                            break;
+                        }
+                    }
+                }
+                if (installedOnlyAsInstantApp) {
+                    if (packagesToDelete == null) {
+                        packagesToDelete = new ArrayList<>();
+                    }
+                    packagesToDelete.add(pkg.packageName);
+                }
+            }
 
-                final long elapsedCachingMillis = System.currentTimeMillis()
-                        - metadataFile.lastModified();
-                if (elapsedCachingMillis > maxCacheDurationMillis) {
-                    deleteDir(instantDir);
+            if (packagesToDelete != null) {
+                packagesToDelete.sort((String lhs, String rhs) -> {
+                    final PackageParser.Package lhsPkg = mService.mPackages.get(lhs);
+                    final PackageParser.Package rhsPkg = mService.mPackages.get(rhs);
+                    if (lhsPkg == null && rhsPkg == null) {
+                        return 0;
+                    } else if (lhsPkg == null) {
+                        return -1;
+                    } else if (rhsPkg == null) {
+                        return 1;
+                    } else {
+                        if (lhsPkg.getLatestPackageUseTimeInMills() >
+                                rhsPkg.getLatestPackageUseTimeInMills()) {
+                            return 1;
+                        } else if (lhsPkg.getLatestPackageUseTimeInMills() <
+                                rhsPkg.getLatestPackageUseTimeInMills()) {
+                            return -1;
+                        } else {
+                            if (lhsPkg.mExtras instanceof PackageSetting
+                                    && rhsPkg.mExtras instanceof PackageSetting) {
+                                final PackageSetting lhsPs = (PackageSetting) lhsPkg.mExtras;
+                                final PackageSetting rhsPs = (PackageSetting) rhsPkg.mExtras;
+                                if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) {
+                                    return 1;
+                                } else {
+                                    return -1;
+                                }
+                            } else {
+                                return 0;
+                            }
+                        }
+                    }
+                });
+            }
+        }
+
+        if (packagesToDelete != null) {
+            final int packageCount = packagesToDelete.size();
+            for (int i = 0; i < packageCount; i++) {
+                final String packageToDelete = packagesToDelete.get(i);
+                if (mService.deletePackageX(packageToDelete, PackageManager.VERSION_CODE_HIGHEST,
+                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
+                                == PackageManager.DELETE_SUCCEEDED) {
+                    if (file.getUsableSpace() >= neededSpace) {
+                        return true;
+                    }
                 }
             }
         }
+
+        // Prune uninstalled instant apps
+        synchronized (mService.mPackages) {
+            // TODO: Track last used time for uninstalled instant apps for better pruning
+            for (int userId : UserManagerService.getInstance().getUserIds()) {
+                // Prune in-memory state
+                removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
+                    final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
+                    return (elapsedCachingMillis > maxUninstalledCacheDuration);
+                }, userId);
+
+                // Prune on-disk state
+                File instantAppsDir = getInstantApplicationsDir(userId);
+                if (!instantAppsDir.exists()) {
+                    continue;
+                }
+                File[] files = instantAppsDir.listFiles();
+                if (files == null) {
+                    continue;
+                }
+                for (File instantDir : files) {
+                    if (!instantDir.isDirectory()) {
+                        continue;
+                    }
+
+                    File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
+                    if (!metadataFile.exists()) {
+                        continue;
+                    }
+
+                    final long elapsedCachingMillis = System.currentTimeMillis()
+                            - metadataFile.lastModified();
+                    if (elapsedCachingMillis > maxUninstalledCacheDuration) {
+                        deleteDir(instantDir);
+                        if (file.getUsableSpace() >= neededSpace) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
     }
 
     private @Nullable List<InstantAppInfo> getInstalledInstantApplicationsLPr(
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 782325a..99eda86 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -875,9 +875,9 @@
             new ParallelPackageParserCallback();
 
     public static final class SharedLibraryEntry {
-        public final String path;
-        public final String apk;
-        public final SharedLibraryInfo info;
+        public final @Nullable String path;
+        public final @Nullable String apk;
+        public final @NonNull SharedLibraryInfo info;
 
         SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
                 String declaringPackageName, int declaringPackageVersionCode) {
@@ -1312,6 +1312,9 @@
     // Delay time in millisecs
     static final int BROADCAST_DELAY = 10 * 1000;
 
+    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
+            2 * 60 * 60 * 1000L; /* two hours */
+
     static UserManagerService sUserManager;
 
     // Stores a list of users whose package restrictions file needs to be updated
@@ -4155,13 +4158,13 @@
 
     @Override
     public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
-            final IPackageDataObserver observer) {
+            final int storageFlags, final IPackageDataObserver observer) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CLEAR_APP_CACHE, null);
         mHandler.post(() -> {
             boolean success = false;
             try {
-                freeStorage(volumeUuid, freeStorageSize, 0);
+                freeStorage(volumeUuid, freeStorageSize, storageFlags);
                 success = true;
             } catch (IOException e) {
                 Slog.w(TAG, e);
@@ -4178,13 +4181,13 @@
 
     @Override
     public void freeStorage(final String volumeUuid, final long freeStorageSize,
-            final IntentSender pi) {
+            final int storageFlags, final IntentSender pi) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CLEAR_APP_CACHE, TAG);
         mHandler.post(() -> {
             boolean success = false;
             try {
-                freeStorage(volumeUuid, freeStorageSize, 0);
+                freeStorage(volumeUuid, freeStorageSize, storageFlags);
                 success = true;
             } catch (IOException e) {
                 Slog.w(TAG, e);
@@ -4209,10 +4212,14 @@
         if (file.getUsableSpace() >= bytes) return;
 
         if (ENABLE_FREE_CACHE_V2) {
-            final boolean aggressive = (storageFlags
-                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
             final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
                     volumeUuid);
+            final boolean aggressive = (storageFlags
+                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
+            final boolean defyReserved = (storageFlags
+                    & StorageManager.FLAG_ALLOCATE_DEFY_RESERVED) != 0;
+            final long reservedBytes = (aggressive || defyReserved) ? 0
+                    : storage.getStorageCacheBytes(file);
 
             // 1. Pre-flight to determine if we have any chance to succeed
             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
@@ -4230,29 +4237,52 @@
 
             // 4. Consider cached app data (above quotas)
             try {
-                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
+                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
+                        Installer.FLAG_FREE_CACHE_V2);
             } catch (InstallerException ignored) {
             }
             if (file.getUsableSpace() >= bytes) return;
 
-            // 5. Consider shared libraries with refcount=0 and age>2h
+            // 5. Consider shared libraries with refcount=0 and age>min cache period
+            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
+                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
+                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
+                return;
+            }
+
             // 6. Consider dexopt output (aggressive only)
-            // 7. Consider ephemeral apps not used in last week
+            // TODO: Implement
+
+            // 7. Consider installed instant apps unused longer than min cache period
+            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
+                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
+                return;
+            }
 
             // 8. Consider cached app data (below quotas)
             try {
-                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
-                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
+                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
+                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
             } catch (InstallerException ignored) {
             }
             if (file.getUsableSpace() >= bytes) return;
 
             // 9. Consider DropBox entries
-            // 10. Consider ephemeral cookies
+            // TODO: Implement
 
+            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
+            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
+                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
+                return;
+            }
         } else {
             try {
-                mInstaller.freeCache(volumeUuid, bytes, 0);
+                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
             } catch (InstallerException ignored) {
             }
             if (file.getUsableSpace() >= bytes) return;
@@ -4261,6 +4291,69 @@
         throw new IOException("Failed to free " + bytes + " on storage device at " + file);
     }
 
+    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
+            throws IOException {
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
+
+        List<VersionedPackage> packagesToDelete = null;
+        final long now = System.currentTimeMillis();
+
+        synchronized (mPackages) {
+            final int[] allUsers = sUserManager.getUserIds();
+            final int libCount = mSharedLibraries.size();
+            for (int i = 0; i < libCount; i++) {
+                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
+                if (versionedLib == null) {
+                    continue;
+                }
+                final int versionCount = versionedLib.size();
+                for (int j = 0; j < versionCount; j++) {
+                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
+                    // Skip packages that are not static shared libs.
+                    if (!libInfo.isStatic()) {
+                        break;
+                    }
+                    // Important: We skip static shared libs used for some user since
+                    // in such a case we need to keep the APK on the device. The check for
+                    // a lib being used for any user is performed by the uninstall call.
+                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
+                    // Resolve the package name - we use synthetic package names internally
+                    final String internalPackageName = resolveInternalPackageNameLPr(
+                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
+                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
+                    // Skip unused static shared libs cached less than the min period
+                    // to prevent pruning a lib needed by a subsequently installed package.
+                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
+                        continue;
+                    }
+                    if (packagesToDelete == null) {
+                        packagesToDelete = new ArrayList<>();
+                    }
+                    packagesToDelete.add(new VersionedPackage(internalPackageName,
+                            declaringPackage.getVersionCode()));
+                }
+            }
+        }
+
+        if (packagesToDelete != null) {
+            final int packageCount = packagesToDelete.size();
+            for (int i = 0; i < packageCount; i++) {
+                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
+                // Delete the package synchronously (will fail of the lib used for any user).
+                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
+                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
+                                == PackageManager.DELETE_SUCCEEDED) {
+                    if (volume.getUsableSpace() >= neededSpace) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Update given flags based on encryption status of current user.
      */
@@ -10650,8 +10743,7 @@
                     final int versionCount = versionedLib.size();
                     for (int i = 0; i < versionCount; i++) {
                         SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
-                        // TODO: We will change version code to long, so in the new API it is long
-                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
+                        final int libVersionCode = libInfo.getDeclaringPackage()
                                 .getVersionCode();
                         if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
                             minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
@@ -15494,7 +15586,7 @@
                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
 
                     try {
-                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
+                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
                                 installFlags, packageAbiOverride);
                     } catch (InstallerException e) {
@@ -18488,7 +18580,7 @@
      *  persisting settings for later use
      *  sending a broadcast if necessary
      */
-    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
+    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
         final PackageRemovedInfo info = new PackageRemovedInfo(this);
         final boolean res;
 
@@ -18531,7 +18623,7 @@
                         pkg.staticSharedLibVersion);
                 if (libEntry != null) {
                     for (int currUserId : allUsers) {
-                        if (userId != UserHandle.USER_ALL && userId != currUserId) {
+                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
                             continue;
                         }
                         List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
@@ -24273,9 +24365,7 @@
 
         @Override
         public void pruneInstantApps() {
-            synchronized (mPackages) {
-                mInstantAppRegistry.pruneInstantAppsLPw();
-            }
+            mInstantAppRegistry.pruneInstantApps();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 908e517..e3bc919 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -60,7 +60,6 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
@@ -1128,16 +1127,25 @@
                 + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
                 + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
                 + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+        final boolean keyguardGoingAway = mWindowManagerInternal.isKeyguardGoingAway();
+
         boolean disable = true;
         // Note: We postpone the rotating of the screen until the keyguard as well as the
-        // window manager have reported a draw complete.
-        if (mScreenOnEarly && mAwake &&
-                mKeyguardDrawComplete && mWindowManagerDrawComplete) {
+        // window manager have reported a draw complete or the keyguard is going away in dismiss
+        // mode.
+        if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete)
+                || keyguardGoingAway)) {
             if (needSensorRunningLp()) {
                 disable = false;
                 //enable listener if not already enabled
                 if (!mOrientationSensorEnabled) {
-                    mOrientationListener.enable();
+                    // Don't clear the current sensor orientation if the keyguard is going away in
+                    // dismiss mode. This allows window manager to use the last sensor reading to
+                    // determine the orientation vs. falling back to the last known orientation if
+                    // the sensor reading was cleared which can cause it to relaunch the app that
+                    // will show in the wrong orientation first before correcting leading to app
+                    // launch delays.
+                    mOrientationListener.enable(!keyguardGoingAway /* clearCurrentRotation */);
                     if(localLOGV) Slog.v(TAG, "Enabling listeners");
                     mOrientationSensorEnabled = true;
                 }
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 8ef0acb..64f64c0 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -109,24 +109,37 @@
      * {@link #onProposedRotationChanged(int)} when the device orientation changes.
      */
     public void enable() {
+        enable(true /* clearCurrentRotation */);
+    }
+
+    /**
+     * Enables the WindowOrientationListener so it will monitor the sensor and call
+     * {@link #onProposedRotationChanged(int)} when the device orientation changes.
+     *
+     * @param clearCurrentRotation True if the current proposed sensor rotation should be cleared as
+     *                             part of the reset.
+     */
+    public void enable(boolean clearCurrentRotation) {
         synchronized (mLock) {
             if (mSensor == null) {
                 Slog.w(TAG, "Cannot detect sensors. Not enabled");
                 return;
             }
-            if (mEnabled == false) {
-                if (LOG) {
-                    Slog.d(TAG, "WindowOrientationListener enabled");
-                }
-                mOrientationJudge.resetLocked();
-                if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-                    mSensorManager.registerListener(
-                            mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
-                } else {
-                    mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
-                }
-                mEnabled = true;
+            if (mEnabled) {
+                return;
             }
+            if (LOG) {
+                Slog.d(TAG, "WindowOrientationListener enabled clearCurrentRotation="
+                        + clearCurrentRotation);
+            }
+            mOrientationJudge.resetLocked(clearCurrentRotation);
+            if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+                mSensorManager.registerListener(
+                        mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
+            } else {
+                mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
+            }
+            mEnabled = true;
         }
     }
 
@@ -278,8 +291,11 @@
          * Resets the state of the judge.
          *
          * Should only be called when holding WindowOrientationListener lock.
+         *
+         * @param clearCurrentRotation True if the current proposed sensor rotation should be
+         *                             cleared as part of the reset.
          */
-        public abstract void resetLocked();
+        public abstract void resetLocked(boolean clearCurrentRotation);
 
         /**
          * Dumps internal state of the orientation judge.
@@ -602,7 +618,7 @@
                     if (LOG) {
                         Slog.v(TAG, "Resetting orientation listener.");
                     }
-                    resetLocked();
+                    resetLocked(true /* clearCurrentRotation */);
                     skipSample = true;
                 } else {
                     final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS);
@@ -778,9 +794,11 @@
         }
 
         @Override
-        public void resetLocked() {
+        public void resetLocked(boolean clearCurrentRotation) {
             mLastFilteredTimestampNanos = Long.MIN_VALUE;
-            mProposedRotation = -1;
+            if (clearCurrentRotation) {
+                mProposedRotation = -1;
+            }
             mFlatTimestampNanos = Long.MIN_VALUE;
             mFlat = false;
             mSwingTimestampNanos = Long.MIN_VALUE;
@@ -1015,9 +1033,11 @@
         }
 
         @Override
-        public void resetLocked() {
-            mProposedRotation = -1;
-            mDesiredRotation = -1;
+        public void resetLocked(boolean clearCurrentRotation) {
+            if (clearCurrentRotation) {
+                mProposedRotation = -1;
+                mDesiredRotation = -1;
+            }
             mTouching = false;
             mTouchEndedTimestampNanos = Long.MIN_VALUE;
             unscheduleRotationEvaluationLocked();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 1b4eaf5..da90e5a 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -30,7 +30,7 @@
  */
 public class KeyguardServiceDelegate {
     private static final String TAG = "KeyguardServiceDelegate";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private static final int SCREEN_STATE_OFF = 0;
     private static final int SCREEN_STATE_TURNING_ON = 1;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c8ade2d..3b5db29 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -87,6 +87,7 @@
 import com.android.server.RescueParty;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
+import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.lights.Light;
@@ -1940,7 +1941,8 @@
                         && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
                     nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
                     if (now < nextTimeout) {
-                        if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) {
+                        if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
+                                || mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
                             mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                         } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
                             mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
@@ -2728,9 +2730,9 @@
         };
 
         // ShutdownThread must run on a looper capable of displaying the UI.
-        Message msg = Message.obtain(mHandler, runnable);
+        Message msg = Message.obtain(UiThread.getHandler(), runnable);
         msg.setAsynchronous(true);
-        mHandler.sendMessage(msg);
+        UiThread.getHandler().sendMessage(msg);
 
         // PowerManager.reboot() is documented not to return so just wait for the inevitable.
         if (wait) {
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index fbc9e56..88b6d87 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -16,71 +16,60 @@
 
 package com.android.server.storage;
 
-import android.app.NotificationChannel;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.DumpUtils;
-import com.android.server.EventLogTags;
-import com.android.server.SystemService;
-import com.android.server.pm.InstructionSets;
+import android.annotation.WorkerThread;
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.net.TrafficStats;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileObserver;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
-import android.os.StatFs;
-import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.text.format.Formatter;
-import android.util.EventLog;
+import android.os.storage.VolumeInfo;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
 import android.util.Slog;
-import android.util.TimeUtils;
 
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.concurrent.atomic.AtomicInteger;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.EventLogTags;
+import com.android.server.IoThread;
+import com.android.server.SystemService;
+import com.android.server.pm.InstructionSets;
+import com.android.server.pm.PackageManagerService;
 
 import dalvik.system.VMRuntime;
 
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
- * This class implements a service to monitor the amount of disk
- * storage space on the device.  If the free storage on device is less
- * than a tunable threshold value (a secure settings parameter;
- * default 10%) a low memory notification is displayed to alert the
- * user. If the user clicks on the low memory notification the
- * Application Manager application gets launched to let the user free
- * storage space.
- *
- * Event log events: A low memory event with the free storage on
- * device in bytes is logged to the event log when the device goes low
- * on storage space.  The amount of free storage on the device is
- * periodically logged to the event log. The log interval is a secure
- * settings parameter with a default value of 12 hours.  When the free
- * storage differential goes below a threshold (again a secure
- * settings parameter with a default value of 2MB), the free memory is
- * logged to the event log.
+ * Service that monitors and maintains free space on storage volumes.
+ * <p>
+ * As the free space on a volume nears the threshold defined by
+ * {@link StorageManager#getStorageLowBytes(File)}, this service will clear out
+ * cached data to keep the disk from entering this low state.
  */
 public class DeviceStorageMonitorService extends SystemService {
-    static final String TAG = "DeviceStorageMonitorService";
+    private static final String TAG = "DeviceStorageMonitorService";
 
     /**
      * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
@@ -88,68 +77,75 @@
      */
     public static final String EXTRA_SEQUENCE = "seq";
 
-    // TODO: extend to watch and manage caches on all private volumes
+    private static final int MSG_CHECK = 1;
 
-    static final boolean DEBUG = false;
-    static final boolean localLOGV = false;
-
-    static final int DEVICE_MEMORY_WHAT = 1;
-    static final int FORCE_MEMORY_WHAT = 2;
-    private static final int MONITOR_INTERVAL = 1; //in minutes
-
-    private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes
-    private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
-    private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
+    private static final long DEFAULT_LOG_DELTA_BYTES = 64 * TrafficStats.MB_IN_BYTES;
+    private static final long DEFAULT_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS;
 
     // com.android.internal.R.string.low_internal_storage_view_text_no_boot
     // hard codes 250MB in the message as the storage space required for the
     // boot image.
-    private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = 250 * 1024 * 1024;
+    private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = 250 * TrafficStats.MB_IN_BYTES;
 
-    private long mFreeMem;  // on /data
-    private long mFreeMemAfterLastCacheClear;  // on /data
-    private long mLastReportedFreeMem;
-    private long mLastReportedFreeMemTime;
-    boolean mLowMemFlag=false;
-    private boolean mMemFullFlag=false;
-    private final boolean mIsBootImageOnDisk;
-    private final ContentResolver mResolver;
-    private final long mTotalMemory;  // on /data
-    private final StatFs mDataFileStats;
-    private final StatFs mSystemFileStats;
-    private final StatFs mCacheFileStats;
+    private NotificationManager mNotifManager;
 
-    private static final File DATA_PATH = Environment.getDataDirectory();
-    private static final File SYSTEM_PATH = Environment.getRootDirectory();
-    private static final File CACHE_PATH = Environment.getDownloadCacheDirectory();
+    /** Sequence number used for testing */
+    private final AtomicInteger mSeq = new AtomicInteger(1);
+    /** Forced level used for testing */
+    private volatile int mForceLevel = State.LEVEL_UNKNOWN;
 
-    private long mThreadStartTime = -1;
-    boolean mUpdatesStopped;
-    AtomicInteger mSeq = new AtomicInteger(1);
-    boolean mClearSucceeded = false;
-    boolean mClearingCache;
-    private final Intent mStorageLowIntent;
-    private final Intent mStorageOkIntent;
-    private final Intent mStorageFullIntent;
-    private final Intent mStorageNotFullIntent;
-    private CachePackageDataObserver mClearCacheObserver;
+    /** Map from storage volume UUID to internal state */
+    private final ArrayMap<UUID, State> mStates = new ArrayMap<>();
+
+    /**
+     * State for a specific storage volume, including the current "level" that
+     * we've alerted the user and apps about.
+     */
+    private static class State {
+        private static final int LEVEL_UNKNOWN = -1;
+        private static final int LEVEL_NORMAL = 0;
+        private static final int LEVEL_LOW = 1;
+        private static final int LEVEL_FULL = 2;
+
+        /** Last "level" that we alerted about */
+        public int level = LEVEL_NORMAL;
+        /** Last {@link File#getUsableSpace()} that we logged about */
+        public long lastUsableBytes = Long.MAX_VALUE;
+
+        /**
+         * Test if the given level transition is "entering" a specific level.
+         * <p>
+         * As an example, a transition from {@link #LEVEL_NORMAL} to
+         * {@link #LEVEL_FULL} is considered to "enter" both {@link #LEVEL_LOW}
+         * and {@link #LEVEL_FULL}.
+         */
+        private static boolean isEntering(int level, int oldLevel, int newLevel) {
+            return newLevel >= level && (oldLevel < level || oldLevel == LEVEL_UNKNOWN);
+        }
+
+        /**
+         * Test if the given level transition is "leaving" a specific level.
+         * <p>
+         * As an example, a transition from {@link #LEVEL_FULL} to
+         * {@link #LEVEL_NORMAL} is considered to "leave" both
+         * {@link #LEVEL_FULL} and {@link #LEVEL_LOW}.
+         */
+        private static boolean isLeaving(int level, int oldLevel, int newLevel) {
+            return newLevel < level && (oldLevel >= level || oldLevel == LEVEL_UNKNOWN);
+        }
+
+        private static String levelToString(int level) {
+            switch (level) {
+                case State.LEVEL_UNKNOWN: return "UNKNOWN";
+                case State.LEVEL_NORMAL: return "NORMAL";
+                case State.LEVEL_LOW: return "LOW";
+                case State.LEVEL_FULL: return "FULL";
+                default: return Integer.toString(level);
+            }
+        }
+    }
+
     private CacheFileDeletedObserver mCacheFileDeletedObserver;
-    private static final int _TRUE = 1;
-    private static final int _FALSE = 0;
-    // This is the raw threshold that has been set at which we consider
-    // storage to be low.
-    long mMemLowThreshold;
-    // This is the threshold at which we start trying to flush caches
-    // to get below the low threshold limit.  It is less than the low
-    // threshold; we will allow storage to get a bit beyond the limit
-    // before flushing and checking if we are actually low.
-    private long mMemCacheStartTrimThreshold;
-    // This is the threshold that we try to get to when deleting cache
-    // files.  This is greater than the low threshold so that we will flush
-    // more files than absolutely needed, to reduce the frequency that
-    // flushing takes place.
-    private long mMemCacheTrimToThreshold;
-    private long mMemFullThreshold;
 
     /**
      * This string is used for ServiceManager access to this class.
@@ -159,244 +155,107 @@
     private static final String TV_NOTIFICATION_CHANNEL_ID = "devicestoragemonitor.tv";
 
     /**
-    * Handler that checks the amount of disk space on the device and sends a
-    * notification if the device runs low on disk space
-    */
-    private final Handler mHandler = new Handler() {
+     * Handler that checks the amount of disk space on the device and sends a
+     * notification if the device runs low on disk space
+     */
+    private final Handler mHandler = new Handler(IoThread.get().getLooper()) {
         @Override
         public void handleMessage(Message msg) {
-            //don't handle an invalid message
             switch (msg.what) {
-                case DEVICE_MEMORY_WHAT:
-                    checkMemory(msg.arg1 == _TRUE);
-                    return;
-                case FORCE_MEMORY_WHAT:
-                    forceMemory(msg.arg1, msg.arg2);
-                    return;
-                default:
-                    Slog.w(TAG, "Will not process invalid message");
+                case MSG_CHECK:
+                    check();
                     return;
             }
         }
     };
 
-    private class CachePackageDataObserver extends IPackageDataObserver.Stub {
-        public void onRemoveCompleted(String packageName, boolean succeeded) {
-            mClearSucceeded = succeeded;
-            mClearingCache = false;
-            if(localLOGV) Slog.i(TAG, " Clear succeeded:"+mClearSucceeded
-                    +", mClearingCache:"+mClearingCache+" Forcing memory check");
-            postCheckMemoryMsg(false, 0);
+    private State findOrCreateState(UUID uuid) {
+        State state = mStates.get(uuid);
+        if (state == null) {
+            state = new State();
+            mStates.put(uuid, state);
         }
+        return state;
     }
 
-    private void restatDataDir() {
-        try {
-            mDataFileStats.restat(DATA_PATH.getAbsolutePath());
-            mFreeMem = (long) mDataFileStats.getAvailableBlocks() *
-                mDataFileStats.getBlockSize();
-        } catch (IllegalArgumentException e) {
-            // use the old value of mFreeMem
-        }
-        // Allow freemem to be overridden by debug.freemem for testing
-        String debugFreeMem = SystemProperties.get("debug.freemem");
-        if (!"".equals(debugFreeMem)) {
-            mFreeMem = Long.parseLong(debugFreeMem);
-        }
-        // Read the log interval from secure settings
-        long freeMemLogInterval = Settings.Global.getLong(mResolver,
-                Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL,
-                DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
-        //log the amount of free memory in event log
-        long currTime = SystemClock.elapsedRealtime();
-        if((mLastReportedFreeMemTime == 0) ||
-           (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
-            mLastReportedFreeMemTime = currTime;
-            long mFreeSystem = -1, mFreeCache = -1;
-            try {
-                mSystemFileStats.restat(SYSTEM_PATH.getAbsolutePath());
-                mFreeSystem = (long) mSystemFileStats.getAvailableBlocks() *
-                    mSystemFileStats.getBlockSize();
-            } catch (IllegalArgumentException e) {
-                // ignore; report -1
-            }
-            try {
-                mCacheFileStats.restat(CACHE_PATH.getAbsolutePath());
-                mFreeCache = (long) mCacheFileStats.getAvailableBlocks() *
-                    mCacheFileStats.getBlockSize();
-            } catch (IllegalArgumentException e) {
-                // ignore; report -1
-            }
-            EventLog.writeEvent(EventLogTags.FREE_STORAGE_LEFT,
-                                mFreeMem, mFreeSystem, mFreeCache);
-        }
-        // Read the reporting threshold from secure settings
-        long threshold = Settings.Global.getLong(mResolver,
-                Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
-                DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD);
-        // If mFree changed significantly log the new value
-        long delta = mFreeMem - mLastReportedFreeMem;
-        if (delta > threshold || delta < -threshold) {
-            mLastReportedFreeMem = mFreeMem;
-            EventLog.writeEvent(EventLogTags.FREE_STORAGE_CHANGED, mFreeMem);
-        }
-    }
+    /**
+     * Core logic that checks the storage state of every mounted private volume.
+     * Since this can do heavy I/O, callers should invoke indirectly using
+     * {@link #MSG_CHECK}.
+     */
+    @WorkerThread
+    private void check() {
+        final StorageManager storage = getContext().getSystemService(StorageManager.class);
+        final int seq = mSeq.get();
 
-    private void clearCache() {
-        if (mClearCacheObserver == null) {
-            // Lazy instantiation
-            mClearCacheObserver = new CachePackageDataObserver();
-        }
-        mClearingCache = true;
-        try {
-            if (localLOGV) Slog.i(TAG, "Clearing cache");
-            IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
-                    freeStorageAndNotify(null, mMemCacheTrimToThreshold, mClearCacheObserver);
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
-            mClearingCache = false;
-            mClearSucceeded = false;
-        }
-    }
+        // Check every mounted private volume to see if they're low on space
+        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+            final File file = vol.getPath();
+            final long fullBytes = storage.getStorageFullBytes(file);
+            final long lowBytes = storage.getStorageLowBytes(file);
 
-    void forceMemory(int opts, int seq) {
-        if ((opts&OPTION_UPDATES_STOPPED) == 0) {
-            if (mUpdatesStopped) {
-                mUpdatesStopped = false;
-                checkMemory(true);
-            }
-        } else {
-            mUpdatesStopped = true;
-            final boolean forceLow = (opts&OPTION_STORAGE_LOW) != 0;
-            if (mLowMemFlag != forceLow || (opts&OPTION_FORCE_UPDATE) != 0) {
-                mLowMemFlag = forceLow;
-                if (forceLow) {
-                    sendNotification(seq);
-                } else {
-                    cancelNotification(seq);
+            // Automatically trim cached data when nearing the low threshold;
+            // when it's within 150% of the threshold, we try trimming usage
+            // back to 200% of the threshold.
+            if (file.getUsableSpace() < (lowBytes * 3) / 2) {
+                final PackageManagerService pms = (PackageManagerService) ServiceManager
+                        .getService("package");
+                try {
+                    pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
+                } catch (IOException e) {
+                    Slog.w(TAG, e);
                 }
             }
-        }
-    }
 
-    void checkMemory(boolean checkCache) {
-        if (mUpdatesStopped) {
-            return;
-        }
+            // Send relevant broadcasts and show notifications based on any
+            // recently noticed state transitions.
+            final UUID uuid = StorageManager.convert(vol.getFsUuid());
+            final State state = findOrCreateState(uuid);
+            final long totalBytes = file.getTotalSpace();
+            final long usableBytes = file.getUsableSpace();
 
-        //if the thread that was started to clear cache is still running do nothing till its
-        //finished clearing cache. Ideally this flag could be modified by clearCache
-        // and should be accessed via a lock but even if it does this test will fail now and
-        //hopefully the next time this flag will be set to the correct value.
-        if (mClearingCache) {
-            if(localLOGV) Slog.i(TAG, "Thread already running just skip");
-            //make sure the thread is not hung for too long
-            long diffTime = System.currentTimeMillis() - mThreadStartTime;
-            if(diffTime > (10*60*1000)) {
-                Slog.w(TAG, "Thread that clears cache file seems to run for ever");
-            }
-        } else {
-            restatDataDir();
-            if (localLOGV)  Slog.v(TAG, "freeMemory="+mFreeMem);
-
-            //post intent to NotificationManager to display icon if necessary
-            if (mFreeMem < mMemLowThreshold) {
-                if (checkCache) {
-                    // We are allowed to clear cache files at this point to
-                    // try to get down below the limit, because this is not
-                    // the initial call after a cache clear has been attempted.
-                    // In this case we will try a cache clear if our free
-                    // space has gone below the cache clear limit.
-                    if (mFreeMem < mMemCacheStartTrimThreshold) {
-                        // We only clear the cache if the free storage has changed
-                        // a significant amount since the last time.
-                        if ((mFreeMemAfterLastCacheClear-mFreeMem)
-                                >= ((mMemLowThreshold-mMemCacheStartTrimThreshold)/4)) {
-                            // See if clearing cache helps
-                            // Note that clearing cache is asynchronous and so we do a
-                            // memory check again once the cache has been cleared.
-                            mThreadStartTime = System.currentTimeMillis();
-                            mClearSucceeded = false;
-                            clearCache();
-                        }
-                    }
-                } else {
-                    // This is a call from after clearing the cache.  Note
-                    // the amount of free storage at this point.
-                    mFreeMemAfterLastCacheClear = mFreeMem;
-                    if (!mLowMemFlag) {
-                        // We tried to clear the cache, but that didn't get us
-                        // below the low storage limit.  Tell the user.
-                        Slog.i(TAG, "Running low on memory. Sending notification");
-                        sendNotification(0);
-                        mLowMemFlag = true;
-                    } else {
-                        if (localLOGV) Slog.v(TAG, "Running low on memory " +
-                                "notification already sent. do nothing");
-                    }
-                }
+            int oldLevel = state.level;
+            int newLevel;
+            if (mForceLevel != State.LEVEL_UNKNOWN) {
+                // When in testing mode, use unknown old level to force sending
+                // of any relevant broadcasts.
+                oldLevel = State.LEVEL_UNKNOWN;
+                newLevel = mForceLevel;
+            } else if (usableBytes <= fullBytes) {
+                newLevel = State.LEVEL_FULL;
+            } else if (usableBytes <= lowBytes) {
+                newLevel = State.LEVEL_LOW;
+            } else if (StorageManager.UUID_DEFAULT.equals(uuid) && !isBootImageOnDisk()
+                    && usableBytes < BOOT_IMAGE_STORAGE_REQUIREMENT) {
+                newLevel = State.LEVEL_LOW;
             } else {
-                mFreeMemAfterLastCacheClear = mFreeMem;
-                if (mLowMemFlag) {
-                    Slog.i(TAG, "Memory available. Cancelling notification");
-                    cancelNotification(0);
-                    mLowMemFlag = false;
-                }
+                newLevel = State.LEVEL_NORMAL;
             }
-            if (!mLowMemFlag && !mIsBootImageOnDisk && mFreeMem < BOOT_IMAGE_STORAGE_REQUIREMENT) {
-                Slog.i(TAG, "No boot image on disk due to lack of space. Sending notification");
-                sendNotification(0);
-                mLowMemFlag = true;
-            }
-            if (mFreeMem < mMemFullThreshold) {
-                if (!mMemFullFlag) {
-                    sendFullNotification();
-                    mMemFullFlag = true;
-                }
-            } else {
-                if (mMemFullFlag) {
-                    cancelFullNotification();
-                    mMemFullFlag = false;
-                }
-            }
-        }
-        if(localLOGV) Slog.i(TAG, "Posting Message again");
-        //keep posting messages to itself periodically
-        postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
-    }
 
-    void postCheckMemoryMsg(boolean clearCache, long delay) {
-        // Remove queued messages
-        mHandler.removeMessages(DEVICE_MEMORY_WHAT);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
-                clearCache ?_TRUE : _FALSE, 0),
-                delay);
+            // Log whenever we notice drastic storage changes
+            if ((Math.abs(state.lastUsableBytes - usableBytes) > DEFAULT_LOG_DELTA_BYTES)
+                    || oldLevel != newLevel) {
+                EventLogTags.writeStorageState(uuid.toString(), oldLevel, newLevel,
+                        usableBytes, totalBytes);
+                state.lastUsableBytes = usableBytes;
+            }
+
+            updateNotifications(vol, oldLevel, newLevel);
+            updateBroadcasts(vol, oldLevel, newLevel, seq);
+
+            state.level = newLevel;
+        }
+
+        // Loop around to check again in future; we don't remove messages since
+        // there might be an immediate request pending.
+        if (!mHandler.hasMessages(MSG_CHECK)) {
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK),
+                    DEFAULT_CHECK_INTERVAL);
+        }
     }
 
     public DeviceStorageMonitorService(Context context) {
         super(context);
-        mLastReportedFreeMemTime = 0;
-        mResolver = context.getContentResolver();
-        mIsBootImageOnDisk = isBootImageOnDisk();
-        //create StatFs object
-        mDataFileStats = new StatFs(DATA_PATH.getAbsolutePath());
-        mSystemFileStats = new StatFs(SYSTEM_PATH.getAbsolutePath());
-        mCacheFileStats = new StatFs(CACHE_PATH.getAbsolutePath());
-        //initialize total storage on device
-        mTotalMemory = (long)mDataFileStats.getBlockCount() *
-                        mDataFileStats.getBlockSize();
-        mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
-        mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
-                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-        mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
-        mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
-                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-        mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL);
-        mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
-        mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
     }
 
     private static boolean isBootImageOnDisk() {
@@ -408,35 +267,20 @@
         return true;
     }
 
-    /**
-    * Initializes the disk space threshold value and posts an empty message to
-    * kickstart the process.
-    */
     @Override
     public void onStart() {
-        // cache storage thresholds
-        Context context = getContext();
-        final StorageManager sm = StorageManager.from(context);
-        mMemLowThreshold = sm.getStorageLowBytes(DATA_PATH);
-        mMemFullThreshold = sm.getStorageFullBytes(DATA_PATH);
-
-        mMemCacheStartTrimThreshold = ((mMemLowThreshold*3)+mMemFullThreshold)/4;
-        mMemCacheTrimToThreshold = mMemLowThreshold
-                + ((mMemLowThreshold-mMemCacheStartTrimThreshold)*2);
-        mFreeMemAfterLastCacheClear = mTotalMemory;
-        checkMemory(true);
+        final Context context = getContext();
+        mNotifManager = context.getSystemService(NotificationManager.class);
 
         mCacheFileDeletedObserver = new CacheFileDeletedObserver();
         mCacheFileDeletedObserver.startWatching();
 
         // Ensure that the notification channel is set up
-        NotificationManager notificationMgr =
-            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         PackageManager packageManager = context.getPackageManager();
         boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
 
         if (isTv) {
-            notificationMgr.createNotificationChannel(new NotificationChannel(
+            mNotifManager.createNotificationChannel(new NotificationChannel(
                     TV_NOTIFICATION_CHANNEL_ID,
                     context.getString(
                         com.android.internal.R.string.device_storage_monitor_notification_channel),
@@ -445,23 +289,29 @@
 
         publishBinderService(SERVICE, mRemoteService);
         publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
+
+        // Kick off pass to examine storage state
+        mHandler.removeMessages(MSG_CHECK);
+        mHandler.obtainMessage(MSG_CHECK).sendToTarget();
     }
 
     private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() {
         @Override
         public void checkMemory() {
-            // force an early check
-            postCheckMemoryMsg(true, 0);
+            // Kick off pass to examine storage state
+            mHandler.removeMessages(MSG_CHECK);
+            mHandler.obtainMessage(MSG_CHECK).sendToTarget();
         }
 
         @Override
         public boolean isMemoryLow() {
-            return mLowMemFlag;
+            return Environment.getDataDirectory().getUsableSpace() < getMemoryLowThreshold();
         }
 
         @Override
         public long getMemoryLowThreshold() {
-            return mMemLowThreshold;
+            return getContext().getSystemService(StorageManager.class)
+                    .getStorageLowBytes(Environment.getDataDirectory());
         }
     };
 
@@ -494,8 +344,6 @@
     }
 
     static final int OPTION_FORCE_UPDATE = 1<<0;
-    static final int OPTION_UPDATES_STOPPED = 1<<1;
-    static final int OPTION_STORAGE_LOW = 1<<2;
 
     int parseOptions(Shell shell) {
         String opt;
@@ -518,10 +366,11 @@
                 int opts = parseOptions(shell);
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.DEVICE_POWER, null);
+                mForceLevel = State.LEVEL_LOW;
                 int seq = mSeq.incrementAndGet();
-                mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
-                        opts | OPTION_UPDATES_STOPPED | OPTION_STORAGE_LOW, seq));
                 if ((opts & OPTION_FORCE_UPDATE) != 0) {
+                    mHandler.removeMessages(MSG_CHECK);
+                    mHandler.obtainMessage(MSG_CHECK).sendToTarget();
                     pw.println(seq);
                 }
             } break;
@@ -529,10 +378,11 @@
                 int opts = parseOptions(shell);
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.DEVICE_POWER, null);
+                mForceLevel = State.LEVEL_NORMAL;
                 int seq = mSeq.incrementAndGet();
-                mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
-                        opts | OPTION_UPDATES_STOPPED, seq));
                 if ((opts & OPTION_FORCE_UPDATE) != 0) {
+                    mHandler.removeMessages(MSG_CHECK);
+                    mHandler.obtainMessage(MSG_CHECK).sendToTarget();
                     pw.println(seq);
                 }
             } break;
@@ -540,10 +390,11 @@
                 int opts = parseOptions(shell);
                 getContext().enforceCallingOrSelfPermission(
                         android.Manifest.permission.DEVICE_POWER, null);
+                mForceLevel = State.LEVEL_UNKNOWN;
                 int seq = mSeq.incrementAndGet();
-                mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
-                        opts, seq));
                 if ((opts & OPTION_FORCE_UPDATE) != 0) {
+                    mHandler.removeMessages(MSG_CHECK);
+                    mHandler.obtainMessage(MSG_CHECK).sendToTarget();
                     pw.println(seq);
                 }
             } break;
@@ -568,145 +419,125 @@
         pw.println("    -f: force a storage change broadcast be sent, prints new sequence.");
     }
 
-    void dumpImpl(FileDescriptor fd, PrintWriter pw, String[] args) {
+    void dumpImpl(FileDescriptor fd, PrintWriter _pw, String[] args) {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(_pw, "  ");
         if (args == null || args.length == 0 || "-a".equals(args[0])) {
-            final Context context = getContext();
-
-            pw.println("Current DeviceStorageMonitor state:");
-
-            pw.print("  mFreeMem=");
-            pw.print(Formatter.formatFileSize(context, mFreeMem));
-            pw.print(" mTotalMemory=");
-            pw.println(Formatter.formatFileSize(context, mTotalMemory));
-
-            pw.print("  mFreeMemAfterLastCacheClear=");
-            pw.println(Formatter.formatFileSize(context, mFreeMemAfterLastCacheClear));
-
-            pw.print("  mLastReportedFreeMem=");
-            pw.print(Formatter.formatFileSize(context, mLastReportedFreeMem));
-            pw.print(" mLastReportedFreeMemTime=");
-            TimeUtils.formatDuration(mLastReportedFreeMemTime, SystemClock.elapsedRealtime(), pw);
+            pw.println("Known volumes:");
+            pw.increaseIndent();
+            for (int i = 0; i < mStates.size(); i++) {
+                final UUID uuid = mStates.keyAt(i);
+                final State state = mStates.valueAt(i);
+                if (StorageManager.UUID_DEFAULT.equals(uuid)) {
+                    pw.println("Default:");
+                } else {
+                    pw.println(uuid + ":");
+                }
+                pw.increaseIndent();
+                pw.printPair("level", State.levelToString(state.level));
+                pw.printPair("lastUsableBytes", state.lastUsableBytes);
+                pw.println();
+                pw.decreaseIndent();
+            }
+            pw.decreaseIndent();
             pw.println();
 
-            if (mUpdatesStopped) {
-                pw.print("  mUpdatesStopped=");
-                pw.print(mUpdatesStopped);
-                pw.print(" mSeq=");
-                pw.println(mSeq.get());
-            } else {
-                pw.print("  mClearSucceeded=");
-                pw.print(mClearSucceeded);
-                pw.print(" mClearingCache=");
-                pw.println(mClearingCache);
-            }
+            pw.printPair("mSeq", mSeq.get());
+            pw.printPair("mForceState", State.levelToString(mForceLevel));
+            pw.println();
+            pw.println();
 
-            pw.print("  mLowMemFlag=");
-            pw.print(mLowMemFlag);
-            pw.print(" mMemFullFlag=");
-            pw.println(mMemFullFlag);
-
-            pw.print("  mMemLowThreshold=");
-            pw.print(Formatter.formatFileSize(context, mMemLowThreshold));
-            pw.print(" mMemFullThreshold=");
-            pw.println(Formatter.formatFileSize(context, mMemFullThreshold));
-
-            pw.print("  mMemCacheStartTrimThreshold=");
-            pw.print(Formatter.formatFileSize(context, mMemCacheStartTrimThreshold));
-            pw.print(" mMemCacheTrimToThreshold=");
-            pw.println(Formatter.formatFileSize(context, mMemCacheTrimToThreshold));
-
-            pw.print("  mIsBootImageOnDisk="); pw.println(mIsBootImageOnDisk);
         } else {
             Shell shell = new Shell();
             shell.exec(mRemoteService, null, fd, null, args, null, new ResultReceiver(null));
         }
     }
 
-    /**
-    * This method sends a notification to NotificationManager to display
-    * an error dialog indicating low disk space and launch the Installer
-    * application
-    */
-    private void sendNotification(int seq) {
+    private void updateNotifications(VolumeInfo vol, int oldLevel, int newLevel) {
         final Context context = getContext();
-        if(localLOGV) Slog.i(TAG, "Sending low memory notification");
-        //log the event to event log with the amount of free storage(in bytes) left on the device
-        EventLog.writeEvent(EventLogTags.LOW_STORAGE, mFreeMem);
-        //  Pack up the values and broadcast them to everyone
-        Intent lowMemIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
-        lowMemIntent.putExtra("memory", mFreeMem);
-        lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        NotificationManager notificationMgr =
-                (NotificationManager)context.getSystemService(
-                        Context.NOTIFICATION_SERVICE);
-        CharSequence title = context.getText(
-                com.android.internal.R.string.low_internal_storage_view_title);
-        CharSequence details = context.getText(mIsBootImageOnDisk
-                ? com.android.internal.R.string.low_internal_storage_view_text
-                : com.android.internal.R.string.low_internal_storage_view_text_no_boot);
-        PendingIntent intent = PendingIntent.getActivityAsUser(context, 0,  lowMemIntent, 0,
-                null, UserHandle.CURRENT);
-        Notification notification =
-                new Notification.Builder(context, SystemNotificationChannels.ALERTS)
-                        .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
-                        .setTicker(title)
-                        .setColor(context.getColor(
-                            com.android.internal.R.color.system_notification_accent_color))
-                        .setContentTitle(title)
-                        .setContentText(details)
-                        .setContentIntent(intent)
-                        .setStyle(new Notification.BigTextStyle()
-                              .bigText(details))
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setCategory(Notification.CATEGORY_SYSTEM)
-                        .extend(new Notification.TvExtender()
-                                .setChannelId(TV_NOTIFICATION_CHANNEL_ID))
-                        .build();
-        notification.flags |= Notification.FLAG_NO_CLEAR;
-        notificationMgr.notifyAsUser(null, SystemMessage.NOTE_LOW_STORAGE, notification,
-                UserHandle.ALL);
-        Intent broadcast = new Intent(mStorageLowIntent);
-        if (seq != 0) {
-            broadcast.putExtra(EXTRA_SEQUENCE, seq);
+        final UUID uuid = StorageManager.convert(vol.getFsUuid());
+
+        if (State.isEntering(State.LEVEL_LOW, oldLevel, newLevel)) {
+            Intent lowMemIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
+            lowMemIntent.putExtra(StorageManager.EXTRA_UUID, uuid);
+            lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            final CharSequence title = context.getText(
+                    com.android.internal.R.string.low_internal_storage_view_title);
+
+            final CharSequence details;
+            if (StorageManager.UUID_DEFAULT.equals(uuid)) {
+                details = context.getText(isBootImageOnDisk()
+                        ? com.android.internal.R.string.low_internal_storage_view_text
+                        : com.android.internal.R.string.low_internal_storage_view_text_no_boot);
+            } else {
+                details = context.getText(
+                        com.android.internal.R.string.low_internal_storage_view_text);
+            }
+
+            PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0,
+                    null, UserHandle.CURRENT);
+            Notification notification =
+                    new Notification.Builder(context, SystemNotificationChannels.ALERTS)
+                            .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
+                            .setTicker(title)
+                            .setColor(context.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                            .setContentTitle(title)
+                            .setContentText(details)
+                            .setContentIntent(intent)
+                            .setStyle(new Notification.BigTextStyle()
+                                  .bigText(details))
+                            .setVisibility(Notification.VISIBILITY_PUBLIC)
+                            .setCategory(Notification.CATEGORY_SYSTEM)
+                            .extend(new Notification.TvExtender()
+                                    .setChannelId(TV_NOTIFICATION_CHANNEL_ID))
+                            .build();
+            notification.flags |= Notification.FLAG_NO_CLEAR;
+            mNotifManager.notifyAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
+                    notification, UserHandle.ALL);
+        } else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
+            mNotifManager.cancelAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
+                    UserHandle.ALL);
         }
-        context.sendStickyBroadcastAsUser(broadcast, UserHandle.ALL);
     }
 
-    /**
-     * Cancels low storage notification and sends OK intent.
-     */
-    private void cancelNotification(int seq) {
-        final Context context = getContext();
-        if(localLOGV) Slog.i(TAG, "Canceling low memory notification");
-        NotificationManager mNotificationMgr =
-                (NotificationManager)context.getSystemService(
-                        Context.NOTIFICATION_SERVICE);
-        //cancel notification since memory has been freed
-        mNotificationMgr.cancelAsUser(null, SystemMessage.NOTE_LOW_STORAGE, UserHandle.ALL);
-
-        context.removeStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
-        Intent broadcast = new Intent(mStorageOkIntent);
-        if (seq != 0) {
-            broadcast.putExtra(EXTRA_SEQUENCE, seq);
+    private void updateBroadcasts(VolumeInfo vol, int oldLevel, int newLevel, int seq) {
+        if (!Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, vol.getFsUuid())) {
+            // We don't currently send broadcasts for secondary volumes
+            return;
         }
-        context.sendBroadcastAsUser(broadcast, UserHandle.ALL);
-    }
 
-    /**
-     * Send a notification when storage is full.
-     */
-    private void sendFullNotification() {
-        if(localLOGV) Slog.i(TAG, "Sending memory full notification");
-        getContext().sendStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL);
-    }
+        final Intent lowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS)
+                .putExtra(EXTRA_SEQUENCE, seq);
+        final Intent notLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS)
+                .putExtra(EXTRA_SEQUENCE, seq);
 
-    /**
-     * Cancels memory full notification and sends "not full" intent.
-     */
-    private void cancelFullNotification() {
-        if(localLOGV) Slog.i(TAG, "Canceling memory full notification");
-        getContext().removeStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL);
-        getContext().sendBroadcastAsUser(mStorageNotFullIntent, UserHandle.ALL);
+        if (State.isEntering(State.LEVEL_LOW, oldLevel, newLevel)) {
+            getContext().sendStickyBroadcastAsUser(lowIntent, UserHandle.ALL);
+        } else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
+            getContext().removeStickyBroadcastAsUser(lowIntent, UserHandle.ALL);
+            getContext().sendBroadcastAsUser(notLowIntent, UserHandle.ALL);
+        }
+
+        final Intent fullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
+                .putExtra(EXTRA_SEQUENCE, seq);
+        final Intent notFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)
+                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
+                .putExtra(EXTRA_SEQUENCE, seq);
+
+        if (State.isEntering(State.LEVEL_FULL, oldLevel, newLevel)) {
+            getContext().sendStickyBroadcastAsUser(fullIntent, UserHandle.ALL);
+        } else if (State.isLeaving(State.LEVEL_FULL, oldLevel, newLevel)) {
+            getContext().removeStickyBroadcastAsUser(fullIntent, UserHandle.ALL);
+            getContext().sendBroadcastAsUser(notFullIntent, UserHandle.ALL);
+        }
     }
 
     private static class CacheFileDeletedObserver extends FileObserver {
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 4044fdb..b937f9d 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -96,6 +96,7 @@
 public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
 
     public static final String TAG = "VrManagerService";
+    static final boolean DBG = false;
 
     private static final int PENDING_STATE_DELAY_MS = 300;
     private static final int EVENT_LOG_SIZE = 32;
@@ -157,7 +158,7 @@
     private void setVrModeAllowedLocked(boolean allowed) {
         if (mVrModeAllowed != allowed) {
             mVrModeAllowed = allowed;
-            Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
+            if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
             if (mVrModeAllowed) {
                 consumeAndApplyPendingStateLocked();
             } else {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a38addb..9d8f124 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -52,6 +52,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -346,12 +347,12 @@
         mAppTransitionState = APP_STATE_TIMEOUT;
     }
 
-    Bitmap getAppTransitionThumbnailHeader(int taskId) {
+    GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
         AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
         if (spec == null) {
             spec = mDefaultNextAppTransitionAnimationSpec;
         }
-        return spec != null ? spec.bitmap : null;
+        return spec != null ? spec.buffer : null;
     }
 
     /** Returns whether the next thumbnail transition is aspect scaled up. */
@@ -716,9 +717,9 @@
     }
 
     private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height,
-            Bitmap bitmap) {
+            GraphicBuffer buffer) {
         mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
-                bitmap, new Rect(left, top, left + width, top + height));
+                buffer, new Rect(left, top, left + width, top + height));
     }
 
     /**
@@ -943,7 +944,7 @@
      * when a thumbnail is specified with the pending animation override.
      */
     Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
-            Bitmap thumbnailHeader, final int taskId, int uiMode, int orientation) {
+            GraphicBuffer thumbnailHeader, final int taskId, int uiMode, int orientation) {
         Animation a;
         final int thumbWidthI = thumbnailHeader.getWidth();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
@@ -1296,7 +1297,7 @@
      * when a thumbnail is specified with the pending animation override.
      */
     Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit,
-            Bitmap thumbnailHeader) {
+            GraphicBuffer thumbnailHeader) {
         Animation a;
         getDefaultNextAppTransitionStartRect(mTmpRect);
         final int thumbWidthI = thumbnailHeader.getWidth();
@@ -1341,7 +1342,7 @@
             int transit, int taskId) {
         final int appWidth = containingFrame.width();
         final int appHeight = containingFrame.height();
-        Bitmap thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
+        final GraphicBuffer thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
         Animation a;
         getDefaultNextAppTransitionStartRect(mTmpRect);
         final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
@@ -1714,7 +1715,7 @@
         }
     }
 
-    void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
+    void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
                                            IRemoteCallback startedCallback, boolean scaleUp) {
         if (isTransitionSet()) {
             clear();
@@ -1729,7 +1730,7 @@
         }
     }
 
-    void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
+    void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX, int startY,
             int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
         if (isTransitionSet()) {
             clear();
@@ -1763,7 +1764,7 @@
                             // to be set.
                             Rect rect = spec.rect;
                             putDefaultNextAppTransitionCoordinates(rect.left, rect.top,
-                                    rect.width(), rect.height(), spec.bitmap);
+                                    rect.width(), rect.height(), spec.buffer);
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 221e795..b5476d7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3492,10 +3492,15 @@
 
             if (win != null) {
                 final int req = win.mAttrs.screenOrientation;
-                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
                 if (policy.isKeyguardHostWindow(win.mAttrs)) {
                     mLastKeyguardForcedOrientation = req;
+                    if (mService.mKeyguardGoingAway) {
+                        // Keyguard can't affect the orientation if it is going away...
+                        mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+                        return SCREEN_ORIENTATION_UNSET;
+                    }
                 }
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
                 return (mLastWindowForcedOrientation = req);
             }
 
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index fc4ec28..9a9e29a 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -92,17 +92,16 @@
     private final Rect mStableInsets = new Rect();
 
     // The size and position information that describes where the pinned stack will go by default.
+    private int mDefaultMinSize;
     private int mDefaultStackGravity;
     private float mDefaultAspectRatio;
     private Point mScreenEdgeInsets;
+    private int mCurrentMinSize;
 
     // The aspect ratio bounds of the PIP.
     private float mMinAspectRatio;
     private float mMaxAspectRatio;
 
-    // The minimum edge size of the normal PiP bounds.
-    private int mMinSize;
-
     // Temp vars for calculation
     private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
     private final Rect mTmpInsets = new Rect();
@@ -124,6 +123,13 @@
         }
 
         @Override
+        public void setMinEdgeSize(int minEdgeSize) {
+            mHandler.post(() -> {
+                mCurrentMinSize = Math.max(mDefaultMinSize, minEdgeSize);
+            });
+        }
+
+        @Override
         public int getDisplayRotation() {
             synchronized (mService.mWindowMap) {
                 return mDisplayInfo.rotation;
@@ -160,10 +166,12 @@
      */
     private void reloadResources() {
         final Resources res = mService.mContext.getResources();
-        mMinSize = res.getDimensionPixelSize(
+        mDefaultMinSize = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
+        mCurrentMinSize = mDefaultMinSize;
         mDefaultAspectRatio = res.getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
+        mAspectRatio = mDefaultAspectRatio;
         final String screenEdgeInsetsDpString = res.getString(
                 com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
         final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
@@ -212,11 +220,15 @@
      * Returns the current bounds (or the default bounds if there are no current bounds) with the
      * specified aspect ratio.
      */
-    Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio) {
+    Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
+            boolean useCurrentMinEdgeSize) {
         // Save the snap fraction, calculate the aspect ratio based on screen size
         final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
                 getMovementBounds(stackBounds));
-        final Size size = getSize(aspectRatio);
+
+        final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
+        final Size size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
+                mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
         final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
         final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
         stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
@@ -228,16 +240,6 @@
     }
 
     /**
-     * @return the size of the PIP based on the given {@param aspectRatio}.
-     */
-    Size getSize(float aspectRatio) {
-        synchronized (mService.mWindowMap) {
-            return mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mMinSize,
-                    mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
-        }
-    }
-
-    /**
      * @return the default bounds to show the PIP when there is no active PIP.
      */
     Rect getDefaultBounds() {
@@ -246,7 +248,8 @@
             getInsetBounds(insetBounds);
 
             final Rect defaultBounds = new Rect();
-            final Size size = getSize(mDefaultAspectRatio);
+            final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
+                    mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
             Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
                     0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
             return defaultBounds;
@@ -401,7 +404,8 @@
                     getInsetBounds(insetBounds);
                     final Rect normalBounds = getDefaultBounds();
                     if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
-                        transformBoundsToAspectRatio(normalBounds, mAspectRatio);
+                        transformBoundsToAspectRatio(normalBounds, mAspectRatio,
+                                false /* useCurrentMinEdgeSize */);
                     }
                     final Rect animatingBounds = mTmpAnimatingBoundsRect;
                     final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index 0c628ac..989e8f2 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 
 import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
 import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
@@ -36,7 +35,8 @@
  */
 public class PinnedStackWindowController extends StackWindowController {
 
-    private Rect mTmpBoundsRect = new Rect();
+    private Rect mTmpFromBounds = new Rect();
+    private Rect mTmpToBounds = new Rect();
 
     public PinnedStackWindowController(int stackId, PinnedStackWindowListener listener,
             int displayId, boolean onTop, Rect outBounds) {
@@ -44,16 +44,16 @@
     }
 
     /**
-     * @param useExistingStackBounds Apply {@param aspectRatio} to the existing target stack bounds
-     *                               if possible
+     * @return the {@param currentStackBounds} transformed to the give {@param aspectRatio}.  If
+     *         {@param currentStackBounds} is null, then the {@param aspectRatio} is applied to the
+     *         default bounds.
      */
-    public Rect getPictureInPictureBounds(float aspectRatio, boolean useExistingStackBounds) {
+    public Rect getPictureInPictureBounds(float aspectRatio, Rect stackBounds) {
         synchronized (mWindowMap) {
             if (!mService.mSupportsPictureInPicture || mContainer == null) {
                 return null;
             }
 
-            final Rect stackBounds;
             final DisplayContent displayContent = mContainer.getDisplayContent();
             if (displayContent == null) {
                 return null;
@@ -61,18 +61,14 @@
 
             final PinnedStackController pinnedStackController =
                     displayContent.getPinnedStackController();
-            if (useExistingStackBounds) {
-                // If the stack exists, then use its final bounds to calculate the new aspect ratio
-                // bounds
-                stackBounds = new Rect();
-                mContainer.getAnimationOrCurrentBounds(stackBounds);
-            } else {
-                // Otherwise, just calculate the aspect ratio bounds from the default bounds
+            if (stackBounds == null) {
+                // Calculate the aspect ratio bounds from the default bounds
                 stackBounds = pinnedStackController.getDefaultBounds();
             }
 
             if (pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)) {
-                return pinnedStackController.transformBoundsToAspectRatio(stackBounds, aspectRatio);
+                return pinnedStackController.transformBoundsToAspectRatio(stackBounds, aspectRatio,
+                        true /* useCurrentMinEdgeSize */);
             } else {
                 return stackBounds;
             }
@@ -104,10 +100,10 @@
                 }
                 schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
 
-                mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
-                if (!mTmpBoundsRect.isEmpty()) {
+                mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpToBounds);
+                if (!mTmpToBounds.isEmpty()) {
                     // If there is a fullscreen bounds, use that
-                    toBounds = new Rect(mTmpBoundsRect);
+                    toBounds = new Rect(mTmpToBounds);
                 } else {
                     // Otherwise, use the display bounds
                     toBounds = new Rect();
@@ -142,16 +138,15 @@
                 return;
             }
 
-            final Rect toBounds = getPictureInPictureBounds(aspectRatio,
-                    true /* useExistingStackBounds */);
-            final Rect targetBounds = new Rect();
-            mContainer.getAnimationOrCurrentBounds(targetBounds);
             final PinnedStackController pinnedStackController =
                     mContainer.getDisplayContent().getPinnedStackController();
 
             if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) != 0) {
-                if (!toBounds.equals(targetBounds)) {
-                    animateResizePinnedStack(toBounds, null /* sourceHintBounds */,
+                mContainer.getAnimationOrCurrentBounds(mTmpFromBounds);
+                mTmpToBounds.set(mTmpFromBounds);
+                getPictureInPictureBounds(aspectRatio, mTmpToBounds);
+                if (!mTmpToBounds.equals(mTmpFromBounds)) {
+                    animateResizePinnedStack(mTmpToBounds, null /* sourceHintBounds */,
                             -1 /* duration */, false /* fromFullscreen */);
                 }
                 pinnedStackController.setAspectRatio(
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75b..fb500bc 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -858,14 +858,20 @@
         final int privateflags = attrs.privateFlags;
         boolean displayHasContent = false;
 
+        if (DEBUG_KEEP_SCREEN_ON && (attrFlags & FLAG_KEEP_SCREEN_ON) != 0
+                && w != mService.mLastWakeLockHoldingWindow) {
+            Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w
+                    + " has FLAG_KEEP_SCREEN_ON set, hasSurface=" + w.mHasSurface
+                    + ", canBeSeen=" + canBeSeen);
+        }
+
         if (w.mHasSurface && canBeSeen) {
             if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
                 mHoldScreen = w.mSession;
                 mHoldScreenWindow = w;
             } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
                 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
-                        + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
-                        + Debug.getCallers(10));
+                        + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!!");
             }
             if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
                 mScreenBrightness = w.mAttrs.screenBrightness;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index b266778..1f7ef50 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -31,6 +31,9 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.util.ArraySet;
+import android.view.DisplayListCanvas;
+import android.view.RenderNode;
+import android.view.ThreadedRenderer;
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerPolicy.ScreenOffListener;
 import android.view.WindowManagerPolicy.StartingSurface;
@@ -238,19 +241,22 @@
         final int color = task.getTaskDescription().getBackgroundColor();
         final int statusBarColor = task.getTaskDescription().getStatusBarColor();
         final int navigationBarColor = task.getTaskDescription().getNavigationBarColor();
-        final Bitmap b = Bitmap.createBitmap(mainWindow.getFrameLw().width(),
-                mainWindow.getFrameLw().height(), ARGB_8888);
-        final Canvas c = new Canvas(b);
-        c.drawColor(color);
         final LayoutParams attrs = mainWindow.getAttrs();
         final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
                 attrs.privateFlags, attrs.systemUiVisibility, statusBarColor, navigationBarColor);
+        final int width = mainWindow.getFrameLw().width();
+        final int height = mainWindow.getFrameLw().height();
+
+        final RenderNode node = RenderNode.create("TaskSnapshotController", null);
+        node.setLeftTopRightBottom(0, 0, width, height);
+        node.setClipToBounds(false);
+        final DisplayListCanvas c = node.start(width, height);
+        c.drawColor(color);
         decorPainter.setInsets(mainWindow.mContentInsets, mainWindow.mStableInsets);
         decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
+        node.end(c);
+        final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height);
 
-        // Flush writer.
-        c.setBitmap(null);
-        final Bitmap hwBitmap = b.copy(HARDWARE, false /* isMutable */);
         return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(),
                 topChild.getConfiguration().orientation, mainWindow.mStableInsets,
                 false /* reduced */, 1.0f /* scale */);
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 8279b51..c080f34 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -77,5 +77,5 @@
     static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
 
     static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
-    static final boolean DEBUG_KEEP_SCREEN_ON = false;
+    static final boolean DEBUG_KEEP_SCREEN_ON = true;
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a15891b..02fdfee 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -123,6 +123,7 @@
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -349,6 +350,7 @@
     private static final int ANIMATION_DURATION_SCALE = 2;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
+    boolean mKeyguardGoingAway;
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -2629,7 +2631,7 @@
     }
 
     @Override
-    public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
+    public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX,
             int startY, IRemoteCallback startedCallback, boolean scaleUp) {
         synchronized(mWindowMap) {
             mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
@@ -2638,7 +2640,7 @@
     }
 
     @Override
-    public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
+    public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
             boolean scaleUp) {
         synchronized(mWindowMap) {
@@ -2876,6 +2878,12 @@
         }
     }
 
+    public void setKeyguardGoingAway(boolean keyguardGoingAway) {
+        synchronized (mWindowMap) {
+            mKeyguardGoingAway = keyguardGoingAway;
+        }
+    }
+
     // -------------------------------------------------------------
     // Misc IWindowSession methods
     // -------------------------------------------------------------
@@ -3816,20 +3824,22 @@
         long origId = Binder.clearCallingIdentity();
 
         try {
-            final boolean rotationChanged;
             // TODO(multi-display): Update rotation for different displays separately.
-            final DisplayContent displayContent = getDefaultDisplayContentLocked();
+            final boolean rotationChanged;
+            final int displayId;
             synchronized (mWindowMap) {
+                final DisplayContent displayContent = getDefaultDisplayContentLocked();
                 rotationChanged = displayContent.updateRotationUnchecked(
                         false /* inTransaction */);
                 if (!rotationChanged || forceRelayout) {
-                    getDefaultDisplayContentLocked().setLayoutNeeded();
+                    displayContent.setLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement();
                 }
+                displayId = displayContent.getDisplayId();
             }
 
             if (rotationChanged || alwaysSendConfiguration) {
-                sendNewConfiguration(displayContent.getDisplayId());
+                sendNewConfiguration(displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -6457,7 +6467,7 @@
                     pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
                     pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
                     pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
-            pw.print(" mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
+            pw.print("  mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
             pw.println("  mLayoutToAnim:");
             mAppTransition.dump(pw, "    ");
         }
@@ -6890,9 +6900,11 @@
                 "registerDockedStackListener()")) {
             return;
         }
-        // TODO(multi-display): The listener is registered on the default display only.
-        getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
-                listener);
+        synchronized (mWindowMap) {
+            // TODO(multi-display): The listener is registered on the default display only.
+            getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
+                    listener);
+        }
     }
 
     @Override
@@ -7173,6 +7185,11 @@
         }
 
         @Override
+        public boolean isKeyguardGoingAway() {
+            return WindowManagerService.this.mKeyguardGoingAway;
+        }
+
+        @Override
         public void showGlobalActions() {
             WindowManagerService.this.showGlobalActions();
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index acd7703..44a867c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2202,18 +2202,30 @@
         }
     }
 
-    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration) {
-        if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
-                == SOFT_INPUT_ADJUST_RESIZE) {
-            mLayoutNeeded = true;
-        }
-        if (isDrawnLw() && mService.okToDisplay()) {
-            mWinAnimator.applyEnterAnimationLocked();
-        }
+    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
+            boolean wasVisible) {
+        // We need to turn on screen regardless of visibility.
         if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
             mTurnOnScreen = true;
         }
+
+        // If we were already visible, skip rest of preparation.
+        if (wasVisible) {
+            if (DEBUG_VISIBILITY) Slog.v(TAG,
+                    "Already visible and does not turn on screen, skip preparing: " + this);
+            return;
+        }
+
+        if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
+                == SOFT_INPUT_ADJUST_RESIZE) {
+            mLayoutNeeded = true;
+        }
+
+        if (isDrawnLw() && mService.okToDisplay()) {
+            mWinAnimator.applyEnterAnimationLocked();
+        }
+
         if (isConfigChanged()) {
             final Configuration globalConfig = mService.mRoot.getConfiguration();
             final Configuration overrideConfig = getMergedOverrideConfiguration();
@@ -3407,7 +3419,7 @@
             pw.print(prefix); pw.print("mOrientationChanging=");
                     pw.print(mOrientationChanging);
                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
-                    pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
+                    pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen);
                     pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
         }
         if (mLastFreezeDuration != 0) {
@@ -4348,9 +4360,9 @@
         mLastVisibleLayoutRotation = getDisplayContent().getRotation();
 
         mWinAnimator.mEnteringAnimation = true;
-        if (!wasVisible) {
-            prepareWindowToDisplayDuringRelayout(mergedConfiguration);
-        }
+
+        prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
             // on the new one. This prevents blinking when we change elevation of freeform and
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d75afcf..73f8d27 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -687,6 +687,7 @@
             mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
                     attrs.getTitle().toString(),
                     width, height, format, flags, this, windowType, ownerUid);
+            mSurfaceFormat = format;
 
             w.setHasSurface(true);
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 4a1a705..3c13a1e 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -38,11 +38,9 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 
 import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.os.Binder;
 import android.os.Debug;
 import android.os.Trace;
 import android.util.ArraySet;
@@ -675,8 +673,9 @@
             return;
         }
         final int taskId = appToken.getTask().mTaskId;
-        Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
-        if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
+        final GraphicBuffer thumbnailHeader =
+                mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
+        if (thumbnailHeader == null) {
             if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
             return;
         }
@@ -694,18 +693,17 @@
             SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
                     "thumbnail anim", dirty.width(), dirty.height(),
                     PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN,
-                    appToken.windowType, window.mOwnerUid);
+                    appToken.windowType,
+                    window != null ? window.mOwnerUid : Binder.getCallingUid());
             surfaceControl.setLayerStack(display.getLayerStack());
             if (SHOW_TRANSACTIONS) {
                 Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
             }
 
-            // Draw the thumbnail onto the surface
+            // Transfer the thumbnail to the surface
             Surface drawSurface = new Surface();
             drawSurface.copyFrom(surfaceControl);
-            Canvas c = drawSurface.lockCanvas(dirty);
-            c.drawBitmap(thumbnailHeader, 0, 0, null);
-            drawSurface.unlockCanvasAndPost(c);
+            drawSurface.attachAndQueueBuffer(thumbnailHeader);
             drawSurface.release();
 
             // Get the thumbnail animation
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 9cfa542..bac1216 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -235,8 +235,7 @@
                     if (mStackId == ActivityManager.StackId.PINNED_STACK_ID) {
                         mStack = new PinnedActivityStack(this, recents, mOnTop) {
                             @Override
-                            Rect getPictureInPictureBounds(float aspectRatio,
-                                    boolean useExistingStackBounds) {
+                            Rect getDefaultPictureInPictureBounds(float aspectRatio) {
                                 return new Rect(50, 50, 100, 100);
                             }
                         };
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 5f51898..c809c32 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import android.util.MergedConfiguration;
+import android.view.WindowManager;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -204,4 +206,20 @@
         assertEquals(mediaChild, windows.pollFirst());
         assertTrue(windows.isEmpty());
     }
+
+    @Test
+    public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
+        testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
+    }
+
+    private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
+        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+        root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+        root.mTurnOnScreen = false;
+
+        root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
+                wasVisible /*wasVisible*/);
+        assertTrue(root.mTurnOnScreen);
+    }
 }
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 16b73d5..562443f 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -62,6 +62,8 @@
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.storage.CacheQuotaStrategy;
 
+import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 
 public class StorageStatsService extends IStorageStatsManager.Stub {
@@ -181,29 +183,42 @@
     public long getFreeBytes(String volumeUuid, String callingPackage) {
         // NOTE: No permissions required
 
-        long cacheBytes = 0;
         final long token = Binder.clearCallingIdentity();
         try {
+            final File path;
+            try {
+                path = mStorage.findPathForUuid(volumeUuid);
+            } catch (FileNotFoundException e) {
+                throw new ParcelableException(e);
+            }
+
+            // Free space is usable bytes plus any cached data that we're
+            // willing to automatically clear. To avoid user confusion, this
+            // logic should be kept in sync with getAllocatableBytes().
             if (isQuotaSupported(volumeUuid, callingPackage)) {
-                for (UserInfo user : mUser.getUsers()) {
-                    final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
-                    cacheBytes += stats.cacheBytes;
-                }
+                final long cacheTotal = getCacheBytes(volumeUuid, callingPackage);
+                final long cacheReserved = mStorage.getStorageCacheBytes(path);
+                final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
+
+                return path.getUsableSpace() + cacheClearable;
+            } else {
+                return path.getUsableSpace();
             }
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+    }
 
-        if (volumeUuid == StorageManager.UUID_PRIVATE_INTERNAL) {
-            return Environment.getDataDirectory().getFreeSpace() + cacheBytes;
-        } else {
-            final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid);
-            if (vol == null) {
-                throw new ParcelableException(
-                        new IOException("Failed to find storage device for UUID " + volumeUuid));
-            }
-            return vol.getPath().getFreeSpace() + cacheBytes;
+    @Override
+    public long getCacheBytes(String volumeUuid, String callingPackage) {
+        enforcePermission(Binder.getCallingUid(), callingPackage);
+
+        long cacheBytes = 0;
+        for (UserInfo user : mUser.getUsers()) {
+            final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
+            cacheBytes += stats.cacheBytes;
         }
+        return cacheBytes;
     }
 
     @Override
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index bf18949..b2f1f62 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -160,7 +160,7 @@
 cc_test_host {
     name: "aapt2_tests",
     srcs: ["**/*_test.cpp"],
-    static_libs: ["libaapt2"],
+    static_libs: ["libaapt2", "libgmock"],
     defaults: ["aapt_defaults"],
 }
 
diff --git a/tools/aapt2/Format.proto b/tools/aapt2/Format.proto
index 0917129..870b735 100644
--- a/tools/aapt2/Format.proto
+++ b/tools/aapt2/Format.proto
@@ -69,6 +69,7 @@
 	optional Visibility visibility = 1;
 	optional Source source = 2;
 	optional string comment = 3;
+	optional bool allow_new = 4;
 }
 
 message Entry {
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 0d1850f..57ae270 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -92,14 +92,14 @@
   Source source;
   ResourceId id;
   Maybe<SymbolState> symbol_state;
+  bool allow_new = false;
   std::string comment;
   std::unique_ptr<Value> value;
   std::list<ParsedResource> child_resources;
 };
 
 // Recursively adds resources to the ResourceTable.
-static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag,
-                                ParsedResource* res) {
+static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) {
   StringPiece trimmed_comment = util::TrimWhitespace(res->comment);
   if (trimmed_comment.size() != res->comment.size()) {
     // Only if there was a change do we re-assign.
@@ -111,6 +111,7 @@
     symbol.state = res->symbol_state.value();
     symbol.source = res->source;
     symbol.comment = res->comment;
+    symbol.allow_new = res->allow_new;
     if (!table->SetSymbolState(res->name, res->id, symbol, diag)) {
       return false;
     }
@@ -121,8 +122,8 @@
     res->value->SetComment(std::move(res->comment));
     res->value->SetSource(std::move(res->source));
 
-    if (!table->AddResource(res->name, res->id, res->config, res->product,
-                            std::move(res->value), diag)) {
+    if (!table->AddResource(res->name, res->id, res->config, res->product, std::move(res->value),
+                            diag)) {
       return false;
     }
   }
@@ -849,6 +850,7 @@
                                       ParsedResource* out_resource) {
   if (ParseSymbolImpl(parser, out_resource)) {
     out_resource->symbol_state = SymbolState::kUndefined;
+    out_resource->allow_new = true;
     return true;
   }
   return false;
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index faa6607..e3abde6 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -777,8 +777,7 @@
   ASSERT_FALSE(TestParse(input));
 }
 
-TEST_F(ResourceParserTest,
-       AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
+TEST_F(ResourceParserTest, AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
   std::string input = R"EOF(<add-resource name="bar" type="string" />)EOF";
   ASSERT_TRUE(TestParse(input));
 
@@ -788,6 +787,7 @@
   const ResourceEntry* entry = result.value().entry;
   ASSERT_NE(nullptr, entry);
   EXPECT_EQ(SymbolState::kUndefined, entry->symbol_status.state);
+  EXPECT_TRUE(entry->symbol_status.allow_new);
 }
 
 TEST_F(ResourceParserTest, ParseItemElementWithFormat) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 1947628..168004f 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -440,8 +440,7 @@
   return true;
 }
 
-bool ResourceTable::SetSymbolState(const ResourceNameRef& name,
-                                   const ResourceId& res_id,
+bool ResourceTable::SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id,
                                    const Symbol& symbol, IDiagnostics* diag) {
   return SetSymbolStateImpl(name, res_id, symbol, ValidateName, diag);
 }
@@ -489,8 +488,7 @@
     diag->Error(DiagMessage(symbol.source)
                 << "trying to add resource '" << name << "' with ID " << res_id
                 << " but resource already has ID "
-                << ResourceId(package->id.value(), type->id.value(),
-                              entry->id.value()));
+                << ResourceId(package->id.value(), type->id.value(), entry->id.value()));
     return false;
   }
 
@@ -505,6 +503,11 @@
     type->symbol_status.state = SymbolState::kPublic;
   }
 
+  if (symbol.allow_new) {
+    // This symbol can be added as a new resource when merging (if it belongs to an overlay).
+    entry->symbol_status.allow_new = true;
+  }
+
   if (symbol.state == SymbolState::kUndefined &&
       entry->symbol_status.state != SymbolState::kUndefined) {
     // We can't undefine a symbol (remove its visibility). Ignore.
@@ -517,7 +520,10 @@
     return true;
   }
 
-  entry->symbol_status = std::move(symbol);
+  // This symbol definition takes precedence, replace.
+  entry->symbol_status.state = symbol.state;
+  entry->symbol_status.source = symbol.source;
+  entry->symbol_status.comment = symbol.comment;
   return true;
 }
 
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index b032121..4295d06 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -50,6 +50,10 @@
 struct Symbol {
   SymbolState state = SymbolState::kUndefined;
   Source source;
+
+  // Whether this entry (originating from an overlay) can be added as a new resource.
+  bool allow_new = false;
+
   std::string comment;
 };
 
@@ -223,8 +227,7 @@
   bool SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id,
                       const Symbol& symbol, IDiagnostics* diag);
 
-  bool SetSymbolStateAllowMangled(const ResourceNameRef& name,
-                                  const ResourceId& res_id,
+  bool SetSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId& res_id,
                                   const Symbol& symbol, IDiagnostics* diag);
 
   struct SearchResult {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 1bb7d9b..818c8ce 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -496,19 +496,17 @@
 
 std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str) {
   if (Maybe<bool> maybe_result = ParseBool(str)) {
-    android::Res_value value = {};
-    value.dataType = android::Res_value::TYPE_INT_BOOLEAN;
-
-    if (maybe_result.value()) {
-      value.data = 0xffffffffu;
-    } else {
-      value.data = 0;
-    }
-    return util::make_unique<BinaryPrimitive>(value);
+    const uint32_t data = maybe_result.value() ? 0xffffffffu : 0u;
+    return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN, data);
   }
   return {};
 }
 
+std::unique_ptr<BinaryPrimitive> MakeBool(bool val) {
+  return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN,
+                                            val ? 0xffffffffu : 0u);
+}
+
 std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) {
   std::u16string str16 = util::Utf8ToUtf16(str);
   android::Res_value value;
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 48922b7..da0fc8e 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -147,6 +147,9 @@
  */
 std::unique_ptr<BinaryPrimitive> TryParseBool(const android::StringPiece& str);
 
+// Returns a boolean BinaryPrimitive.
+std::unique_ptr<BinaryPrimitive> MakeBool(bool val);
+
 /*
  * Returns a BinaryPrimitve object representing an integer if the string was
  * parsed as one.
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 34bd2b4..abfdec4 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -29,6 +29,11 @@
 
 namespace aapt {
 
+std::ostream& operator<<(std::ostream& out, const Value& value) {
+  value.Print(&out);
+  return out;
+}
+
 template <typename Derived>
 void BaseValue<Derived>::Accept(RawValueVisitor* visitor) {
   visitor->Visit(static_cast<Derived*>(this));
@@ -346,6 +351,15 @@
   weak_ = w;
 }
 
+std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) {
+  if (s.symbol.name) {
+    out << s.symbol.name.value().entry;
+  } else {
+    out << "???";
+  }
+  return out << "=" << s.value;
+}
+
 template <typename T>
 constexpr T* add_pointer(T& val) {
   return &val;
@@ -361,31 +375,27 @@
     return false;
   }
 
-  if (type_mask != other->type_mask || min_int != other->min_int ||
-      max_int != other->max_int) {
+  if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) {
     return false;
   }
 
   std::vector<const Symbol*> sorted_a;
   std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
                  add_pointer<const Symbol>);
-  std::sort(sorted_a.begin(), sorted_a.end(),
-            [](const Symbol* a, const Symbol* b) -> bool {
-              return a->symbol.name < b->symbol.name;
-            });
+  std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool {
+    return a->symbol.name < b->symbol.name;
+  });
 
   std::vector<const Symbol*> sorted_b;
-  std::transform(other->symbols.begin(), other->symbols.end(),
-                 std::back_inserter(sorted_b), add_pointer<const Symbol>);
-  std::sort(sorted_b.begin(), sorted_b.end(),
-            [](const Symbol* a, const Symbol* b) -> bool {
-              return a->symbol.name < b->symbol.name;
-            });
+  std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b),
+                 add_pointer<const Symbol>);
+  std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool {
+    return a->symbol.name < b->symbol.name;
+  });
 
   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                     [](const Symbol* a, const Symbol* b) -> bool {
-                      return a->symbol.Equals(&b->symbol) &&
-                             a->value == b->value;
+                      return a->symbol.Equals(&b->symbol) && a->value == b->value;
                     });
 }
 
@@ -588,14 +598,50 @@
   return true;
 }
 
+std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
+  if (entry.key.name) {
+    out << entry.key.name.value();
+  } else if (entry.key.id) {
+    out << entry.key.id.value();
+  } else {
+    out << "???";
+  }
+  out << " = " << entry.value;
+  return out;
+}
+
+template <typename T>
+std::vector<T*> ToPointerVec(std::vector<T>& src) {
+  std::vector<T*> dst;
+  dst.reserve(src.size());
+  for (T& in : src) {
+    dst.push_back(&in);
+  }
+  return dst;
+}
+
+template <typename T>
+std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
+  std::vector<const T*> dst;
+  dst.reserve(src.size());
+  for (const T& in : src) {
+    dst.push_back(&in);
+  }
+  return dst;
+}
+
+static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
+  return a->key.name < b->key.name;
+}
+
 bool Style::Equals(const Value* value) const {
   const Style* other = ValueCast<Style>(value);
   if (!other) {
     return false;
   }
+
   if (bool(parent) != bool(other->parent) ||
-      (parent && other->parent &&
-       !parent.value().Equals(&other->parent.value()))) {
+      (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
     return false;
   }
 
@@ -603,26 +649,15 @@
     return false;
   }
 
-  std::vector<const Entry*> sorted_a;
-  std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a),
-                 add_pointer<const Entry>);
-  std::sort(sorted_a.begin(), sorted_a.end(),
-            [](const Entry* a, const Entry* b) -> bool {
-              return a->key.name < b->key.name;
-            });
+  std::vector<const Entry*> sorted_a = ToPointerVec(entries);
+  std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);
 
-  std::vector<const Entry*> sorted_b;
-  std::transform(other->entries.begin(), other->entries.end(),
-                 std::back_inserter(sorted_b), add_pointer<const Entry>);
-  std::sort(sorted_b.begin(), sorted_b.end(),
-            [](const Entry* a, const Entry* b) -> bool {
-              return a->key.name < b->key.name;
-            });
+  std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
+  std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);
 
   return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
                     [](const Entry* a, const Entry* b) -> bool {
-                      return a->key.Equals(&b->key) &&
-                             a->value->Equals(b->value.get());
+                      return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
                     });
 }
 
@@ -633,8 +668,7 @@
   style->comment_ = comment_;
   style->source_ = source_;
   for (auto& entry : entries) {
-    style->entries.push_back(
-        Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
+    style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
   }
   return style;
 }
@@ -642,26 +676,73 @@
 void Style::Print(std::ostream* out) const {
   *out << "(style) ";
   if (parent && parent.value().name) {
-    if (parent.value().private_reference) {
+    const Reference& parent_ref = parent.value();
+    if (parent_ref.private_reference) {
       *out << "*";
     }
-    *out << parent.value().name.value();
+    *out << parent_ref.name.value();
   }
   *out << " [" << util::Joiner(entries, ", ") << "]";
 }
 
-static ::std::ostream& operator<<(::std::ostream& out,
-                                  const Style::Entry& value) {
-  if (value.key.name) {
-    out << value.key.name.value();
-  } else if (value.key.id) {
-    out << value.key.id.value();
-  } else {
-    out << "???";
+Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
+  Style::Entry cloned_entry{entry.key};
+  if (entry.value != nullptr) {
+    cloned_entry.value.reset(entry.value->Clone(pool));
   }
-  out << " = ";
-  value.value->Print(&out);
-  return out;
+  return cloned_entry;
+}
+
+void Style::MergeWith(Style* other, StringPool* pool) {
+  if (other->parent) {
+    parent = other->parent;
+  }
+
+  // We can't assume that the entries are sorted alphabetically since they're supposed to be
+  // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
+  // them keying off that.
+  //
+  // Instead, sort the entries of each Style by their name in a separate structure. Then merge
+  // those.
+
+  std::vector<Entry*> this_sorted = ToPointerVec(entries);
+  std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);
+
+  std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
+  std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);
+
+  auto this_iter = this_sorted.begin();
+  const auto this_end = this_sorted.end();
+
+  auto other_iter = other_sorted.begin();
+  const auto other_end = other_sorted.end();
+
+  std::vector<Entry> merged_entries;
+  while (this_iter != this_end) {
+    if (other_iter != other_end) {
+      if ((*this_iter)->key.name < (*other_iter)->key.name) {
+        merged_entries.push_back(std::move(**this_iter));
+        ++this_iter;
+      } else {
+        // The other overrides.
+        merged_entries.push_back(CloneEntry(**other_iter, pool));
+        if ((*this_iter)->key.name == (*other_iter)->key.name) {
+          ++this_iter;
+        }
+        ++other_iter;
+      }
+    } else {
+      merged_entries.push_back(std::move(**this_iter));
+      ++this_iter;
+    }
+  }
+
+  while (other_iter != other_end) {
+    merged_entries.push_back(CloneEntry(**other_iter, pool));
+    ++other_iter;
+  }
+
+  entries = std::move(merged_entries);
 }
 
 bool Array::Equals(const Value* value) const {
@@ -758,11 +839,6 @@
   }
 }
 
-static ::std::ostream& operator<<(::std::ostream& out,
-                                  const std::unique_ptr<Item>& item) {
-  return out << *item;
-}
-
 bool Styleable::Equals(const Value* value) const {
   const Styleable* other = ValueCast<Styleable>(value);
   if (!other) {
@@ -810,8 +886,7 @@
 
 void Styleable::MergeWith(Styleable* other) {
   // Compare only names, because some References may already have their IDs
-  // assigned
-  // (framework IDs that don't change).
+  // assigned (framework IDs that don't change).
   std::set<Reference, NameOnlyComparator> references;
   references.insert(entries.begin(), entries.end());
   references.insert(other->entries.begin(), other->entries.end());
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 06f949f..ac5795f 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -40,7 +40,8 @@
 // type specific operations is to check the Value's type() and
 // cast it to the appropriate subclass. This isn't super clean,
 // but it is the simplest strategy.
-struct Value {
+class Value {
+ public:
   virtual ~Value() = default;
 
   // Whether this value is weak and can be overridden without warning or error. Default is false.
@@ -82,6 +83,8 @@
   // Human readable printout of this value.
   virtual void Print(std::ostream* out) const = 0;
 
+  friend std::ostream& operator<<(std::ostream& out, const Value& value);
+
  protected:
   Source source_;
   std::string comment_;
@@ -245,6 +248,8 @@
   struct Symbol {
     Reference symbol;
     uint32_t value;
+
+    friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
   };
 
   uint32_t type_mask;
@@ -266,6 +271,8 @@
   struct Entry {
     Reference key;
     std::unique_ptr<Item> value;
+
+    friend std::ostream& operator<<(std::ostream& out, const Entry& entry);
   };
 
   Maybe<Reference> parent;
@@ -278,6 +285,10 @@
   bool Equals(const Value* value) const override;
   Style* Clone(StringPool* new_pool) const override;
   void Print(std::ostream* out) const override;
+
+  // Merges `style` into this Style. All identical attributes of `style` take precedence, including
+  // the parent, if there is one.
+  void MergeWith(Style* style, StringPool* pool);
 };
 
 struct Array : public BaseValue<Array> {
@@ -307,20 +318,15 @@
   void MergeWith(Styleable* styleable);
 };
 
-// Stream operator for printing Value objects.
-inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
-  value.Print(&out);
-  return out;
-}
-
-inline ::std::ostream& operator<<(::std::ostream& out,
-                                  const Attribute::Symbol& s) {
-  if (s.symbol.name) {
-    out << s.symbol.name.value().entry;
+template <typename T>
+typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
+    std::ostream& out, const std::unique_ptr<T>& value) {
+  if (value == nullptr) {
+    out << "NULL";
   } else {
-    out << "???";
+    value->Print(&out);
   }
-  return out << "=" << s.value;
+  return out;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp
index 6922580..e154d93 100644
--- a/tools/aapt2/ResourceValues_test.cpp
+++ b/tools/aapt2/ResourceValues_test.cpp
@@ -148,4 +148,36 @@
   EXPECT_TRUE(a->Equals(b.get()));
 }
 
+TEST(ResourceValuesTest, StyleMerges) {
+  StringPool pool_a;
+  StringPool pool_b;
+
+  std::unique_ptr<Style> a =
+      test::StyleBuilder()
+          .SetParent("android:style/Parent")
+          .AddItem("android:attr/a", util::make_unique<String>(pool_a.MakeRef("FooA")))
+          .AddItem("android:attr/b", util::make_unique<String>(pool_a.MakeRef("FooB")))
+          .Build();
+
+  std::unique_ptr<Style> b =
+      test::StyleBuilder()
+          .SetParent("android:style/OverlayParent")
+          .AddItem("android:attr/c", util::make_unique<String>(pool_b.MakeRef("OverlayFooC")))
+          .AddItem("android:attr/a", util::make_unique<String>(pool_b.MakeRef("OverlayFooA")))
+          .Build();
+
+  a->MergeWith(b.get(), &pool_a);
+
+  StringPool pool;
+  std::unique_ptr<Style> expected =
+      test::StyleBuilder()
+          .SetParent("android:style/OverlayParent")
+          .AddItem("android:attr/a", util::make_unique<String>(pool.MakeRef("OverlayFooA")))
+          .AddItem("android:attr/b", util::make_unique<String>(pool.MakeRef("FooB")))
+          .AddItem("android:attr/c", util::make_unique<String>(pool.MakeRef("OverlayFooC")))
+          .Build();
+
+  EXPECT_TRUE(a->Equals(expected.get()));
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 5adf04a..e09a3979 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -478,7 +478,8 @@
 
   {
     std::string content;
-    if (!android::base::ReadFileToString(path_data.source.path, &content)) {
+    if (!android::base::ReadFileToString(path_data.source.path, &content,
+                                         true /*follow_symlinks*/)) {
       context->GetDiagnostics()->Error(DiagMessage(path_data.source)
                                        << android::base::SystemErrorCodeToString(errno));
       return false;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index ebec81b..740a401 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -633,7 +633,7 @@
 static bool LoadStableIdMap(IDiagnostics* diag, const std::string& path,
                             std::unordered_map<ResourceName, ResourceId>* out_id_map) {
   std::string content;
-  if (!android::base::ReadFileToString(path, &content)) {
+  if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) {
     diag->Error(DiagMessage(path) << "failed reading stable ID file");
     return false;
   }
diff --git a/tools/aapt2/integration-tests/SymlinkTest/Android.mk b/tools/aapt2/integration-tests/SymlinkTest/Android.mk
new file mode 100644
index 0000000..902fc65
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2017 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_PACKAGE_NAME := AaptSymlinkTest
+LOCAL_MODULE_TAGS := tests
+include $(BUILD_PACKAGE)
diff --git a/tools/aapt2/integration-tests/SymlinkTest/AndroidManifest.xml b/tools/aapt2/integration-tests/SymlinkTest/AndroidManifest.xml
new file mode 100644
index 0000000..abbfa53
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.aapt.symlinktest" />
diff --git a/tools/aapt2/integration-tests/SymlinkTest/res/drawable/white_3x3.9.png b/tools/aapt2/integration-tests/SymlinkTest/res/drawable/white_3x3.9.png
new file mode 120000
index 0000000..a7e8e2f
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/res/drawable/white_3x3.9.png
@@ -0,0 +1 @@
+../../targets/white_3x3.9.png
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/SymlinkTest/res/layout/layout.xml b/tools/aapt2/integration-tests/SymlinkTest/res/layout/layout.xml
new file mode 120000
index 0000000..29c30e1
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/res/layout/layout.xml
@@ -0,0 +1 @@
+../../targets/layout.xml
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/SymlinkTest/res/values/values.xml b/tools/aapt2/integration-tests/SymlinkTest/res/values/values.xml
new file mode 120000
index 0000000..554bb71
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/res/values/values.xml
@@ -0,0 +1 @@
+../../targets/values.xml
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/SymlinkTest/targets/layout.xml b/tools/aapt2/integration-tests/SymlinkTest/targets/layout.xml
new file mode 100644
index 0000000..e5835ed
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/targets/layout.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/tools/aapt2/integration-tests/SymlinkTest/targets/values.xml b/tools/aapt2/integration-tests/SymlinkTest/targets/values.xml
new file mode 100644
index 0000000..5b02843
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/targets/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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>
+    <bool name="foo">true</bool>
+</resources>
diff --git a/tools/aapt2/integration-tests/SymlinkTest/targets/white_3x3.9.png b/tools/aapt2/integration-tests/SymlinkTest/targets/white_3x3.9.png
new file mode 100644
index 0000000..1a3731b
--- /dev/null
+++ b/tools/aapt2/integration-tests/SymlinkTest/targets/white_3x3.9.png
Binary files differ
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 9311091..10e837c 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -179,32 +179,39 @@
   return true;
 }
 
-/**
- * Modified CollisionResolver which will merge Styleables. Used with overlays.
- *
- * Styleables are not actual resources, but they are treated as such during the
- * compilation phase. Styleables don't simply overlay each other, their
- * definitions merge
- * and accumulate. If both values are Styleables, we just merge them into the
- * existing value.
- */
-static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing,
-                                                            Value* incoming) {
+// Modified CollisionResolver which will merge Styleables and Styles. Used with overlays.
+//
+// Styleables are not actual resources, but they are treated as such during the
+// compilation phase.
+//
+// Styleables and Styles don't simply overlay each other, their definitions merge
+// and accumulate. If both values are Styleables/Styles, we just merge them into the
+// existing value.
+static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, Value* incoming,
+                                                            StringPool* pool) {
   if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) {
     if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) {
       // Styleables get merged.
       existing_styleable->MergeWith(incoming_styleable);
       return ResourceTable::CollisionResult::kKeepOriginal;
     }
+  } else if (Style* existing_style = ValueCast<Style>(existing)) {
+    if (Style* incoming_style = ValueCast<Style>(incoming)) {
+      // Styles get merged.
+      existing_style->MergeWith(incoming_style, pool);
+      return ResourceTable::CollisionResult::kKeepOriginal;
+    }
   }
   // Delegate to the default handler.
   return ResourceTable::ResolveValueCollision(existing, incoming);
 }
 
-static ResourceTable::CollisionResult MergeConfigValue(
-    IAaptContext* context, const ResourceNameRef& res_name, const bool overlay,
-    ResourceConfigValue* dst_config_value,
-    ResourceConfigValue* src_config_value) {
+static ResourceTable::CollisionResult MergeConfigValue(IAaptContext* context,
+                                                       const ResourceNameRef& res_name,
+                                                       const bool overlay,
+                                                       ResourceConfigValue* dst_config_value,
+                                                       ResourceConfigValue* src_config_value,
+                                                       StringPool* pool) {
   using CollisionResult = ResourceTable::CollisionResult;
 
   Value* dst_value = dst_config_value->value.get();
@@ -212,10 +219,9 @@
 
   CollisionResult collision_result;
   if (overlay) {
-    collision_result = ResolveMergeCollision(dst_value, src_value);
+    collision_result = ResolveMergeCollision(dst_value, src_value, pool);
   } else {
-    collision_result =
-        ResourceTable::ResolveValueCollision(dst_value, src_value);
+    collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
   }
 
   if (collision_result == CollisionResult::kConflict) {
@@ -224,10 +230,9 @@
     }
 
     // Error!
-    context->GetDiagnostics()->Error(
-        DiagMessage(src_value->GetSource())
-        << "resource '" << res_name << "' has a conflicting value for "
-        << "configuration (" << src_config_value->config << ")");
+    context->GetDiagnostics()->Error(DiagMessage(src_value->GetSource())
+                                     << "resource '" << res_name << "' has a conflicting value for "
+                                     << "configuration (" << src_config_value->config << ")");
     context->GetDiagnostics()->Note(DiagMessage(dst_value->GetSource())
                                     << "originally defined here");
     return CollisionResult::kConflict;
@@ -243,8 +248,7 @@
   bool error = false;
 
   for (auto& src_type : src_package->types) {
-    ResourceTableType* dst_type =
-        master_package_->FindOrCreateType(src_type->type);
+    ResourceTableType* dst_type = master_package_->FindOrCreateType(src_type->type);
     if (!MergeType(context_, src, dst_type, src_type.get())) {
       error = true;
       continue;
@@ -253,27 +257,24 @@
     for (auto& src_entry : src_type->entries) {
       std::string entry_name = src_entry->name;
       if (mangle_package) {
-        entry_name =
-            NameMangler::MangleEntry(src_package->name, src_entry->name);
+        entry_name = NameMangler::MangleEntry(src_package->name, src_entry->name);
       }
 
       ResourceEntry* dst_entry;
-      if (allow_new_resources) {
+      if (allow_new_resources || src_entry->symbol_status.allow_new) {
         dst_entry = dst_type->FindOrCreateEntry(entry_name);
       } else {
         dst_entry = dst_type->FindEntry(entry_name);
       }
 
-      const ResourceNameRef res_name(src_package->name, src_type->type,
-                                     src_entry->name);
+      const ResourceNameRef res_name(src_package->name, src_type->type, src_entry->name);
 
       if (!dst_entry) {
-        context_->GetDiagnostics()->Error(
-            DiagMessage(src) << "resource " << res_name
-                             << " does not override an existing resource");
-        context_->GetDiagnostics()->Note(
-            DiagMessage(src) << "define an <add-resource> tag or use "
-                             << "--auto-add-overlay");
+        context_->GetDiagnostics()->Error(DiagMessage(src)
+                                          << "resource " << res_name
+                                          << " does not override an existing resource");
+        context_->GetDiagnostics()->Note(DiagMessage(src) << "define an <add-resource> tag or use "
+                                                          << "--auto-add-overlay");
         error = true;
         continue;
       }
@@ -291,7 +292,7 @@
         if (dst_config_value) {
           CollisionResult collision_result =
               MergeConfigValue(context_, res_name, overlay, dst_config_value,
-                               src_config_value.get());
+                               src_config_value.get(), &master_table_->string_pool);
           if (collision_result == CollisionResult::kConflict) {
             error = true;
             continue;
@@ -299,25 +300,22 @@
             continue;
           }
         } else {
-          dst_config_value = dst_entry->FindOrCreateValue(
-              src_config_value->config, src_config_value->product);
+          dst_config_value =
+              dst_entry->FindOrCreateValue(src_config_value->config, src_config_value->product);
         }
 
         // Continue if we're taking the new resource.
 
-        if (FileReference* f =
-                ValueCast<FileReference>(src_config_value->value.get())) {
+        if (FileReference* f = ValueCast<FileReference>(src_config_value->value.get())) {
           std::unique_ptr<FileReference> new_file_ref;
           if (mangle_package) {
             new_file_ref = CloneAndMangleFile(src_package->name, *f);
           } else {
-            new_file_ref = std::unique_ptr<FileReference>(
-                f->Clone(&master_table_->string_pool));
+            new_file_ref = std::unique_ptr<FileReference>(f->Clone(&master_table_->string_pool));
           }
 
           if (callback) {
-            if (!callback(res_name, src_config_value->config,
-                          new_file_ref.get(), f)) {
+            if (!callback(res_name, src_config_value->config, new_file_ref.get(), f)) {
               error = true;
               continue;
             }
@@ -341,18 +339,15 @@
     std::string mangled_entry = NameMangler::MangleEntry(package, entry.to_string());
     std::string newPath = prefix.to_string() + mangled_entry + suffix.to_string();
     std::unique_ptr<FileReference> new_file_ref =
-        util::make_unique<FileReference>(
-            master_table_->string_pool.MakeRef(newPath));
+        util::make_unique<FileReference>(master_table_->string_pool.MakeRef(newPath));
     new_file_ref->SetComment(file_ref.GetComment());
     new_file_ref->SetSource(file_ref.GetSource());
     return new_file_ref;
   }
-  return std::unique_ptr<FileReference>(
-      file_ref.Clone(&master_table_->string_pool));
+  return std::unique_ptr<FileReference>(file_ref.Clone(&master_table_->string_pool));
 }
 
-bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file,
-                                bool overlay) {
+bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, bool overlay) {
   ResourceTable table;
   std::string path = ResourceUtils::BuildResourceFileName(file_desc);
   std::unique_ptr<FileReference> file_ref =
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 742f5a7..45b01a4 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -20,6 +20,14 @@
 #include "io/FileSystem.h"
 #include "test/Test.h"
 
+using ::aapt::test::ValueEq;
+using ::testing::Contains;
+using ::testing::NotNull;
+using ::testing::UnorderedElementsAreArray;
+using ::testing::Pointee;
+using ::testing::Field;
+using ::testing::Eq;
+
 namespace aapt {
 
 struct TableMergerTest : public ::testing::Test {
@@ -62,26 +70,20 @@
   io::FileCollection collection;
 
   ASSERT_TRUE(merger.Merge({}, table_a.get()));
-  ASSERT_TRUE(
-      merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
+  ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
 
   EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0);
 
   // Entries from com.app.a should not be mangled.
-  AAPT_EXPECT_TRUE(
-      final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
-  AAPT_EXPECT_TRUE(
-      final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
-  AAPT_EXPECT_TRUE(final_table.FindResource(
-      test::ParseNameOrDie("com.app.a:styleable/view")));
+  EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
+  EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
+  EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:styleable/view")));
 
   // The unmangled name should not be present.
-  AAPT_EXPECT_FALSE(
-      final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
+  EXPECT_FALSE(final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
 
   // Look for the mangled name.
-  AAPT_EXPECT_TRUE(final_table.FindResource(
-      test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
+  EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
 }
 
 TEST_F(TableMergerTest, MergeFile) {
@@ -100,7 +102,7 @@
 
   FileReference* file = test::GetValueForConfig<FileReference>(
       &final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4"));
-  ASSERT_NE(nullptr, file);
+  ASSERT_THAT(file, NotNull());
   EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path);
 }
 
@@ -137,17 +139,14 @@
   collection.InsertFile("res/xml/file.xml");
 
   ASSERT_TRUE(merger.Merge({}, table_a.get()));
-  ASSERT_TRUE(
-      merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
+  ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
 
-  FileReference* f =
-      test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
-  ASSERT_NE(f, nullptr);
+  FileReference* f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
+  ASSERT_THAT(f, NotNull());
   EXPECT_EQ(std::string("res/xml/file.xml"), *f->path);
 
-  f = test::GetValue<FileReference>(&final_table,
-                                    "com.app.a:xml/com.app.b$file");
-  ASSERT_NE(f, nullptr);
+  f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/com.app.b$file");
+  ASSERT_THAT(f, NotNull());
   EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), *f->path);
 }
 
@@ -171,10 +170,9 @@
   ASSERT_TRUE(merger.Merge({}, base.get()));
   ASSERT_TRUE(merger.MergeOverlay({}, overlay.get()));
 
-  BinaryPrimitive* foo =
-      test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
-  ASSERT_NE(nullptr, foo);
-  EXPECT_EQ(0x0u, foo->value.data);
+  BinaryPrimitive* foo = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
+  ASSERT_THAT(foo,
+              Pointee(Field(&BinaryPrimitive::value, Field(&android::Res_value::data, Eq(0u)))));
 }
 
 TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
@@ -248,18 +246,18 @@
 
 TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
   std::unique_ptr<ResourceTable> table_a =
-      test::ResourceTableBuilder()
-          .SetPackageId("", 0x7f)
-          .SetSymbolState("bool/foo", {}, SymbolState::kUndefined)
-          .Build();
+      test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
           .SetPackageId("", 0x7f)
+          .SetSymbolState("bool/foo", {}, SymbolState::kUndefined, true /*allow new overlay*/)
           .AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
           .Build();
 
   ResourceTable final_table;
-  TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
+  TableMergerOptions options;
+  options.auto_add_overlay = false;
+  TableMerger merger(context_.get(), &final_table, options);
 
   ASSERT_TRUE(merger.Merge({}, table_a.get()));
   ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
@@ -301,7 +299,7 @@
   ASSERT_FALSE(merger.MergeOverlay({}, table_b.get()));
 }
 
-TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) {
+TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) {
   std::unique_ptr<ResourceTable> table_a =
       test::ResourceTableBuilder()
           .SetPackageId("com.app.a", 0x7f)
@@ -310,15 +308,27 @@
                         .AddItem("com.app.a:attr/bar")
                         .AddItem("com.app.a:attr/foo", ResourceId(0x01010000))
                         .Build())
+          .AddValue("com.app.a:style/Theme",
+                    test::StyleBuilder()
+                        .SetParent("com.app.a:style/Parent")
+                        .AddItem("com.app.a:attr/bar", util::make_unique<Id>())
+                        .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false))
+                        .Build())
           .Build();
 
   std::unique_ptr<ResourceTable> table_b =
       test::ResourceTableBuilder()
           .SetPackageId("com.app.a", 0x7f)
-          .AddValue("com.app.a:styleable/Foo",
-                    test::StyleableBuilder()
-                        .AddItem("com.app.a:attr/bat")
-                        .AddItem("com.app.a:attr/foo")
+          .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder()
+                                                   .AddItem("com.app.a:attr/bat")
+                                                   .AddItem("com.app.a:attr/foo")
+                                                   .Build())
+          .AddValue("com.app.a:style/Theme",
+                    test::StyleBuilder()
+                        .SetParent("com.app.a:style/OverlayParent")
+                        .AddItem("com.app.a:attr/bat", util::make_unique<Id>())
+                        .AddItem("com.app.a:attr/foo", ResourceId(0x01010000),
+                                 ResourceUtils::MakeBool(true))
                         .Build())
           .Build();
 
@@ -330,18 +340,29 @@
   ASSERT_TRUE(merger.Merge({}, table_a.get()));
   ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
 
-  Styleable* styleable =
-      test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
-  ASSERT_NE(nullptr, styleable);
+  Styleable* styleable = test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
+  ASSERT_THAT(styleable, NotNull());
 
   std::vector<Reference> expected_refs = {
       Reference(test::ParseNameOrDie("com.app.a:attr/bar")),
       Reference(test::ParseNameOrDie("com.app.a:attr/bat")),
-      Reference(test::ParseNameOrDie("com.app.a:attr/foo"),
-                ResourceId(0x01010000)),
+      Reference(test::ParseNameOrDie("com.app.a:attr/foo"), ResourceId(0x01010000)),
   };
+  EXPECT_THAT(styleable->entries, UnorderedElementsAreArray(expected_refs));
 
-  EXPECT_EQ(expected_refs, styleable->entries);
+  Style* style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme");
+  ASSERT_THAT(style, NotNull());
+
+  std::vector<Reference> extracted_refs;
+  for (const auto& entry : style->entries) {
+    extracted_refs.push_back(entry.key);
+  }
+  EXPECT_THAT(extracted_refs, UnorderedElementsAreArray(expected_refs));
+
+  const auto expected = ResourceUtils::MakeBool(true);
+  EXPECT_THAT(style->entries, Contains(Field(&Style::Entry::value, Pointee(ValueEq(*expected)))));
+  EXPECT_THAT(style->parent,
+              Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent")))));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index d93d495..1d0041b 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -32,8 +32,7 @@
  public:
   using ValueVisitor::Visit;
 
-  explicit ReferenceIdToNameVisitor(
-      const std::map<ResourceId, ResourceNameRef>* mapping)
+  explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping)
       : mapping_(mapping) {
     CHECK(mapping_ != nullptr);
   }
@@ -75,13 +74,11 @@
 
     std::map<ResourceId, ResourceNameRef> idIndex;
 
-    ResourceTablePackage* pkg =
-        table->CreatePackage(pbPackage.package_name(), id);
+    ResourceTablePackage* pkg = table->CreatePackage(pbPackage.package_name(), id);
     for (const pb::Type& pbType : pbPackage.types()) {
       const ResourceType* resType = ParseResourceType(pbType.name());
       if (!resType) {
-        diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name()
-                                          << "'");
+        diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() << "'");
         return {};
       }
 
@@ -95,21 +92,20 @@
         if (pbEntry.has_symbol_status()) {
           const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
           if (pbStatus.has_source()) {
-            DeserializeSourceFromPb(pbStatus.source(), *source_pool_,
-                                    &entry->symbol_status.source);
+            DeserializeSourceFromPb(pbStatus.source(), *source_pool_, &entry->symbol_status.source);
           }
 
           if (pbStatus.has_comment()) {
             entry->symbol_status.comment = pbStatus.comment();
           }
 
-          SymbolState visibility =
-              DeserializeVisibilityFromPb(pbStatus.visibility());
+          entry->symbol_status.allow_new = pbStatus.allow_new();
+
+          SymbolState visibility = DeserializeVisibilityFromPb(pbStatus.visibility());
           entry->symbol_status.state = visibility;
 
           if (visibility == SymbolState::kPublic) {
-            // This is a public symbol, we must encode the ID now if there is
-            // one.
+            // This is a public symbol, we must encode the ID now if there is one.
             if (pbEntry.has_id()) {
               entry->id = static_cast<uint16_t>(pbEntry.id());
             }
@@ -142,16 +138,15 @@
             return {};
           }
 
-          ResourceConfigValue* configValue =
-              entry->FindOrCreateValue(config, pbConfig.product());
+          ResourceConfigValue* configValue = entry->FindOrCreateValue(config, pbConfig.product());
           if (configValue->value) {
             // Duplicate config.
             diag_->Error(DiagMessage(source_) << "duplicate configuration");
             return {};
           }
 
-          configValue->value = DeserializeValueFromPb(
-              pbConfigValue.value(), config, &table->string_pool);
+          configValue->value =
+              DeserializeValueFromPb(pbConfigValue.value(), config, &table->string_pool);
           if (!configValue->value) {
             return {};
           }
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index 7230b55..de10bb8 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -250,19 +250,16 @@
 
         // Write the SymbolStatus struct.
         pb::SymbolStatus* pb_status = pb_entry->mutable_symbol_status();
-        pb_status->set_visibility(
-            SerializeVisibilityToPb(entry->symbol_status.state));
-        SerializeSourceToPb(entry->symbol_status.source, &source_pool,
-                            pb_status->mutable_source());
+        pb_status->set_visibility(SerializeVisibilityToPb(entry->symbol_status.state));
+        SerializeSourceToPb(entry->symbol_status.source, &source_pool, pb_status->mutable_source());
         pb_status->set_comment(entry->symbol_status.comment);
+        pb_status->set_allow_new(entry->symbol_status.allow_new);
 
         for (auto& config_value : entry->values) {
           pb::ConfigValue* pb_config_value = pb_entry->add_config_values();
-          SerializeConfig(config_value->config,
-                          pb_config_value->mutable_config());
+          SerializeConfig(config_value->config, pb_config_value->mutable_config());
           if (!config_value->product.empty()) {
-            pb_config_value->mutable_config()->set_product(
-                config_value->product);
+            pb_config_value->mutable_config()->set_product(config_value->product);
           }
 
           pb::Value* pb_value = pb_config_value->mutable_value();
diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp
index fdd5197..e6ce6d3 100644
--- a/tools/aapt2/proto/TableProtoSerializer_test.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp
@@ -28,12 +28,11 @@
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
           .SetPackageId("com.app.a", 0x7f)
-          .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000),
-                            "res/layout/main.xml")
-          .AddReference("com.app.a:layout/other", ResourceId(0x7f020001),
-                        "com.app.a:layout/main")
+          .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000), "res/layout/main.xml")
+          .AddReference("com.app.a:layout/other", ResourceId(0x7f020001), "com.app.a:layout/main")
           .AddString("com.app.a:string/text", {}, "hi")
           .AddValue("com.app.a:id/foo", {}, util::make_unique<Id>())
+          .SetSymbolState("com.app.a:bool/foo", {}, SymbolState::kUndefined, true /*allow_new*/)
           .Build();
 
   Symbol public_symbol;
@@ -94,21 +93,23 @@
   EXPECT_EQ(SymbolState::kPublic, result.value().type->symbol_status.state);
   EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state);
 
+  result = new_table->FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
+  ASSERT_TRUE(result);
+  EXPECT_EQ(SymbolState::kUndefined, result.value().entry->symbol_status.state);
+  EXPECT_TRUE(result.value().entry->symbol_status.allow_new);
+
   // Find the product-dependent values
   BinaryPrimitive* prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
-      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
-      "");
+      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), "");
   ASSERT_NE(nullptr, prim);
   EXPECT_EQ(123u, prim->value.data);
 
   prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
-      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
-      "tablet");
+      new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), "tablet");
   ASSERT_NE(nullptr, prim);
   EXPECT_EQ(321u, prim->value.data);
 
-  Reference* actual_ref =
-      test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc");
+  Reference* actual_ref = test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc");
   ASSERT_NE(nullptr, actual_ref);
   AAPT_ASSERT_TRUE(actual_ref->name);
   AAPT_ASSERT_TRUE(actual_ref->id);
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index 7e28ae7b..0290e30 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -1,5 +1,10 @@
 # Android Asset Packaging Tool 2.0 (AAPT2) release notes
 
+## Version 2.17
+### `aapt2 compile ...`
+- Fixed an issue where symlinks would not be followed when compiling PNGs. (bug 62144459)
+- Fixed issue where overlays that declared `<add-resource>` did not compile. (bug 38355988)
+
 ## Version 2.16
 ### `aapt2 link ...`
 - Versioning of XML files is more intelligent, using a small set of rules to degrade
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index 6888cf3..02acedb 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -117,12 +117,12 @@
   }
 
   ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
-                                       SymbolState state) {
+                                       SymbolState state, bool allow_new = false) {
     ResourceName res_name = ParseNameOrDie(name);
     Symbol symbol;
     symbol.state = state;
-    CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol,
-                                             &diagnostics_));
+    symbol.allow_new = allow_new;
+    CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol, &diagnostics_));
     return *this;
   }
 
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 248921f..a937de8 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -22,12 +22,14 @@
 #include "android-base/logging.h"
 #include "android-base/macros.h"
 #include "androidfw/StringPiece.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 #include "ConfigDescription.h"
 #include "Debug.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
+#include "ResourceValues.h"
 #include "ValueVisitor.h"
 #include "io/File.h"
 #include "process/IResourceTableConsumer.h"
@@ -51,13 +53,11 @@
         return;
 
       case Level::Warn:
-        std::cerr << actual_msg.source << ": warn: " << actual_msg.message
-                  << "." << std::endl;
+        std::cerr << actual_msg.source << ": warn: " << actual_msg.message << "." << std::endl;
         break;
 
       case Level::Error:
-        std::cerr << actual_msg.source << ": error: " << actual_msg.message
-                  << "." << std::endl;
+        std::cerr << actual_msg.source << ": error: " << actual_msg.message << "." << std::endl;
         break;
     }
   }
@@ -84,11 +84,9 @@
 T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name,
                                const ConfigDescription& config,
                                const android::StringPiece& product) {
-  Maybe<ResourceTable::SearchResult> result =
-      table->FindResource(ParseNameOrDie(res_name));
+  Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name));
   if (result) {
-    ResourceConfigValue* config_value =
-        result.value().entry->FindValue(config, product);
+    ResourceConfigValue* config_value = result.value().entry->FindValue(config, product);
     if (config_value) {
       return ValueCast<T>(config_value->value.get());
     }
@@ -111,9 +109,13 @@
  public:
   explicit TestFile(const android::StringPiece& path) : source_(path) {}
 
-  std::unique_ptr<io::IData> OpenAsData() override { return {}; }
+  std::unique_ptr<io::IData> OpenAsData() override {
+    return {};
+  }
 
-  const Source& GetSource() const override { return source_; }
+  const Source& GetSource() const override {
+    return source_;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestFile);
@@ -122,6 +124,47 @@
 };
 
 }  // namespace test
+
+// Workaround gtest bug (https://github.com/google/googletest/issues/443)
+// that does not select base class operator<< for derived class T.
+template <typename T>
+typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
+    std::ostream& out, const T& value) {
+  value.Print(&out);
+  return out;
+}
+
+template std::ostream& operator<<<Item>(std::ostream&, const Item&);
+template std::ostream& operator<<<Reference>(std::ostream&, const Reference&);
+template std::ostream& operator<<<Id>(std::ostream&, const Id&);
+template std::ostream& operator<<<RawString>(std::ostream&, const RawString&);
+template std::ostream& operator<<<String>(std::ostream&, const String&);
+template std::ostream& operator<<<StyledString>(std::ostream&, const StyledString&);
+template std::ostream& operator<<<FileReference>(std::ostream&, const FileReference&);
+template std::ostream& operator<<<BinaryPrimitive>(std::ostream&, const BinaryPrimitive&);
+template std::ostream& operator<<<Attribute>(std::ostream&, const Attribute&);
+template std::ostream& operator<<<Style>(std::ostream&, const Style&);
+template std::ostream& operator<<<Array>(std::ostream&, const Array&);
+template std::ostream& operator<<<Plural>(std::ostream&, const Plural&);
+
+// Add a print method to Maybe.
+template <typename T>
+void PrintTo(const Maybe<T>& value, std::ostream* out) {
+  if (value) {
+    *out << ::testing::PrintToString(value.value());
+  } else {
+    *out << "Nothing";
+  }
+}
+
+namespace test {
+
+MATCHER_P(ValueEq, a,
+          std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
+  return arg.Equals(&a);
+}
+
+}  // namespace test
 }  // namespace aapt
 
 #endif /* AAPT_TEST_COMMON_H */
diff --git a/tools/aapt2/test/Test.h b/tools/aapt2/test/Test.h
index ec07432..a24c01c 100644
--- a/tools/aapt2/test/Test.h
+++ b/tools/aapt2/test/Test.h
@@ -17,6 +17,7 @@
 #ifndef AAPT_TEST_TEST_H
 #define AAPT_TEST_TEST_H
 
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 #include "test/Builders.h"
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index d10351b..1bf2594 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -181,12 +181,13 @@
   return std::move(filemap);
 }
 
-bool AppendArgsFromFile(const StringPiece& path,
-                        std::vector<std::string>* out_arglist,
+bool AppendArgsFromFile(const StringPiece& path, std::vector<std::string>* out_arglist,
                         std::string* out_error) {
   std::string contents;
-  if (!android::base::ReadFileToString(path.to_string(), &contents)) {
-    if (out_error) *out_error = "failed to read argument-list file";
+  if (!android::base::ReadFileToString(path.to_string(), &contents, true /*follow_symlinks*/)) {
+    if (out_error) {
+      *out_error = "failed to read argument-list file";
+    }
     return false;
   }
 
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 15fd2ce..deb0e09 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -210,13 +211,13 @@
     }
 
     @Override
-    public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
+    public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
             IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
         // TODO Auto-generated method stub
     }
 
     @Override
-    public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
+    public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
             boolean scaleUp) {
         // TODO Auto-generated method stub
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index cfc1fd2..164b7b0 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -160,6 +160,8 @@
      *
      * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
      * components will be launched.
+     *
+     * @hide
      */
     public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
     /**
@@ -167,6 +169,8 @@
      * String representation.
      *
      * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
+     *
+     * @hide
      */
     public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
     /**
@@ -174,12 +178,16 @@
      *
      * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
      * {@link android.graphics.drawable.Icon}.
+     *
+     * @hide
      */
     public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
     /**
      * Name of a file.
      *
      * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+     *
+     * @hide
      */
     public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
 
@@ -195,6 +203,7 @@
      * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
      * components will be launched.
      *
+     * @hide
      */
     public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
             "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
@@ -202,6 +211,8 @@
      * Raw binary data of an ANQP (Access Network Query Protocol) element.
      *
      * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
+     *
+     * @hide
      */
     public static final String EXTRA_ANQP_ELEMENT_DATA =
             "android.net.wifi.extra.ANQP_ELEMENT_DATA";
@@ -220,6 +231,7 @@
      * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
      * components will be launched.
      *
+     * @hide
      */
     public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
             "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
@@ -228,18 +240,24 @@
      * {@code true} for ESS.
      *
      * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
+     *
+     * @hide
      */
     public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
     /**
      * Delay in seconds.
      *
      * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
+     *
+     * @hide
      */
     public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
     /**
      * String representation of an URL.
      *
      * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+     *
+     * @hide
      */
     public static final String EXTRA_URL = "android.net.wifi.extra.URL";
 
@@ -254,8 +272,10 @@
      *
      * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
      *
-     ** <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+     * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
      * components will be launched.
+     *
+     * @hide
      */
     public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
             "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
@@ -265,6 +285,8 @@
      * 1 - SOAP XML SPP
      *
      * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
+     *
+     * @hide
      */
     public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
             "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
@@ -1122,6 +1144,8 @@
      *
      * @param bssid The BSSID of the AP
      * @param fileName Name of the icon file (remote file) to query from the AP
+     *
+     * @hide
      */
     public void queryPasspointIcon(long bssid, String fileName) {
         try {
@@ -1778,25 +1802,25 @@
     }
 
     /**
-     * Start AccessPoint mode with the specified
-     * configuration. If the radio is already running in
-     * AP mode, update the new configuration
-     * Note that starting in access point mode disables station
-     * mode operation
+     * This call will be deprecated and removed in an upcoming release.  It is no longer used to
+     * start WiFi Tethering.  Please use {@link ConnectivityManager#startTethering(int, boolean,
+     * ConnectivityManager#OnStartTetheringCallback)} if
+     * the caller has proper permissions.  Callers can also use the LocalOnlyHotspot feature for a
+     * hotspot capable of communicating with co-located devices {@link
+     * WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback)}.
+     *
      * @param wifiConfig SSID, security and channel details as
      *        part of WifiConfiguration
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
+     * @return {@code false}
      *
      * @hide
      */
     @SystemApi
     public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
-        try {
-            mService.setWifiApEnabled(wifiConfig, enabled);
-            return true;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        String packageName = mContext.getOpPackageName();
+
+        Log.w(TAG, packageName + " attempted call to setWifiApEnabled: enabled = " + enabled);
+        return false;
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 84ac118..b235ccc7 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -778,4 +778,13 @@
         verify(mWifiService).stopWatchLocalOnlyHotspot();
     }
 
+    /**
+     * Verify that calls to setWifiApEnabled return false.
+     */
+    @Test
+    public void testSetWifiApEnabledReturnsFalse() throws Exception {
+        assertFalse(mWifiManager.setWifiApEnabled(null, true));
+        assertFalse(mWifiManager.setWifiApEnabled(null, false));
+        verify(mWifiService, never()).setWifiApEnabled(any(), anyBoolean());
+    }
 }