Merge "Move QS cell indicator back into mobile data tile" into oc-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 9b5b1a2..de738f9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -32596,7 +32596,9 @@
 
   public final class PrintManager {
     method public java.util.List<android.print.PrintJob> getPrintJobs();
+    method public java.util.List<android.printservice.PrintServiceInfo> getPrintServices(int);
     method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes);
+    field public static final int ALL_SERVICES = 3; // 0x3
   }
 
   public final class PrinterCapabilitiesInfo implements android.os.Parcelable {
@@ -32726,6 +32728,13 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
   }
 
+  public final class PrintServiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.content.ComponentName getComponentName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.printservice.PrintServiceInfo> CREATOR;
+  }
+
   public abstract class PrinterDiscoverySession {
     ctor public PrinterDiscoverySession();
     method public final void addPrinters(java.util.List<android.print.PrinterInfo>);
@@ -34989,6 +34998,7 @@
     field public static final java.lang.String DEFAULT_INPUT_METHOD = "default_input_method";
     field public static final deprecated java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
     field public static final deprecated java.lang.String DEVICE_PROVISIONED = "device_provisioned";
+    field public static final java.lang.String DISABLED_PRINT_SERVICES = "disabled_print_services";
     field public static final java.lang.String ENABLED_ACCESSIBILITY_SERVICES = "enabled_accessibility_services";
     field public static final java.lang.String ENABLED_INPUT_METHODS = "enabled_input_methods";
     field public static final java.lang.String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages";
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index ad6b454..4dd71b4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1171,7 +1171,7 @@
      */
     public static final int GROUP_ALERT_CHILDREN = 2;
 
-    private int mGroupAlertBehavior = GROUP_ALERT_CHILDREN;
+    private int mGroupAlertBehavior = GROUP_ALERT_ALL;
 
     /**
      * If this notification is being shown as a badge, always show as a number.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index c99a1e4..266fa7e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -18,7 +18,6 @@
 import android.os.PooledStringWriter;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.service.autofill.FillContext;
 import android.service.autofill.FillRequest;
 import android.text.TextUtils;
 import android.util.Log;
@@ -31,7 +30,6 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 
 import java.util.ArrayList;
@@ -39,18 +37,18 @@
 import java.util.List;
 
 /**
- * Assist data automatically created by the platform's implementation of Assist and Autofill.
+ * Assist data automatically created by the platform's implementation of assist and autofill.
  *
- * <p>The structure is used for Assist purposes when created by
+ * <p>The structure is used for assist purposes when created by
  * {@link android.app.Activity#onProvideAssistData}, {@link View#onProvideStructure(ViewStructure)},
  * or {@link View#onProvideVirtualStructure(ViewStructure)}.
  *
- * <p>The structure is used for Autofill purposes when created by
+ * <p>The structure is used for autofill purposes when created by
  * {@link View#onProvideAutofillStructure(ViewStructure, int)},
  * or {@link View#onProvideAutofillVirtualStructure(ViewStructure, int)}.
  *
- * <p>For performance reasons, some properties of the Assist data might be available just for Assist
- * or Autofill purposes; in those case, the property availability will be document in its javadoc.
+ * <p>For performance reasons, some properties of the assist data might be available just for assist
+ * or autofill purposes; in those case, the property availability will be document in its javadoc.
  */
 public class AssistStructure implements Parcelable {
     static final String TAG = "AssistStructure";
@@ -958,10 +956,10 @@
         /**
          * Gets the id that can be used to autofill the view contents.
          *
-         * <p>It's relevant set when the {@link AssistStructure} is used for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes.
          *
          * @return id that can be used to autofill the view contents, or {@code null} if the
-         * structure was created for Assist purposes.
+         * structure was created for assist purposes.
          */
         @Nullable public AutofillId getAutofillId() {
             return mAutofillId;
@@ -970,10 +968,10 @@
         /**
          * Gets the the type of value that can be used to autofill the view contents.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes.
          *
          * @return autofill type as defined by {@link View#getAutofillType()},
-         * or {@link View#AUTOFILL_TYPE_NONE} if the structure was created for Assist purposes.
+         * or {@link View#AUTOFILL_TYPE_NONE} if the structure was created for assist purposes.
          */
         public @View.AutofillType int getAutofillType() {
             return mAutofillType;
@@ -983,11 +981,11 @@
          * Describes the content of a view so that a autofill service can fill in the appropriate
          * data.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
          * not for Assist - see {@link View#getAutofillHints()} for more info.
          *
          * @return The autofill hints for this view, or {@code null} if the structure was created
-         * for Assist purposes.
+         * for assist purposes.
          */
         @Nullable public String[] getAutofillHints() {
             return mAutofillHints;
@@ -996,11 +994,11 @@
         /**
          * Gets the the value of this view.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
-         * not for Assist purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+         * not for assist purposes.
          *
          * @return the autofill value of this view, or {@code null} if the structure was created
-         * for Assist purposes.
+         * for assist purposes.
          */
         @Nullable public AutofillValue getAutofillValue() {
             return mAutofillValue;
@@ -1017,11 +1015,11 @@
          * <p>Typically used by nodes whose {@link View#getAutofillType()} is a list to indicate
          * the meaning of each possible value in the list.
          *
-         * <p>It's relevant when the {@link AssistStructure} is used for Autofill purposes, not
-         * for Assist purposes.
+         * <p>It's relevant when the {@link AssistStructure} is used for autofill purposes, not
+         * for assist purposes.
          *
          * @return the options that can be used to autofill this view, or {@code null} if the
-         * structure was created for Assist purposes.
+         * structure was created for assist purposes.
          */
         @Nullable public CharSequence[] getAutofillOptions() {
             return mAutofillOptions;
@@ -1106,8 +1104,8 @@
          * or scaling.  The returned Matrix object is owned by ViewNode; do not modify it.
          * Returns null if there is no transformation applied to the view.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public Matrix getTransformation() {
             return mMatrix;
@@ -1118,8 +1116,8 @@
          * characterstics, as set by {@link ViewStructure#setElevation
          * ViewStructure.setElevation(float)}.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public float getElevation() {
             return mElevation;
@@ -1130,8 +1128,8 @@
          * of the view's contents, as set by {@link ViewStructure#setAlpha
          * ViewStructure.setAlpha(float)}.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public float getAlpha() {
             return mAlpha;
@@ -1260,7 +1258,7 @@
          * document.
          *
          * <strong>WARNING:</strong> a {@link android.service.autofill.AutofillService} should only
-         * use this domain for Autofill purposes when it trusts the app generating it (i.e., the app
+         * use this domain for autofill purposes when it trusts the app generating it (i.e., the app
          * defined by {@link AssistStructure#getActivityComponent()}).
          *
          * @return domain-only part of the document. For example, if the full URL is
@@ -1273,11 +1271,11 @@
         /**
          * Returns the HTML properties associated with this view.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
-         * not for Assist purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
+         * not for assist purposes.
          *
          * @return the HTML properties associated with this view, or {@code null} if the
-         * structure was created for Assist purposes.
+         * structure was created for assist purposes.
          */
         @Nullable public HtmlInfo getHtmlInfo() {
             return mHtmlInfo;
@@ -1301,8 +1299,8 @@
         /**
          * If {@link #getText()} is non-null, this is where the current selection starts.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int getTextSelectionStart() {
             return mText != null ? mText.mTextSelectionStart : -1;
@@ -1313,8 +1311,8 @@
          * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
          * indicating the cursor position.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int getTextSelectionEnd() {
             return mText != null ? mText.mTextSelectionEnd : -1;
@@ -1337,8 +1335,8 @@
          * Note that the text may also contain style spans that modify the color of specific
          * parts of the text.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int getTextBackgroundColor() {
             return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
@@ -1350,8 +1348,8 @@
          * Note that the text may also contain style spans that modify the size of specific
          * parts of the text.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public float getTextSize() {
             return mText != null ? mText.mTextSize : 0;
@@ -1365,8 +1363,8 @@
          * Note that the text may also contain style spans that modify the style of specific
          * parts of the text.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int getTextStyle() {
             return mText != null ? mText.mTextStyle : 0;
@@ -1378,8 +1376,8 @@
          * into the text string where that line starts.  May return null if there is no line
          * information.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int[] getTextLineCharOffsets() {
             return mText != null ? mText.mLineCharOffsets : null;
@@ -1391,8 +1389,8 @@
          * where that text appears in the view.  May return null if there is no line
          * information.
          *
-         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
-         * not for Autofill purposes.
+         * <p>It's only relevant when the {@link AssistStructure} is used for assist purposes,
+         * not for autofill purposes.
          */
         public int[] getTextLineBaselines() {
             return mText != null ? mText.mLineBaselines : null;
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 4cee2df..99700df 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -18,7 +18,11 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.pm.PackageManager.ComponentInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManager.PackageInfoFlags;
+import android.content.pm.PackageManager.ResolveInfoFlags;
 import android.os.Bundle;
 import android.util.SparseArray;
 
@@ -133,16 +137,40 @@
     public abstract boolean isPermissionsReviewRequired(String packageName, int userId);
 
     /**
-     * Gets all of the information we know about a particular package.
-     *
-     * @param packageName The package name to find.
-     * @param userId The user under which to check.
-     *
-     * @return An {@link ApplicationInfo} containing information about the
-     *         package, or {@code null} if no application exists with that
-     *         package name.
+     * Retrieve all of the information we know about a particular package/application.
+     * @param filterCallingUid The results will be filtered in the context of this UID instead
+     * of the calling UID.
+     * @see PackageManager#getPackageInfo(String, int)
      */
-    public abstract ApplicationInfo getApplicationInfo(String packageName, int userId);
+    public abstract PackageInfo getPackageInfo(String packageName,
+            @PackageInfoFlags int flags, int filterCallingUid, int userId);
+
+    /**
+     * Retrieve all of the information we know about a particular package/application.
+     * @param filterCallingUid The results will be filtered in the context of this UID instead
+     * of the calling UID.
+     * @see PackageManager#getApplicationInfo(String, int)
+     */
+    public abstract ApplicationInfo getApplicationInfo(String packageName,
+            @ApplicationInfoFlags int flags, int filterCallingUid, int userId);
+
+    /**
+     * Retrieve all of the information we know about a particular activity class.
+     * @param filterCallingUid The results will be filtered in the context of this UID instead
+     * of the calling UID.
+     * @see PackageManager#getActivityInfo(ComponentName, int)
+     */
+    public abstract ActivityInfo getActivityInfo(ComponentName component,
+            @ComponentInfoFlags int flags, int filterCallingUid, int userId);
+
+    /**
+     * Retrieve all activities that can be performed for the given intent.
+     * @param filterCallingUid The results will be filtered in the context of this UID instead
+     * of the calling UID.
+     * @see PackageManager#queryIntentActivities(Intent, int)
+     */
+    public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
+            @ResolveInfoFlags int flags, int filterCallingUid, int userId);
 
     /**
      * Interface to {@link com.android.server.pm.PackageManagerService#getHomeActivitiesAsUser}.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 9b0bab4..5e5a6fc 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -7000,6 +7000,7 @@
             return null;
         }
         if (!copyNeeded(flags, a.owner, state, a.metaData, userId)) {
+            updateApplicationInfo(a.info.applicationInfo, flags, state);
             return a.info;
         }
         // Make shallow copies so we can store the metadata safely
@@ -7088,6 +7089,7 @@
             return null;
         }
         if (!copyNeeded(flags, s.owner, state, s.metaData, userId)) {
+            updateApplicationInfo(s.info.applicationInfo, flags, state);
             return s.info;
         }
         // Make shallow copies so we can store the metadata safely
@@ -7183,6 +7185,7 @@
         if (!copyNeeded(flags, p.owner, state, p.metaData, userId)
                 && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0
                         || p.info.uriPermissionPatterns == null)) {
+            updateApplicationInfo(p.info.applicationInfo, flags, state);
             return p.info;
         }
         // Make shallow copies so we can store the metadata safely
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 417a95f..88c1627 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,7 +16,10 @@
 
 package android.content.res;
 
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.Display;
 import android.view.DisplayInfo;
 import com.android.internal.util.XmlUtils;
 
@@ -42,12 +45,6 @@
 import java.util.ArrayList;
 import java.util.Locale;
 
-import static android.view.Surface.ROTATION_UNDEFINED;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_90;
-import static android.view.Surface.ROTATION_180;
-import static android.view.Surface.ROTATION_270;
-
 /**
  * This class describes all device configuration information that can
  * impact the resources the application retrieves.  This includes both
@@ -603,13 +600,6 @@
      */
     public int orientation;
 
-    /**
-     * The rotation used at the time orientation was determined.
-     * TODO(b/36812336): Move rotation out of {@link Configuration}.
-     * {@hide}
-     */
-    private int rotation;
-
     /** Constant for {@link #uiMode}: bits that encode the mode type. */
     public static final int UI_MODE_TYPE_MASK = 0x0f;
     /** Constant for {@link #uiMode}: a {@link #UI_MODE_TYPE_MASK}
@@ -897,7 +887,6 @@
         navigation = o.navigation;
         navigationHidden = o.navigationHidden;
         orientation = o.orientation;
-        rotation = o.rotation;
         screenLayout = o.screenLayout;
         colorMode = o.colorMode;
         uiMode = o.uiMode;
@@ -1001,14 +990,6 @@
             case ORIENTATION_PORTRAIT: sb.append(" port"); break;
             default: sb.append(" orien="); sb.append(orientation); break;
         }
-        switch (rotation) {
-            case ROTATION_UNDEFINED: sb.append(" ?rotation"); break;
-            case ROTATION_0: sb.append(" rot0"); break;
-            case ROTATION_90: sb.append(" rot90"); break;
-            case ROTATION_180: sb.append(" rot180"); break;
-            case ROTATION_270: sb.append(" rot270"); break;
-            default: sb.append(" rot="); sb.append(rotation); break;
-        }
         switch ((uiMode&UI_MODE_TYPE_MASK)) {
             case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break;
             case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break;
@@ -1096,7 +1077,6 @@
         navigation = NAVIGATION_UNDEFINED;
         navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
         orientation = ORIENTATION_UNDEFINED;
-        rotation = ROTATION_UNDEFINED;
         screenLayout = SCREENLAYOUT_UNDEFINED;
         colorMode = COLOR_MODE_UNDEFINED;
         uiMode = UI_MODE_TYPE_UNDEFINED;
@@ -1205,11 +1185,6 @@
             changed |= ActivityInfo.CONFIG_ORIENTATION;
             orientation = delta.orientation;
         }
-        if (delta.rotation != ROTATION_UNDEFINED
-                && rotation != delta.rotation) {
-            changed |= ActivityInfo.CONFIG_ORIENTATION;
-            rotation = delta.rotation;
-        }
 
         if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED)
                 && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK)
@@ -1404,10 +1379,6 @@
                 && orientation != delta.orientation) {
             changed |= ActivityInfo.CONFIG_ORIENTATION;
         }
-        if ((compareUndefined || delta.rotation != ROTATION_UNDEFINED)
-                && rotation != delta.rotation) {
-            changed |= ActivityInfo.CONFIG_ORIENTATION;
-        }
         if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) !=
                 (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED))
                 && getScreenLayoutNoDirection(screenLayout) !=
@@ -1544,7 +1515,6 @@
         dest.writeInt(navigation);
         dest.writeInt(navigationHidden);
         dest.writeInt(orientation);
-        dest.writeInt(rotation);
         dest.writeInt(screenLayout);
         dest.writeInt(colorMode);
         dest.writeInt(uiMode);
@@ -1581,7 +1551,6 @@
         navigation = source.readInt();
         navigationHidden = source.readInt();
         orientation = source.readInt();
-        rotation = source.readInt();
         screenLayout = source.readInt();
         colorMode = source.readInt();
         uiMode = source.readInt();
@@ -1666,8 +1635,6 @@
         if (n != 0) return n;
         n = this.orientation - that.orientation;
         if (n != 0) return n;
-        n = this.rotation - that.rotation;
-        if (n != 0) return n;
         n = this.colorMode - that.colorMode;
         if (n != 0) return n;
         n = this.screenLayout - that.screenLayout;
@@ -1799,24 +1766,6 @@
     /**
      * @hide
      *
-     * Setter for orientation converts from {@link Surface} values to internal representation.
-     */
-    public void setRotation(int rotation) {
-        this.rotation = rotation;
-    }
-
-    /**
-     * @hide
-     *
-     * Getter for orientation. Converts from internal representation to  {@link Surface} values.
-     */
-    public int getRotation() {
-        return rotation != ROTATION_UNDEFINED ? rotation : ROTATION_0;
-    }
-
-    /**
-     * @hide
-     *
      * Clears the locale without changing layout direction.
      */
     public void clearLocales() {
@@ -2051,23 +2000,6 @@
                 break;
         }
 
-        switch (config.rotation) {
-            case ROTATION_0:
-                parts.add("rot0");
-                break;
-            case ROTATION_90:
-                parts.add("rot90");
-                break;
-            case ROTATION_180:
-                parts.add("rot180");
-                break;
-            case ROTATION_270:
-                parts.add("rot270");
-                break;
-            default:
-                break;
-        }
-
         switch (config.uiMode & Configuration.UI_MODE_TYPE_MASK) {
             case Configuration.UI_MODE_TYPE_APPLIANCE:
                 parts.add("appliance");
@@ -2262,10 +2194,6 @@
             delta.orientation = change.orientation;
         }
 
-        if (base.rotation != change.rotation) {
-            base.rotation = change.rotation;
-        }
-
         if ((base.screenLayout & SCREENLAYOUT_SIZE_MASK) !=
                 (change.screenLayout & SCREENLAYOUT_SIZE_MASK)) {
             delta.screenLayout |= change.screenLayout & SCREENLAYOUT_SIZE_MASK;
@@ -2337,7 +2265,6 @@
     private static final String XML_ATTR_NAVIGATION = "nav";
     private static final String XML_ATTR_NAVIGATION_HIDDEN = "navHid";
     private static final String XML_ATTR_ORIENTATION = "ori";
-    private static final String XML_ATTR_ROTATION = "rot";
     private static final String XML_ATTR_SCREEN_LAYOUT = "scrLay";
     private static final String XML_ATTR_COLOR_MODE = "clrMod";
     private static final String XML_ATTR_UI_MODE = "ui";
@@ -2397,8 +2324,6 @@
                 DENSITY_DPI_UNDEFINED);
         configOut.appBounds =
             Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
-        configOut.rotation = XmlUtils.readIntAttribute(parser, XML_ATTR_ROTATION,
-                ROTATION_UNDEFINED);
 
         // For persistence, we don't care about assetsSeq, so do not read it out.
     }
@@ -2475,10 +2400,6 @@
                 config.appBounds.flattenToString());
         }
 
-        if (config.rotation != ROTATION_UNDEFINED) {
-            XmlUtils.writeIntAttribute(xml, XML_ATTR_ROTATION, config.rotation);
-        }
-
         // For persistence, we do not care about assetsSeq, so do not write it out.
     }
 }
diff --git a/core/java/android/net/NetworkBadging.java b/core/java/android/net/NetworkBadging.java
index 6de28b7..c119b63 100644
--- a/core/java/android/net/NetworkBadging.java
+++ b/core/java/android/net/NetworkBadging.java
@@ -66,15 +66,7 @@
      */
     @NonNull public static Drawable getWifiIcon(
             @IntRange(from=0, to=4) int signalLevel, @Badging int badging, @Nullable Theme theme) {
-        Resources resources = Resources.getSystem();
-        if (badging == BADGING_NONE) {
-            return resources.getDrawable(getWifiSignalResource(signalLevel), theme);
-        }
-        Drawable[] layers = new Drawable[] {
-                resources.getDrawable(getBadgedWifiSignalResource(signalLevel), theme),
-                resources.getDrawable(getWifiBadgeResource(badging), theme)
-        };
-        return new LayerDrawable(layers);
+        return Resources.getSystem().getDrawable(getWifiSignalResource(signalLevel), theme);
     }
 
     /**
@@ -134,31 +126,4 @@
                 throw new IllegalArgumentException("Invalid signal level: " + signalLevel);
         }
     }
-
-    /**
-     * Returns the wifi quality badge resource id for the the given badging balue.
-     *
-     * <p>This badge should be displayed with the badge signal resource retrieved from
-     * {@link #getBadgedWifiSignalResource(int)}.
-     *
-     * @param badging {@see NetworkBadging#Badging} from {@link ScoredNetwork#calculateBadge(int)}.
-     * @return the @DrawableRes for the icon or {@link View#NO_ID} for
-     *         {@link NetworkBadging#BADGING_NONE}
-     * @throws IllegalArgumentException for an invalid badging value.
-     * @hide
-     */
-    @DrawableRes private static int getWifiBadgeResource(@Badging int badging) {
-        switch (badging) {
-            case BADGING_NONE:
-                return View.NO_ID;
-            case BADGING_SD:
-                return com.android.internal.R.drawable.ic_signal_wifi_badged_sd;
-            case BADGING_HD:
-                return com.android.internal.R.drawable.ic_signal_wifi_badged_hd;
-            case BADGING_4K:
-                return com.android.internal.R.drawable.ic_signal_wifi_badged_4k;
-            default:
-                throw new IllegalArgumentException("No resource found for badge: " + badging);
-        }
-    }
 }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index ecc4dec..635df4c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -201,7 +201,7 @@
      * New in version 22:
      *   - BLE scan result background count, BLE unoptimized scan time
      */
-    static final String CHECKIN_VERSION = "22";
+    static final String CHECKIN_VERSION = "23";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -3051,6 +3051,7 @@
             boolean wifiOnly) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
@@ -3437,7 +3438,6 @@
                     final int count = bleTimer.getCountLocked(which);
                     final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
                     final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
-                    final long rawRealtimeMs = (rawRealtime + 500) / 1000;
                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
                     final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeBg = bleTimerBg != null ?
@@ -3486,11 +3486,11 @@
 
             if (u.getAggregatedPartialWakelockTimer() != null) {
                 final Timer timer = u.getAggregatedPartialWakelockTimer();
-                // Convert from microseconds to milliseconds with rounding
-                final long totTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+                // Times are since reset (regardless of 'which')
+                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
                 final Timer bgTimer = timer.getSubTimer();
                 final long bgTimeMs = bgTimer != null ?
-                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                 dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
             }
 
@@ -3527,7 +3527,7 @@
                 final int count = timer.getCountLocked(which);
                 final Timer bgTimer = timer.getSubTimer();
                 final long bgTime = bgTimer != null ?
-                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 if (totalTime != 0) {
                     dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"",
@@ -3543,7 +3543,7 @@
                 final int count = timer.getCountLocked(which);
                 final Timer bgTimer = timer.getSubTimer();
                 final long bgTime = bgTimer != null ?
-                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 if (totalTime != 0) {
                     dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
@@ -3574,7 +3574,6 @@
                         final int count = timer.getCountLocked(which);
                         final Timer bgTimer = se.getSensorBackgroundTime();
                         final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
-                        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
                         // 'actualTime' are unpooled and always since reset (regardless of 'which')
                         final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
                         final long bgActualTime = bgTimer != null ?
@@ -3715,6 +3714,7 @@
             int reqUid, boolean wifiOnly) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+        final long rawRealtimeMs = (rawRealtime + 500) / 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
 
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
@@ -4655,7 +4655,6 @@
                     final int count = bleTimer.getCountLocked(which);
                     final Timer bleTimerBg = u.getBluetoothScanBackgroundTimer();
                     final int countBg = bleTimerBg != null ? bleTimerBg.getCountLocked(which) : 0;
-                    final long rawRealtimeMs = (rawRealtime + 500) / 1000;
                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
                     final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeMsBg = bleTimerBg != null ?
@@ -4823,10 +4822,10 @@
                     final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
                     // Convert from microseconds to milliseconds with rounding
                     actualTotalPartialWakelock =
-                            (aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
+                            aggTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final Timer bgAggTimer = aggTimer.getSubTimer();
                     actualBgPartialWakelock = bgAggTimer != null ?
-                            (bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
+                            bgAggTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                 }
 
                 if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
@@ -4894,7 +4893,7 @@
                 final int count = timer.getCountLocked(which);
                 final Timer bgTimer = timer.getSubTimer();
                 final long bgTime = bgTimer != null ?
-                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 sb.setLength(0);
                 sb.append(prefix);
@@ -4928,7 +4927,7 @@
                 final int count = timer.getCountLocked(which);
                 final Timer bgTimer = timer.getSubTimer();
                 final long bgTime = bgTimer != null ?
-                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                        bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : -1;
                 final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 sb.setLength(0);
                 sb.append(prefix);
@@ -4987,7 +4986,6 @@
                     final int count = timer.getCountLocked(which);
                     final Timer bgTimer = se.getSensorBackgroundTime();
                     final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : 0;
-                    final long rawRealtimeMs = (rawRealtime + 500) / 1000;
                     // 'actualTime' are unpooled and always since reset (regardless of 'which')
                     final long actualTime = timer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long bgActualTime = bgTimer != null ?
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index a6cdb03..5046735 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1403,23 +1403,7 @@
 
     /** {@hide} */
     public static File maybeTranslateEmulatedPathToInternal(File path) {
-        final IStorageManager storageManager = IStorageManager.Stub.asInterface(
-                ServiceManager.getService("mount"));
-        try {
-            final VolumeInfo[] vols = storageManager.getVolumes(0);
-            for (VolumeInfo vol : vols) {
-                if ((vol.getType() == VolumeInfo.TYPE_EMULATED
-                        || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
-                    final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
-                            vol.getInternalPath(), path);
-                    if (internalPath != null && internalPath.exists()) {
-                        return internalPath;
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        // Disabled now that FUSE has been replaced by sdcardfs
         return path;
     }
 
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index e8ff2e2..52dccb4 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.app.Activity;
 import android.app.Application.ActivityLifecycleCallbacks;
 import android.content.ComponentName;
@@ -141,6 +142,7 @@
      * @see #getPrintServices
      * @hide
      */
+    @TestApi
     public static final int ALL_SERVICES = ENABLED_SERVICES | DISABLED_SERVICES;
 
     /**
@@ -627,6 +629,7 @@
      *
      * @hide
      */
+    @TestApi
     @SystemApi
     public @NonNull List<PrintServiceInfo> getPrintServices(int selectionFlags) {
         Preconditions.checkFlagsArgument(selectionFlags, ALL_SERVICES);
diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java
index 57f1229..5ef9319 100644
--- a/core/java/android/printservice/PrintServiceInfo.java
+++ b/core/java/android/printservice/PrintServiceInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -48,6 +49,7 @@
  *
  * @hide
  */
+@TestApi
 @SystemApi
 public final class PrintServiceInfo implements Parcelable {
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6a17ed1..f1ce9d5 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5850,6 +5850,7 @@
          *
          * @hide
          */
+        @TestApi
         public static final String DISABLED_PRINT_SERVICES =
             "disabled_print_services";
 
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 286e790..51d6514 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -96,7 +96,7 @@
             int flags, out Rect outFrame, out Rect outOverscanInsets,
             out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
             out Rect outOutsets, out Rect outBackdropFrame,
-            inout MergedConfiguration mergedConfiguration, out Surface outSurface);
+            out MergedConfiguration outMergedConfiguration, out Surface outSurface);
 
     /*
      * Notify the window manager that an application is relaunching and
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 0ad591b..8bb3fa9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -129,17 +129,11 @@
     public static final int SCALING_MODE_NO_SCALE_CROP = 3;
 
     /** @hide */
-    @IntDef({ROTATION_UNDEFINED, ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Rotation {}
 
     /**
-     * Rotation constant: undefined
-     * @hide
-     */
-    public static final int ROTATION_UNDEFINED = -1;
-
-    /**
      * Rotation constant: 0 degree rotation (natural orientation)
      */
     public static final int ROTATION_0 = 0;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 19ae253..a9c85f0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1139,6 +1139,10 @@
 
     /**
      * Autofill type for views that cannot be autofilled.
+     *
+     * <p>Typically used when the view is read-only; for example, a text label.
+     *
+     * @see #getAutofillType()
      */
     public static final int AUTOFILL_TYPE_NONE = 0;
 
@@ -1148,6 +1152,8 @@
      * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
      * {@link AutofillValue#forText(CharSequence)}, and the value passed to autofill a
      * {@link View} can be fetched through {@link AutofillValue#getTextValue()}.
+     *
+     * @see #getAutofillType()
      */
     public static final int AUTOFILL_TYPE_TEXT = 1;
 
@@ -1157,6 +1163,8 @@
      * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
      * {@link AutofillValue#forToggle(boolean)}, and the value passed to autofill a
      * {@link View} can be fetched through {@link AutofillValue#getToggleValue()}.
+     *
+     * @see #getAutofillType()
      */
     public static final int AUTOFILL_TYPE_TOGGLE = 2;
 
@@ -1170,6 +1178,8 @@
      *
      * <p>The available options in the selection list are typically provided by
      * {@link android.app.assist.AssistStructure.ViewNode#getAutofillOptions()}.
+     *
+     * @see #getAutofillType()
      */
     public static final int AUTOFILL_TYPE_LIST = 3;
 
@@ -1182,6 +1192,8 @@
      * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
      * {@link AutofillValue#forDate(long)}, and the values passed to
      * autofill a {@link View} can be fetched through {@link AutofillValue#getDateValue()}.
+     *
+     * @see #getAutofillType()
      */
     public static final int AUTOFILL_TYPE_DATE = 4;
 
@@ -1198,26 +1210,41 @@
 
     /**
      * Automatically determine whether a view is important for autofill.
+     *
+     * @see #isImportantForAutofill()
+     * @see #setImportantForAutofill(int)
      */
     public static final int IMPORTANT_FOR_AUTOFILL_AUTO = 0x0;
 
     /**
      * The view is important for autofill, and its children (if any) will be traversed.
+     *
+     * @see #isImportantForAutofill()
+     * @see #setImportantForAutofill(int)
      */
     public static final int IMPORTANT_FOR_AUTOFILL_YES = 0x1;
 
     /**
      * The view is not important for autofill, but its children (if any) will be traversed.
+     *
+     * @see #isImportantForAutofill()
+     * @see #setImportantForAutofill(int)
      */
     public static final int IMPORTANT_FOR_AUTOFILL_NO = 0x2;
 
     /**
      * The view is important for autofill, but its children (if any) will not be traversed.
+     *
+     * @see #isImportantForAutofill()
+     * @see #setImportantForAutofill(int)
      */
     public static final int IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS = 0x4;
 
     /**
      * The view is not important for autofill, and its children (if any) will not be traversed.
+     *
+     * @see #isImportantForAutofill()
+     * @see #setImportantForAutofill(int)
      */
     public static final int IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS = 0x8;
 
@@ -7366,23 +7393,70 @@
     }
 
     /**
-     * Called when assist structure is being retrieved from a view as part of an autofill request.
+     * Populates a {@link ViewStructure} to fullfil an autofill request.
      *
-     * <p>This method already provides most of what's needed for autofill, but should be overridden
-     * when:
+     * <p>The structure should contain at least the following properties:
      * <ul>
-     *   <li>The view contents does not include PII (Personally Identifiable Information), so it
-     * can call {@link ViewStructure#setDataIsSensitive(boolean)} passing {@code false}.
-     *   <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
-     * {@link ViewStructure#setAutofillOptions(CharSequence[])},
-     * or {@link ViewStructure#setWebDomain(String)}.
-     *   <li> The {@code left} and {@code top} values set in
-     * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
-     * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
+     *   <li>Autofill id ({@link ViewStructure#setAutofillId(AutofillId, int)}).
+     *   <li>Autofill type ({@link ViewStructure#setAutofillType(int)}).
+     *   <li>Autofill value ({@link ViewStructure#setAutofillValue(AutofillValue)}).
+     *   <li>Whether the data is sensitive ({@link ViewStructure#setDataIsSensitive(boolean)}).
      * </ul>
      *
-     * @param structure Fill in with structured view data. The default implementation
-     * fills in all data that can be inferred from the view itself.
+     * <p>It's also recommended to set the following properties - the more properties the structure
+     * has, the higher the changes of an {@link android.service.autofill.AutofillService} properly
+     * using the structure:
+     *
+     * <ul>
+     *   <li>Autofill hints ({@link ViewStructure#setAutofillHints(String[])}).
+     *   <li>Autofill options ({@link ViewStructure#setAutofillOptions(CharSequence[])}) when the
+     *       view can only be filled with predefined values (typically used when the autofill type
+     *       is {@link #AUTOFILL_TYPE_LIST}).
+     *   <li>Resource id ({@link ViewStructure#setId(int, String, String, String)}).
+     *   <li>Class name ({@link ViewStructure#setClassName(String)}).
+     *   <li>Content description ({@link ViewStructure#setContentDescription(CharSequence)}).
+     *   <li>Visual properties such as visibility ({@link ViewStructure#setVisibility(int)}),
+     *       dimensions ({@link ViewStructure#setDimens(int, int, int, int, int, int)}), and
+     *       opacity ({@link ViewStructure#setOpaque(boolean)}).
+     *   <li>For views representing text fields, text properties such as the text itself
+     *       ({@link ViewStructure#setText(CharSequence)}), text hints
+     *       ({@link ViewStructure#setHint(CharSequence)}, input type
+     *       ({@link ViewStructure#setInputType(int)}),
+     *   <li>For views representing HTML nodes, its web domain
+     *       ({@link ViewStructure#setWebDomain(String)}) and HTML properties
+     *       (({@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}).
+     * </ul>
+     *
+     * <p>The default implementation of this method already sets most of these properties based on
+     * related {@link View} methods (for example, the autofill id is set using
+     * {@link #getAutofillId()}, the autofill type set using {@link #getAutofillType()}, etc.),
+     * and views in the standard Android widgets library also override it to set their
+     * relevant properties (for example, {@link android.widget.TextView} already sets the text
+     * properties), so it's recommended to only override this method
+     * (and call {@code super.onProvideAutofillStructure()}) when:
+     *
+     * <ul>
+     *   <li>The view contents does not include PII (Personally Identifiable Information), so it
+     *       can call {@link ViewStructure#setDataIsSensitive(boolean)} passing {@code false}.
+     *   <li>The view can only be autofilled with predefined options, so it can call
+     *       {@link ViewStructure#setAutofillOptions(CharSequence[])}.
+     * </ul>
+     *
+     * <p><b>NOTE:</b> the {@code left} and {@code top} values set in
+     * {@link ViewStructure#setDimens(int, int, int, int, int, int)} must be relative to the next
+     * {@link ViewGroup#isImportantForAutofill()} predecessor view included in the structure.
+     *
+     * <p>Views support the Autofill Framework mainly by:
+     * <ul>
+     *   <li>Providing the metadata defining what the view means and how it can be autofilled.
+     *   <li>Notifying the Android System when the view value changed by calling
+     *       {@link AutofillManager#notifyValueChanged(View)}.
+     *   <li>Implementing the methods that autofill the view.
+     * </ul>
+     * <p>This method is responsible for the former; {@link #autofill(AutofillValue)} is responsible
+     * for the latter.
+     *
+     * @param structure fill in with structured view data for autofill purposes.
      * @param flags optional flags.
      *
      * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
@@ -7510,32 +7584,56 @@
     }
 
     /**
-     * Called when assist structure is being retrieved from a view as part of an autofill request
-     * to generate additional virtual structure under this view.
+     * Populates a {@link ViewStructure} containing virtual children to fullfil an autofill
+     * request.
+     *
+     * <p>This method should be used when the view manages a virtual structure under this view. For
+     * example, a view that draws input fields using {@link #draw(Canvas)}.
      *
      * <p>When implementing this method, subclasses must follow the rules below:
      *
-     * <ol>
-     * <li>Also implement {@link #autofill(SparseArray)} to autofill the virtual
-     * children.
-     * <li>Call
-     * {@link android.view.autofill.AutofillManager#notifyViewEntered} and
-     * {@link android.view.autofill.AutofillManager#notifyViewExited(View, int)}
-     * when the focus inside the view changed.
-     * <li>Call {@link android.view.autofill.AutofillManager#notifyValueChanged(View, int,
-     * AutofillValue)} when the value of a child changed.
-     * <li>Call {@link AutofillManager#commit()} when the autofill context
-     * of the view structure changed and you want the current autofill interaction if such
-     * to be commited.
-     * <li>Call {@link AutofillManager#cancel()} when the autofill context
-     * of the view structure changed and you want the current autofill interaction if such
-     * to be cancelled.
-     * <li> The {@code left} and {@code top} values set in
-     * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
-     * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
-     * </ol>
+     * <ul>
+     *   <li>Add virtual children by calling the {@link ViewStructure#newChild(int)} or
+     *       {@link ViewStructure#asyncNewChild(int)} methods, where the {@code id} is an unique id
+     *       identifying the children in the virtual structure.
+     *   <li>The children hierarchy can have multiple levels if necessary, but ideally it should
+     *       exclude intermediate levels that are irrelevant for autofill; that would improve the
+     *       autofill performance.
+     *   <li>Also implement {@link #autofill(SparseArray)} to autofill the virtual
+     *       children.
+     *   <li>Set the autofill properties of the child structure as defined by
+     *       {@link #onProvideAutofillStructure(ViewStructure, int)}, using
+     *       {@link ViewStructure#setAutofillId(AutofillId, int)} to set its autofill id.
+     *   <li>Call {@link android.view.autofill.AutofillManager#notifyViewEntered(View, int, Rect)}
+     *       and/or {@link android.view.autofill.AutofillManager#notifyViewExited(View, int)}
+     *       when the focused virtual child changed.
+     *   <li>Call
+     *    {@link android.view.autofill.AutofillManager#notifyValueChanged(View, int, AutofillValue)}
+     *       when the value of a virtual child changed.
+     *   <li>Call {@link AutofillManager#commit()} when the autofill context of the view structure
+     *       changed and the current context should be committed (for example, when the user tapped
+     *       a {@code SUBMIT} button in an HTML page).
+     *   <li>Call {@link AutofillManager#cancel()} when the autofill context of the view structure
+     *       changed and the current context should be canceled (for example, when the user tapped
+     *       a {@code CANCEL} button in an HTML page).
+     *   <li>Provide ways for users to manually request autofill by calling
+     *       {@link AutofillManager#requestAutofill(View, int, Rect)}.
+     *   <li>The {@code left} and {@code top} values set in
+     *       {@link ViewStructure#setDimens(int, int, int, int, int, int)} must be relative to the
+     *       next {@link ViewGroup#isImportantForAutofill()} predecessor view included in the
+     *       structure.
+     * </ul>
      *
-     * @param structure Fill in with structured view data.
+     * <p>Views with virtual children support the Autofill Framework mainly by:
+     * <ul>
+     *   <li>Providing the metadata defining what the virtual children mean and how they can be
+     *       autofilled.
+     *   <li>Implementing the methods that autofill the virtual children.
+     * </ul>
+     * <p>This method is responsible for the former; {@link #autofill(SparseArray)} is responsible
+     * for the latter.
+     *
+     * @param structure fill in with virtual children data for autofill purposes.
      * @param flags optional flags.
      *
      * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
@@ -7546,15 +7644,21 @@
     /**
      * Automatically fills the content of this view with the {@code value}.
      *
-     * <p>By default does nothing, but views should override it (and {@link #getAutofillType()},
-     * {@link #getAutofillValue()}, and {@link #onProvideAutofillStructure(ViewStructure, int)}
-     * to support the Autofill Framework.
+     * <p>Views support the Autofill Framework mainly by:
+     * <ul>
+     *   <li>Providing the metadata defining what the view means and how it can be autofilled.
+     *   <li>Implementing the methods that autofill the view.
+     * </ul>
+     * <p>{@link #onProvideAutofillStructure(ViewStructure, int)} is responsible for the former,
+     * this method is responsible for latter.
      *
-     * <p>Typically, it is implemented by:
-     *
+     * <p>This method does nothing by default, but when overridden it typically:
      * <ol>
-     * <li>Calling the proper getter method on {@link AutofillValue} to fetch the actual value.
-     * <li>Passing the actual value to the equivalent setter in the view.
+     *   <li>Checks if the provided value matches the expected type (which is defined by
+     *       {@link #getAutofillType()}).
+     *   <li>Checks if the view is editable - if it isn't, it should return right away.
+     *   <li>Call the proper getter method on {@link AutofillValue} to fetch the actual value.
+     *   <li>Pass the actual value to the equivalent setter in the view.
      * </ol>
      *
      * <p>For example, a text-field view could implement the method this way:
@@ -7573,7 +7677,7 @@
      * </pre>
      *
      * <p>If the value is updated asynchronously the next call to
-     * {@link AutofillManager#notifyValueChanged(View)} must happen <u>after</u> the value was
+     * {@link AutofillManager#notifyValueChanged(View)} must happen <b>after</b> the value was
      * changed to the autofilled value. If not, the view will not be considered autofilled.
      *
      * @param value value to be autofilled.
@@ -7582,11 +7686,19 @@
     }
 
     /**
-     * Automatically fills the content of a virtual views.
+     * Automatically fills the content of the virtual children within this view.
      *
-     * <p>See {@link #autofill(AutofillValue)} and
-     * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
-     * <p>To indicate that a virtual view was autofilled
+     * <p>Views with virtual children support the Autofill Framework mainly by:
+     * <ul>
+     *   <li>Providing the metadata defining what the virtual children mean and how they can be
+     *       autofilled.
+     *   <li>Implementing the methods that autofill the virtual children.
+     * </ul>
+     * <p>{@link #onProvideAutofillVirtualStructure(ViewStructure, int)} is responsible for the
+     * former, this method is responsible for the latter - see {@link #autofill(AutofillValue)} and
+     * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info about autofill.
+     *
+     * <p><b>NOTE:</b> to indicate that a virtual view was autofilled,
      * <code>?android:attr/autofilledHighlight</code> should be drawn over it until the data
      * changes.
      *
@@ -7598,9 +7710,9 @@
     }
 
     /**
-     * Gets the unique identifier of this view on the screen for Autofill purposes.
+     * Gets the unique identifier of this view in the screen, for autofill purposes.
      *
-     * @return The View's Autofill id.
+     * @return The View's autofill id.
      */
     public final AutofillId getAutofillId() {
         if (mAutofillId == null) {
@@ -7612,11 +7724,18 @@
     }
 
     /**
-     * Describes the autofill type that should be used on calls to
-     * {@link #autofill(AutofillValue)} and {@link #autofill(SparseArray)}.
+     * Describes the autofill type of this view, so an
+     * {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue}
+     * when autofilling the view.
      *
-     * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it (and
-     * {@link #autofill(AutofillValue)} to support the Autofill Framework.
+     * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it to properly
+     * support the Autofill Framework.
+     *
+     * @return either {@link #AUTOFILL_TYPE_NONE}, {@link #AUTOFILL_TYPE_TEXT},
+     * {@link #AUTOFILL_TYPE_LIST}, {@link #AUTOFILL_TYPE_DATE}, or {@link #AUTOFILL_TYPE_TOGGLE}.
+     *
+     * @see #onProvideAutofillStructure(ViewStructure, int)
+     * @see #autofill(AutofillValue)
      */
     public @AutofillType int getAutofillType() {
         return AUTOFILL_TYPE_NONE;
@@ -7648,9 +7767,11 @@
     /**
      * Gets the {@link View}'s current autofill value.
      *
-     * <p>By default returns {@code null}, but views should override it (and
-     * {@link #autofill(AutofillValue)}, and {@link #getAutofillType()} to support the Autofill
-     * Framework.
+     * <p>By default returns {@code null}, but views should override it to properly support the
+     * Autofill Framework.
+     *
+     * @see #onProvideAutofillStructure(ViewStructure, int)
+     * @see #autofill(AutofillValue)
      */
     @Nullable
     public AutofillValue getAutofillValue() {
@@ -7658,9 +7779,10 @@
     }
 
     /**
-     * Gets the mode for determining whether this View is important for autofill.
+     * Gets the mode for determining whether this view is important for autofill.
      *
-     * <p>See {@link #setImportantForAutofill(int)} for more info about this mode.
+     * <p>See {@link #setImportantForAutofill(int)} and {@link #isImportantForAutofill()} for more
+     * info about this mode.
      *
      * @return {@link #IMPORTANT_FOR_AUTOFILL_AUTO} by default, or value passed to
      * {@link #setImportantForAutofill(int)}.
@@ -7681,20 +7803,29 @@
     }
 
     /**
-     * Sets the mode for determining whether this View is important for autofill.
-     *
-     * <p>This property controls how this view is presented to the autofill components
-     * which help users to fill credentials, addresses, etc. For example, views
-     * that contain labels and input fields are useful for autofill components to
-     * determine the user context and provide values for the inputs. Note that the
-     * user can always override this by manually triggering autotill which would
-     * expose the view to the autofill provider.
+     * Sets the mode for determining whether this view is considered important for autofill.
      *
      * <p>The platform determines the importance for autofill automatically but you
-     * can use this method to customize the behavior. See the autofill modes below
-     * for more details.
+     * can use this method to customize the behavior. For example:
      *
-     * <p>See {@link #setImportantForAutofill(int)} for more info about this mode.
+     * <ol>
+     *   <li>When the view contents is irrelevant for autofill (for example, a text field used in a
+     *       "Captcha" challenge), it should be {@link #IMPORTANT_FOR_AUTOFILL_NO}.
+     *   <li>When both the view and its children are irrelevant for autofill (for example, the root
+     *       view of an activity containing a spreadhseet editor), it should be
+     *       {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}.
+     *   <li>When the view content is relevant for autofill but its children aren't (for example,
+     *       a credit card expiration date represented by a custom view that overrides the proper
+     *       autofill methods and has 2 children representing the month and year), it should
+     *       be {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS}.
+     * </ol>
+     *
+     * <p><b>NOTE:</strong> setting the mode as does {@link #IMPORTANT_FOR_AUTOFILL_NO} or
+     * {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS} does not guarantee the view (and its
+     * children) will be always be considered not important; for example, when the user explicitly
+     * makes an autofill request, all views are considered important. See
+     * {@link #isImportantForAutofill()} for more details about how the View's importance for
+     * autofill is used.
      *
      * @param mode {@link #IMPORTANT_FOR_AUTOFILL_AUTO}, {@link #IMPORTANT_FOR_AUTOFILL_YES},
      * {@link #IMPORTANT_FOR_AUTOFILL_NO}, {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS},
@@ -7710,40 +7841,51 @@
 
     /**
      * Hints the Android System whether the {@link android.app.assist.AssistStructure.ViewNode}
-     * associated with this View should be included in a {@link ViewStructure} used for
-     * autofill purposes.
+     * associated with this view is considered important for autofill purposes.
      *
      * <p>Generally speaking, a view is important for autofill if:
      * <ol>
-     * <li>The view can-be autofilled by an {@link android.service.autofill.AutofillService}.
-     * <li>The view contents can help an {@link android.service.autofill.AutofillService} to
-     * autofill other views.
+     * <li>The view can be autofilled by an {@link android.service.autofill.AutofillService}.
+     * <li>The view contents can help an {@link android.service.autofill.AutofillService}
+     *     determine how other views can be autofilled.
      * <ol>
      *
      * <p>For example, view containers should typically return {@code false} for performance reasons
-     * (since the important info is provided by their children), but if the container is actually
-     * whose children are part of a compound view, it should return {@code true} (and then override
-     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
-     * {@link #onProvideAutofillStructure(ViewStructure, int)} so its children are not included in
-     * the structure). On the other hand, views representing labels or editable fields should
-     * typically return {@code true}, but in some cases they could return {@code false} (for
-     * example, if they're part of a "Captcha" mechanism).
+     * (since the important info is provided by their children), but if its properties have relevant
+     * information (for example, a resource id called {@code credentials}, it should return
+     * {@code true}. On the other hand, views representing labels or editable fields should
+     * typically return {@code true}, but in some cases they could return {@code false}
+     * (for example, if they're part of a "Captcha" mechanism).
      *
-     * <p>By default, this method returns {@code true} if {@link #getImportantForAutofill()} returns
-     * {@link #IMPORTANT_FOR_AUTOFILL_YES}, {@code false } if it returns
-     * {@link #IMPORTANT_FOR_AUTOFILL_NO}, and use some heuristics to define the importance when it
-     * returns {@link #IMPORTANT_FOR_AUTOFILL_AUTO}. Hence, it should rarely be overridden - Views
-     * should use {@link #setImportantForAutofill(int)} instead.
+     * <p>The value returned by this method depends on the value returned by
+     * {@link #getImportantForAutofill()}:
      *
-     * <p><strong>Note:</strong> returning {@code false} does not guarantee the view will be
-     * excluded from the structure; for example, if the user explicitly requested autofill, the
-     * View might be always included.
+     * <ol>
+     *   <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_YES} or
+     *       {@link #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS}, then it returns {@code true}
+     *   <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_NO} or
+     *       {@link #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS}, then it returns {@code false}
+     *   <li>if it returns {@link #IMPORTANT_FOR_AUTOFILL_AUTO}, then it uses some simple heuristics
+     *       that can return {@code true} in some cases (like a container with a resource id),
+     *       but {@code false} in most.
+     *   <li>otherwise, it returns {@code false}.
+     * </ol>
      *
-     * <p>This decision applies just for the view, not its children - if the view children are not
-     * important for autofill, the view should override
-     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
-     * {@link #onProvideAutofillStructure(ViewStructure, int)} (instead of calling
-     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} for each child).
+     * <p>When a view is considered important for autofill:
+     * <ul>
+     *   <li>The view might automatically trigger an autofill request when focused on.
+     *   <li>The contents of the view are included in the {@link ViewStructure} used in an autofill
+     *       request.
+     * </ul>
+     *
+     * <p>On the other hand, when a view is considered not important for autofill:
+     * <ul>
+     *   <li>The view never automatically triggers autofill requests, but it can trigger a manual
+     *       request through {@link AutofillManager#requestAutofill(View)}.
+     *   <li>The contents of the view are not included in the {@link ViewStructure} used in an
+     *       autofill request, unless the request has the
+     *       {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag.
+     * </ul>
      *
      * @return whether the view is considered important for autofill.
      *
@@ -7753,6 +7895,7 @@
      * @see #IMPORTANT_FOR_AUTOFILL_NO
      * @see #IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS
      * @see #IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS
+     * @see AutofillManager#requestAutofill(View)
      */
     public final boolean isImportantForAutofill() {
         // Check parent mode to ensure we're not hidden.
@@ -7877,29 +8020,38 @@
     }
 
     /**
-     * Dispatch creation of {@link ViewStructure} down the hierarchy.
+     * Dispatches creation of a {@link ViewStructure}s for autofill purposes down the hierarchy,
+     * when an Assist structure is being created as part of an autofill request.
      *
      * <p>The default implementation does the following:
-     *
      * <ul>
      *   <li>Sets the {@link AutofillId} in the structure.
      *   <li>Calls {@link #onProvideAutofillStructure(ViewStructure, int)}.
      *   <li>Calls {@link #onProvideAutofillVirtualStructure(ViewStructure, int)}.
      * </ul>
      *
-     * <p>When overridden, it must either call
-     * {@code super.dispatchProvideAutofillStructure(structure, flags)} or explicitly
-     * set the {@link AutofillId} in the structure (for example, by calling
-     * {@code structure.setAutofillId(getAutofillId())}).
+     * <p>Typically, this method should only be overridden by subclasses that provide a view
+     * hierarchy (such as {@link ViewGroup}) - other classes should override
+     * {@link #onProvideAutofillStructure(ViewStructure, int)} or
+     * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} instead.
      *
-     * <p>When providing your implementation you need to decide how to handle
-     * the {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag which instructs you
-     * to report all views to the structure regardless if {@link #isImportantForAutofill()}
-     * returns true. We encourage you respect the importance property for a better
-     * user experience in your app. If the flag is not set then you should filter out
-     * not important views to optimize autofill performance in your app.
+     * <p>When overridden, it must:
      *
-     * @param structure Fill in with structured view data.
+     * <ul>
+     *   <li>Either call
+     *       {@code super.dispatchProvideAutofillStructure(structure, flags)} or explicitly
+     *       set the {@link AutofillId} in the structure (for example, by calling
+     *       {@code structure.setAutofillId(getAutofillId())}).
+     *   <li>Decide how to handle the {@link #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} flag - when
+     *       set, all views in the structure should be considered important for autofill,
+     *       regardless of what {@link #isImportantForAutofill()} returns. We encourage you to
+     *       respect this flag to provide a better user experience - this flag is typically used
+     *       when an user explicitly requested autofill. If the flag is not set,
+     *       then only views marked as important for autofill should be included in the
+     *       structure - skipping non-important views optimizes the overall autofill performance.
+     * </ul>
+     *
+     * @param structure fill in with structured view data for autofill purposes.
      * @param flags optional flags.
      *
      * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 19e0c95..2605b4a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1845,12 +1845,8 @@
 
         final boolean isViewVisible = viewVisibility == View.VISIBLE;
         final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
-        final int contextConfigSeq = mContext.getResources().getConfiguration().seq;
-        final int lastConfigSeq = mLastReportedMergedConfiguration.getMergedConfiguration().seq;
-        final boolean staleConfig = lastConfigSeq != 0 && contextConfigSeq != lastConfigSeq;
-
-        if (mFirst || windowShouldResize || insetsChanged || staleConfig || viewVisibilityChanged
-                || params != null || mForceNextWindowRelayout) {
+        if (mFirst || windowShouldResize || insetsChanged ||
+                viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
             mForceNextWindowRelayout = false;
 
             if (isViewVisible) {
@@ -6087,13 +6083,7 @@
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
-
-        if (mPendingMergedConfiguration.getMergedConfiguration().seq == 0) {
-            mPendingMergedConfiguration.setTo(mLastReportedMergedConfiguration);
-        }
-
-        int initialConfigSeq = mPendingMergedConfiguration.getMergedConfiguration().seq;
-
+        mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
         //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
@@ -6112,10 +6102,6 @@
                 mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame,
                 mPendingMergedConfiguration, mSurface);
 
-        if (initialConfigSeq == mPendingMergedConfiguration.getMergedConfiguration().seq) {
-            mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
-        }
-
         mPendingAlwaysConsumeNavBar =
                 (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;
 
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index ddfe697..0ecd20d 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -269,6 +269,9 @@
      * Create a new child {@link ViewStructure} in this view, putting into the list of
      * children at <var>index</var>.
      *
+     * <p><b>NOTE: </b>you must pre-allocate space for the child first, by calling either
+     * {@link #addChildCount(int)} or {@link #setChildCount(int)}.
+     *
      * @return Returns an fresh {@link ViewStructure} ready to be filled in.
      */
     public abstract ViewStructure newChild(int index);
@@ -279,6 +282,10 @@
      * to build its content (and children etc).  Once done, some thread must call
      * {@link #asyncCommit} to tell the containing {@link ViewStructure} that the async
      * population is done.
+     *
+     * <p><b>NOTE: </b>you must pre-allocate space for the child first, by calling either
+     * {@link #addChildCount(int)} or {@link #setChildCount(int)}.
+     *
      * @return Returns an fresh {@link ViewStructure} ready to be filled in.
      */
     public abstract ViewStructure asyncNewChild(int index);
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index cfd1445..1e8207a 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -16,8 +16,6 @@
 
 package android.widget;
 
-import static android.os.Build.VERSION_CODES.O;
-
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -293,22 +291,10 @@
      * @param timeInMillis the target day in milliseconds
      * @param animate whether to smooth scroll to the new position
      * @param setSelected whether to set the specified day as selected
-     *
-     * @throws IllegalArgumentException if the build version is greater than
-     *         {@link android.os.Build.VERSION_CODES#N_MR1} and the provided timeInMillis is before
-     *         the range start or after the range end.
      */
     private void setDate(long timeInMillis, boolean animate, boolean setSelected) {
         getTempCalendarForTime(timeInMillis);
 
-        final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
-        if (targetSdkVersion >= O) {
-            if (mTempCalendar.before(mMinDate) || mTempCalendar.after(mMaxDate)) {
-                throw new IllegalArgumentException("timeInMillis must be between the values of "
-                        + "getMinDate() and getMaxDate()");
-            }
-        }
-
         if (setSelected) {
             mSelectedDay.setTimeInMillis(timeInMillis);
         }
@@ -367,6 +353,13 @@
     public void onRangeChanged() {
         mAdapter.setRange(mMinDate, mMaxDate);
 
+        // Clamp the selected day to the new min/max.
+        if (mSelectedDay.before(mMinDate)) {
+            mSelectedDay.setTimeInMillis(mMinDate.getTimeInMillis());
+        } else if (mSelectedDay.after(mMaxDate)) {
+            mSelectedDay.setTimeInMillis(mMaxDate.getTimeInMillis());
+        }
+
         // Changing the min/max date changes the selection position since we
         // don't really have stable IDs. Jumps immediately to the new position.
         setDate(mSelectedDay.getTimeInMillis(), false, false);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 46942bf..235ebc8 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3518,6 +3518,7 @@
     public void removeIsolatedUidLocked(int isolatedUid) {
         mIsolatedUids.delete(isolatedUid);
         mKernelUidCpuTimeReader.removeUid(isolatedUid);
+        mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
     }
 
     public int mapUid(int uid) {
@@ -10351,6 +10352,9 @@
                     public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
                         uid = mapUid(uid);
                         if (Process.isIsolated(uid)) {
+                            mKernelUidCpuFreqTimeReader.removeUid(uid);
+                            Slog.d(TAG, "Got freq readings for an isolated uid with"
+                                    + " no mapping to owning uid: " + uid);
                             return;
                         }
                         final Uid u = getUidStatsLocked(uid);
@@ -11019,6 +11023,7 @@
      */
     public void removeUidStatsLocked(int uid) {
         mKernelUidCpuTimeReader.removeUid(uid);
+        mKernelUidCpuFreqTimeReader.removeUid(uid);
         mUidStats.remove(uid);
     }
 
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index 9fbc4a8..ff521c2 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -72,6 +72,10 @@
         }
     }
 
+    public void removeUid(int uid) {
+        mLastUidCpuFreqTimeMs.delete(uid);
+    }
+
     @VisibleForTesting
     public void readDelta(BufferedReader reader, @Nullable Callback callback) throws IOException {
         String line = reader.readLine();
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 90ece60..3eebe7e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -191,21 +191,15 @@
 
     <!-- Notification title to tell the user that data service is blocked by access control. -->
     <string name="RestrictedOnDataTitle">No data service</string>
-    <!-- Notification title to tell the user that emergency service is blocked by access control. -->
-    <string name="RestrictedOnEmergencyTitle">No emergency service</string>
+    <!-- Notification title to tell the user that emergency calling is blocked by access control. -->
+    <string name="RestrictedOnEmergencyTitle">No emergency calling</string>
     <!-- Notification title to tell the user that normal service is blocked by access control. -->
     <string name="RestrictedOnNormalTitle">No voice service</string>
     <!-- Notification title to tell the user that all emergency and normal voice services are blocked by access control. -->
     <string name="RestrictedOnAllVoiceTitle">No voice/emergency service</string>
 
-    <!-- Notification content to tell the user that data service is blocked by access control. -->
-    <string name="RestrictedOnDataContent">Your carrier has temporarily suspended data service at this location</string>
-    <!-- Notification content to tell the user that emergency service is blocked by access control. -->
-    <string name="RestrictedOnEmergencyContent">Your carrier has temporarily suspended emergency calls at this location</string>
-    <!-- Notification content to tell the user that normal service is blocked by access control. -->
-    <string name="RestrictedOnNormalContent">Your carrier has temporarily suspended voice calls at this location</string>
-    <!-- Notification content to tell the user that all emergency and normal voice services are blocked by access control. -->
-    <string name="RestrictedOnAllVoiceContent">Your carrier has temporarily suspended voice and emergency calls at this location</string>
+    <!-- Notification content to tell the user that voice/data/emergency service is blocked by access control. -->
+    <string name="RestrictedStateContent">Temporarily not offered by the mobile network at your location</string>
 
     <!-- Displayed to tell the user that they should switch their network preference. -->
     <string name="NetworkPreferenceSwitchTitle">Can\u2019t reach network</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index bdefd09..7dd4022 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -521,10 +521,7 @@
   <java-symbol type="string" name="RestrictedOnDataTitle" />
   <java-symbol type="string" name="RestrictedOnEmergencyTitle" />
   <java-symbol type="string" name="RestrictedOnNormalTitle" />
-  <java-symbol type="string" name="RestrictedOnAllVoiceContent" />
-  <java-symbol type="string" name="RestrictedOnDataContent" />
-  <java-symbol type="string" name="RestrictedOnEmergencyContent" />
-  <java-symbol type="string" name="RestrictedOnNormalContent" />
+  <java-symbol type="string" name="RestrictedStateContent" />
   <java-symbol type="string" name="notification_channel_network_alert" />
   <java-symbol type="string" name="notification_channel_call_forward" />
   <java-symbol type="string" name="notification_channel_emergency_callback" />
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index e3b4740..f931d21 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1036,6 +1036,8 @@
         // old shader's pointer may be reused by another shader allocation later
         if (mShader != shader) {
             mNativeShader = -1;
+            // Release any native references to the old shader content
+            nSetShader(mNativePaint, 0);
         }
         // Defer setting the shader natively until getNativeInstance() is called
         mShader = shader;
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 00b5eda..90d6ab8 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -834,6 +834,16 @@
             final Animator localAnimator = animator.clone();
             final String targetName = mTargetNameMap.get(animator);
             final Object target = mVectorDrawable.getTargetByName(targetName);
+            if (!mShouldIgnoreInvalidAnim) {
+                if (target == null) {
+                    throw new IllegalStateException("Target with the name \"" + targetName
+                            + "\" cannot be found in the VectorDrawable to be animated.");
+                } else if (!(target instanceof VectorDrawable.VectorDrawableState)
+                        && !(target instanceof VectorDrawable.VObject)) {
+                    throw new UnsupportedOperationException("Target should be either VGroup, VPath,"
+                            + " or ConstantState, " + target.getClass() + " is not supported");
+                }
+            }
             localAnimator.setTarget(target);
             return localAnimator;
         }
@@ -1321,16 +1331,10 @@
                         throw new IllegalArgumentException("ClipPath only supports PathData " +
                                 "property");
                     }
-
                 }
             } else if (target instanceof VectorDrawable.VectorDrawableState) {
                 createRTAnimatorForRootGroup(values, animator,
                         (VectorDrawable.VectorDrawableState) target, startTime);
-            } else if (!mDrawable.mAnimatedVectorState.mShouldIgnoreInvalidAnim) {
-                // Should never get here
-                throw new UnsupportedOperationException("Target should be either VGroup, VPath, " +
-                        "or ConstantState, " + target == null ? "Null target" : target.getClass() +
-                        " is not supported");
             }
         }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
index 6678f8b..5680d9f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/StaticMetadata.java
@@ -1139,9 +1139,18 @@
         }
         List<Integer> modeList = new ArrayList<Integer>();
         for (int mode : modes) {
-            modeList.add(mode);
+            // Skip vendor-added modes
+            if (mode <= CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
+                modeList.add(mode);
+            }
         }
         checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
+        modes = new int[modeList.size()];
+        for (int i = 0; i < modeList.size(); i++) {
+            modes[i] = modeList.get(i);
+        }
+
+        checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
 
         // All camera device must support ON
         checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain ON mode",
@@ -1227,7 +1236,17 @@
             return new int[0];
         }
 
-        List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes));
+        List<Integer> modesList = new ArrayList<Integer>();
+        for (int afMode : afModes) {
+            // Skip vendor-added AF modes
+            if (afMode > CameraCharacteristics.CONTROL_AF_MODE_EDOF) continue;
+            modesList.add(afMode);
+        }
+        afModes = new int[modesList.size()];
+        for (int i = 0; i < modesList.size(); i++) {
+            afModes[i] = modesList.get(i);
+        }
+
         if (isHardwareLevelLimitedOrBetter()) {
             // Some LEGACY mode devices do not support AF OFF
             checkTrueForKey(key, " All camera devices must support OFF mode",
@@ -1417,6 +1436,16 @@
         return fpsRanges;
     }
 
+    public static String getAeModeName(int aeMode) {
+        return (aeMode >= AE_MODE_NAMES.length) ? String.format("VENDOR_AE_MODE_%d", aeMode) :
+            AE_MODE_NAMES[aeMode];
+    }
+
+    public static String getAfModeName(int afMode) {
+        return (afMode >= AF_MODE_NAMES.length) ? String.format("VENDOR_AF_MODE_%d", afMode) :
+            AF_MODE_NAMES[afMode];
+    }
+
     /**
      * Get the highest supported target FPS range.
      * Prioritizes maximizing the min FPS, then the max FPS without lowering min FPS.
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 20cc5a6..40a59cf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -136,8 +136,6 @@
 
     private final NetworkScoreManager mNetworkScoreManager;
     private final WifiNetworkScoreCache mScoreCache;
-    private boolean mNetworkScoringUiEnabled;
-    private final ContentObserver mObserver;
 
     @GuardedBy("mLock")
     private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
@@ -225,16 +223,6 @@
                 updateNetworkScores();
             }
         });
-
-        mObserver = new ContentObserver(mWorkHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mNetworkScoringUiEnabled =
-                        Settings.Global.getInt(
-                                mContext.getContentResolver(),
-                                Settings.Global.NETWORK_SCORING_UI_ENABLED, 0) == 1;
-            }
-        };
     }
 
     /**
@@ -308,12 +296,6 @@
         synchronized (mLock) {
             registerScoreCache();
 
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
-                    false /* notifyForDescendants */,
-                    mObserver);
-            mObserver.onChange(false /* selfChange */); // Set mScoringUiEnabled
-
             resumeScanning();
             if (!mRegistered) {
                 mContext.registerReceiver(mReceiver, mFilter);
@@ -360,7 +342,6 @@
             }
             unregisterAndClearScoreCache();
             pauseScanning();
-            mContext.getContentResolver().unregisterContentObserver(mObserver);
 
             mWorkHandler.removePendingMessages();
             mMainHandler.removePendingMessages();
@@ -580,7 +561,7 @@
 
         requestScoresForNetworkKeys(scoresToRequest);
         for (AccessPoint ap : accessPoints) {
-            ap.update(mScoreCache, mNetworkScoringUiEnabled);
+            ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */);
         }
 
         // Pre-sort accessPoints to speed preference insertion
@@ -678,7 +659,7 @@
                     updated = true;
                     if (previouslyConnected != ap.isActive()) reorder = true;
                 }
-                if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
+                if (ap.update(mScoreCache, false /* mNetworkScoringUiEnabled */)) {
                     reorder = true;
                     updated = true;
                 }
@@ -701,7 +682,8 @@
         synchronized (mLock) {
             boolean updated = false;
             for (int i = 0; i < mInternalAccessPoints.size(); i++) {
-                if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
+                if (mInternalAccessPoints.get(i).update(
+                        mScoreCache, false /* mNetworkScoringUiEnabled */)) {
                     updated = true;
                 }
             }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 086e10c..c526432 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -473,7 +473,7 @@
     }
 
     @Test
-    public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
+    public void scoreCacheUpdateScoresShouldNotChangeSortOrder() throws InterruptedException {
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
         List<AccessPoint> aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
@@ -484,8 +484,8 @@
 
         aps = tracker.getAccessPoints();
         assertTrue(aps.size() == 2);
-        assertEquals(aps.get(0).getSsidStr(), SSID_2);
-        assertEquals(aps.get(1).getSsidStr(), SSID_1);
+        assertEquals(aps.get(0).getSsidStr(), SSID_1);
+        assertEquals(aps.get(1).getSsidStr(), SSID_2);
     }
 
     @Test
@@ -511,7 +511,8 @@
     }
 
     @Test
-    public void scoreCacheUpdateScoresShouldInsertBadgeIntoAccessPoint() throws InterruptedException {
+    public void scoreCacheUpdateScoresShouldNotInsertBadgeIntoAccessPoint()
+            throws InterruptedException {
         WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
         updateScoresAndWaitForAccessPointsChangedCallback();
 
@@ -519,9 +520,9 @@
 
         for (AccessPoint ap : aps) {
             if (ap.getSsidStr().equals(SSID_1)) {
-                assertEquals(BADGE_1, ap.getBadge());
+                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
             } else if (ap.getSsidStr().equals(SSID_2)) {
-                assertEquals(BADGE_2, ap.getBadge());
+                assertEquals(NetworkBadging.BADGING_NONE, ap.getBadge());
             }
         }
     }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 455d9cb..f5d7dd8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2212,11 +2212,7 @@
                 throw new IllegalStateException("Key is corrupted", e);
             }
 
-            // Mac the package name and each of the signatures.
-            final String packageName = callingPkg.packageName;
-            byte[] packageNameBytes = packageName.getBytes(StandardCharsets.UTF_8);
-            m.update(getLengthPrefix(packageNameBytes), 0, 4);
-            m.update(packageNameBytes);
+            // Mac each of the developer signatures.
             for (int i = 0; i < callingPkg.signatures.length; i++) {
                 byte[] sig = callingPkg.signatures[i].toByteArray();
                 m.update(getLengthPrefix(sig), 0, 4);
@@ -2231,7 +2227,7 @@
             final String uid = Integer.toString(callingPkg.applicationInfo.uid);
             final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
             final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
-                    packageName);
+                callingPkg.packageName);
 
             if (!success) {
                 throw new IllegalStateException("Ssaid settings not accessible");
diff --git a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
index 3fb86d0..1b6fa4c 100644
--- a/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-h560dp/dimens.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources>
-    <dimen name="widget_big_font_size">64dp</dimen>
+    <dimen name="widget_big_font_size">72dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
index 3fb86d0..1b6fa4c 100644
--- a/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-h650dp/dimens.xml
@@ -16,5 +16,5 @@
   -->
 
 <resources>
-    <dimen name="widget_big_font_size">64dp</dimen>
+    <dimen name="widget_big_font_size">72dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 3ca6e69..41c723e 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -41,7 +41,7 @@
     <!-- Default clock parameters -->
     <dimen name="bottom_text_spacing_digital">-1dp</dimen>
     <dimen name="widget_label_font_size">14sp</dimen>
-    <dimen name="widget_big_font_size">64dp</dimen>
+    <dimen name="widget_big_font_size">72dp</dimen>
 
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index ecbc4f7..9557262 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -140,7 +140,8 @@
         if (mState.value) {
             mController.setZen(ZEN_MODE_OFF, null, TAG);
         } else {
-            mController.setZen(ZEN_MODE_ALARMS, null, TAG);
+            int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
+            mController.setZen(zen, null, TAG);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 7697061..ba3bcc7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -514,6 +514,9 @@
             RecentsActivityLaunchState launchState = config.getLaunchState();
             launchState.reset();
         }
+
+        // Force a gc to attempt to clean up bitmap references more quickly (b/38258699)
+        Recents.getSystemServices().gc();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index cbfa0e5..1f13830 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -362,6 +362,19 @@
     }
 
     /**
+     * Requests a gc() from the background thread.
+     */
+    public void gc() {
+        BackgroundThread.getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                System.gc();
+                System.runFinalization();
+            }
+        });
+    }
+
+    /**
      * @return whether the provided {@param className} is blacklisted
      */
     public boolean isBlackListedActivity(String className) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 6fb5d6b..1c1be98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1395,6 +1395,7 @@
         if (mIsSummaryWithChildren) {
             mChildrenContainer.setDark(dark, fade, delay);
         }
+        updateShelfIconColor();
     }
 
     public boolean isExpandable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index baf0c2c..c432ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -49,11 +49,11 @@
  */
 public class NotificationContentView extends FrameLayout {
 
-    private static final int VISIBLE_TYPE_CONTRACTED = 0;
-    private static final int VISIBLE_TYPE_EXPANDED = 1;
-    private static final int VISIBLE_TYPE_HEADSUP = 2;
+    public static final int VISIBLE_TYPE_CONTRACTED = 0;
+    public static final int VISIBLE_TYPE_EXPANDED = 1;
+    public static final int VISIBLE_TYPE_HEADSUP = 2;
     private static final int VISIBLE_TYPE_SINGLELINE = 3;
-    private static final int VISIBLE_TYPE_AMBIENT = 4;
+    public static final int VISIBLE_TYPE_AMBIENT = 4;
     private static final int VISIBLE_TYPE_AMBIENT_SINGLELINE = 5;
     public static final int UNDEFINED = -1;
 
@@ -928,7 +928,7 @@
         }
     }
 
-    private NotificationViewWrapper getVisibleWrapper(int visibleType) {
+    public NotificationViewWrapper getVisibleWrapper(int visibleType) {
         switch (visibleType) {
             case VISIBLE_TYPE_EXPANDED:
                 return mExpandedWrapper;
@@ -1085,16 +1085,16 @@
         mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
         updateAllSingleLineViews();
         if (mContractedChild != null) {
-            mContractedWrapper.notifyContentUpdated(entry.row);
+            mContractedWrapper.onContentUpdated(entry.row);
         }
         if (mExpandedChild != null) {
-            mExpandedWrapper.notifyContentUpdated(entry.row);
+            mExpandedWrapper.onContentUpdated(entry.row);
         }
         if (mHeadsUpChild != null) {
-            mHeadsUpWrapper.notifyContentUpdated(entry.row);
+            mHeadsUpWrapper.onContentUpdated(entry.row);
         }
         if (mAmbientChild != null) {
-            mAmbientWrapper.notifyContentUpdated(entry.row);
+            mAmbientWrapper.onContentUpdated(entry.row);
         }
         applyRemoteInput(entry);
         updateLegacy();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 531437d..58844ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -146,12 +146,12 @@
 
             // Construct the icon.
             icon = new StatusBarIconView(context,
-                    sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
+                    sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
             icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
             // Construct the expanded icon.
             expandedIcon = new StatusBarIconView(context,
-                    sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
+                    sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
             expandedIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
             final StatusBarIcon ic = new StatusBarIcon(
                     sbn.getUser(),
@@ -187,9 +187,11 @@
          * @param n the notification to read the icon from.
          * @throws InflationException
          */
-        public void updateIcons(Context context, Notification n) throws InflationException {
+        public void updateIcons(Context context, StatusBarNotification sbn)
+                throws InflationException {
             if (icon != null) {
                 // Update the icon
+                Notification n = sbn.getNotification();
                 final StatusBarIcon ic = new StatusBarIcon(
                         notification.getUser(),
                         notification.getPackageName(),
@@ -197,8 +199,8 @@
                         n.iconLevel,
                         n.number,
                         StatusBarIconView.contentDescForNotification(context, n));
-                icon.setNotification(n);
-                expandedIcon.setNotification(n);
+                icon.setNotification(sbn);
+                expandedIcon.setNotification(sbn);
                 if (!icon.set(ic) || !expandedIcon.set(ic)) {
                     throw new InflationException("Couldn't update icon: " + ic);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 85475b6..3c7ddb5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -34,6 +34,7 @@
 import android.graphics.drawable.Icon;
 import android.os.Parcelable;
 import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -99,7 +100,7 @@
     private int mNumberX;
     private int mNumberY;
     private String mNumberText;
-    private Notification mNotification;
+    private StatusBarNotification mNotification;
     private final boolean mBlocked;
     private int mDensity;
     private float mIconScale = 1.0f;
@@ -127,11 +128,11 @@
     };
     private final NotificationIconDozeHelper mDozer;
 
-    public StatusBarIconView(Context context, String slot, Notification notification) {
-        this(context, slot, notification, false);
+    public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
+        this(context, slot, sbn, false);
     }
 
-    public StatusBarIconView(Context context, String slot, Notification notification,
+    public StatusBarIconView(Context context, String slot, StatusBarNotification sbn,
             boolean blocked) {
         super(context);
         mDozer = new NotificationIconDozeHelper(context);
@@ -141,7 +142,7 @@
         mNumberPain.setTextAlign(Paint.Align.CENTER);
         mNumberPain.setColor(context.getColor(R.drawable.notification_number_text_color));
         mNumberPain.setAntiAlias(true);
-        setNotification(notification);
+        setNotification(sbn);
         maybeUpdateIconScaleDimens();
         setScaleType(ScaleType.CENTER);
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
@@ -207,9 +208,11 @@
         }
     }
 
-    public void setNotification(Notification notification) {
+    public void setNotification(StatusBarNotification notification) {
         mNotification = notification;
-        setContentDescription(notification);
+        if (notification != null) {
+            setContentDescription(notification.getNotification());
+        }
     }
 
     public StatusBarIconView(Context context, AttributeSet attrs) {
@@ -315,6 +318,10 @@
         return true;
     }
 
+    public Icon getSourceIcon() {
+        return mIcon.icon;
+    }
+
     private Drawable getIcon(StatusBarIcon icon) {
         return getIcon(getContext(), icon);
     }
@@ -354,7 +361,7 @@
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
         if (mNotification != null) {
-            event.setParcelableData(mNotification);
+            event.setParcelableData(mNotification.getNotification());
         }
     }
 
@@ -456,6 +463,10 @@
             + " notification=" + mNotification + ")";
     }
 
+    public StatusBarNotification getNotification() {
+        return mNotification;
+    }
+
     public String getSlot() {
         return mSlot;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
index 7a34b6e..cf12e94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
@@ -36,8 +36,8 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
-        super.notifyContentUpdated(row);
+    public void onContentUpdated(ExpandableNotificationRow row) {
+        super.onContentUpdated(row);
         updateImageTag(row.getStatusBarNotification());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
index 9476eed..20a3d8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
@@ -41,11 +41,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
+    public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveViews(row.getStatusBarNotification());
-        super.notifyContentUpdated(row);
+        super.onContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 0b9244a..15cca5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -128,8 +128,8 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
-        super.notifyContentUpdated(row);
+    public void onContentUpdated(ExpandableNotificationRow row) {
+        super.onContentUpdated(row);
         mIsLowPriority = row.isLowPriority();
         mTransformLowPriorityTitle = !row.isChildInGroup() && !row.isSummaryWithChildren();
         ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 4b08f2b..7eaa290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -36,7 +36,6 @@
 import com.android.systemui.util.Assert;
 
 import java.util.HashMap;
-import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
@@ -207,7 +206,8 @@
             };
             applyRemoteView(result, reInflateFlags, flag, row, redactAmbient,
                     isNewView, remoteViewClickHandler, callback, entry, privateLayout,
-                    privateLayout.getContractedChild(),
+                    privateLayout.getContractedChild(), privateLayout.getVisibleWrapper(
+                            NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
         }
 
@@ -229,7 +229,9 @@
                 };
                 applyRemoteView(result, reInflateFlags, flag, row,
                         redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
-                        privateLayout, privateLayout.getExpandedChild(), runningInflations,
+                        privateLayout, privateLayout.getExpandedChild(),
+                        privateLayout.getVisibleWrapper(
+                                NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations,
                         applyCallback);
             }
         }
@@ -252,7 +254,9 @@
                 };
                 applyRemoteView(result, reInflateFlags, flag, row,
                         redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
-                        privateLayout, privateLayout.getHeadsUpChild(), runningInflations,
+                        privateLayout, privateLayout.getHeadsUpChild(),
+                        privateLayout.getVisibleWrapper(
+                                NotificationContentView.VISIBLE_TYPE_HEADSUP), runningInflations,
                         applyCallback);
             }
         }
@@ -274,8 +278,9 @@
             };
             applyRemoteView(result, reInflateFlags, flag, row,
                     redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
-                    publicLayout, publicLayout.getContractedChild(), runningInflations,
-                    applyCallback);
+                    publicLayout, publicLayout.getContractedChild(),
+                    publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED),
+                    runningInflations, applyCallback);
         }
 
         flag = FLAG_REINFLATE_AMBIENT_VIEW;
@@ -296,7 +301,8 @@
             };
             applyRemoteView(result, reInflateFlags, flag, row,
                     redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
-                    newParent, newParent.getAmbientChild(), runningInflations,
+                    newParent, newParent.getAmbientChild(), newParent.getVisibleWrapper(
+                            NotificationContentView.VISIBLE_TYPE_AMBIENT), runningInflations,
                     applyCallback);
         }
 
@@ -316,6 +322,7 @@
             RemoteViews.OnClickHandler remoteViewClickHandler,
             @Nullable final InflationCallback callback, NotificationData.Entry entry,
             NotificationContentView parentLayout, View existingView,
+            NotificationViewWrapper existingWrapper,
             final HashMap<Integer, CancellationSignal> runningInflations,
             ApplyCallback applyCallback) {
         RemoteViews.OnViewAppliedListener listener
@@ -326,6 +333,8 @@
                 if (isNewView) {
                     v.setIsRootNamespace(true);
                     applyCallback.setResultView(v);
+                } else if (existingWrapper != null) {
+                    existingWrapper.onReinflated();
                 }
                 runningInflations.remove(inflationId);
                 finishIfDone(result, reInflateFlags, runningInflations, callback, row,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
index 8596cb3..eb211a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification;
 
 import android.content.Context;
-import android.service.notification.StatusBarNotification;
 import android.view.View;
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -40,11 +39,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
+    public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveViews();
-        super.notifyContentUpdated(row);
+        super.onContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
index 9631556..f6ee1ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
@@ -70,11 +70,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
+    public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveViews();
-        super.notifyContentUpdated(row);
+        super.onContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index f0b6b2e..abb4cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -133,11 +133,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
+    public void onContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveTemplateViews(row.getStatusBarNotification());
-        super.notifyContentUpdated(row);
+        super.onContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 5cc39cc..4b73613 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -66,6 +66,7 @@
         mView = view;
         mRow = row;
         mDozer = createDozer(ctx);
+        onReinflated();
     }
 
     protected NotificationDozeHelper createDozer(Context ctx) {
@@ -92,12 +93,15 @@
      * Notifies this wrapper that the content of the view might have changed.
      * @param row the row this wrapper is attached to
      */
-    public void notifyContentUpdated(ExpandableNotificationRow row) {
+    public void onContentUpdated(ExpandableNotificationRow row) {
         mDarkInitialized = false;
-        Drawable background = mView.getBackground();
+    }
+
+    public void onReinflated() {
         if (shouldClearBackgroundOnReapply()) {
             mBackgroundColor = 0;
         }
+        Drawable background = mView.getBackground();
         if (background instanceof ColorDrawable) {
             mBackgroundColor = ((ColorDrawable) background).getColor();
             mView.setBackground(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 52838b0..5bfdd1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -4,11 +4,15 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.graphics.drawable.Icon;
 import android.support.annotation.NonNull;
+import android.support.v4.util.ArrayMap;
+import android.support.v4.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.FrameLayout;
 
+import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -180,14 +184,54 @@
             }
         }
 
+        // In case we are changing the suppression of a group, the replacement shouldn't flicker
+        // and it should just be replaced instead. We therefore look for notifications that were
+        // just replaced by the child or vice-versa to suppress this.
 
+        ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons = new ArrayMap<>();
         ArrayList<View> toRemove = new ArrayList<>();
         for (int i = 0; i < hostLayout.getChildCount(); i++) {
             View child = hostLayout.getChildAt(i);
+            if (!(child instanceof StatusBarIconView)) {
+                continue;
+            }
             if (!toShow.contains(child)) {
-                toRemove.add(child);
+                boolean iconWasReplaced = false;
+                StatusBarIconView removedIcon = (StatusBarIconView) child;
+                String removedGroupKey = removedIcon.getNotification().getGroupKey();
+                for (int j = 0; j < toShow.size(); j++) {
+                    StatusBarIconView candidate = toShow.get(j);
+                    if (candidate.getSourceIcon().sameAs((removedIcon.getSourceIcon()))
+                            && candidate.getNotification().getGroupKey().equals(removedGroupKey)) {
+                        if (!iconWasReplaced) {
+                            iconWasReplaced = true;
+                        } else {
+                            iconWasReplaced = false;
+                            break;
+                        }
+                    }
+                }
+                if (iconWasReplaced) {
+                    ArrayList<StatusBarIcon> statusBarIcons = replacingIcons.get(removedGroupKey);
+                    if (statusBarIcons == null) {
+                        statusBarIcons = new ArrayList<>();
+                        replacingIcons.put(removedGroupKey, statusBarIcons);
+                    }
+                    statusBarIcons.add(removedIcon.getStatusBarIcon());
+                }
+                toRemove.add(removedIcon);
             }
         }
+        // removing all duplicates
+        ArrayList<String> duplicates = new ArrayList<>();
+        for (String key : replacingIcons.keySet()) {
+            ArrayList<StatusBarIcon> statusBarIcons = replacingIcons.get(key);
+            if (statusBarIcons.size() != 1) {
+                duplicates.add(key);
+            }
+        }
+        replacingIcons.removeAll(duplicates);
+        hostLayout.setReplacingIcons(replacingIcons);
 
         final int toRemoveCount = toRemove.size();
         for (int i = 0; i < toRemoveCount; i++) {
@@ -217,6 +261,7 @@
             hostLayout.addView(expected, i);
         }
         hostLayout.setChangingViewPositions(false);
+        hostLayout.setReplacingIcons(null);
     }
 
     /**
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 f94bb0c..a4fadc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -21,9 +21,13 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.drawable.Icon;
+import android.support.v4.util.ArrayMap;
+import android.support.v4.util.ArraySet;
 import android.util.AttributeSet;
 import android.view.View;
 
+import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
@@ -33,6 +37,7 @@
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 import com.android.systemui.statusbar.stack.ViewState;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
@@ -117,6 +122,7 @@
     private float mVisualOverflowAdaption;
     private boolean mDisallowNextAnimation;
     private boolean mAnimationsEnabled = true;
+    private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons;
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -183,11 +189,17 @@
     @Override
     public void onViewAdded(View child) {
         super.onViewAdded(child);
+        boolean isReplacingIcon = isReplacingIcon(child);
         if (!mChangingViewPositions) {
-            mIconStates.put(child, new IconState());
+            IconState v = new IconState();
+            if (isReplacingIcon) {
+                v.justAdded = false;
+                v.justReplaced = true;
+            }
+            mIconStates.put(child, v);
         }
         int childIndex = indexOfChild(child);
-        if (childIndex < getChildCount() - 1
+        if (childIndex < getChildCount() - 1 && !isReplacingIcon
             && mIconStates.get(getChildAt(childIndex + 1)).iconAppearAmount > 0.0f) {
             if (mAddAnimationStartIndex < 0) {
                 mAddAnimationStartIndex = childIndex;
@@ -200,13 +212,34 @@
         }
     }
 
+    private boolean isReplacingIcon(View child) {
+        if (mReplacingIcons == null) {
+            return false;
+        }
+        if (!(child instanceof StatusBarIconView)) {
+            return false;
+        }
+        StatusBarIconView iconView = (StatusBarIconView) child;
+        Icon sourceIcon = iconView.getSourceIcon();
+        String groupKey = iconView.getNotification().getGroupKey();
+        ArrayList<StatusBarIcon> statusBarIcons = mReplacingIcons.get(groupKey);
+        if (statusBarIcons != null) {
+            StatusBarIcon replacedIcon = statusBarIcons.get(0);
+            if (sourceIcon.sameAs(replacedIcon.icon)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
         if (child instanceof StatusBarIconView) {
+            boolean isReplacingIcon = isReplacingIcon(child);
             final StatusBarIconView icon = (StatusBarIconView) child;
             if (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
-                    && child.getVisibility() == VISIBLE) {
+                    && child.getVisibility() == VISIBLE && isReplacingIcon) {
                 int animationStartIndex = findFirstViewIndexAfter(icon.getTranslationX());
                 if (mAddAnimationStartIndex < 0) {
                     mAddAnimationStartIndex = animationStartIndex;
@@ -216,9 +249,11 @@
             }
             if (!mChangingViewPositions) {
                 mIconStates.remove(child);
-                addTransientView(icon, 0);
-                icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
-                        () -> removeTransientView(icon));
+                if (!isReplacingIcon) {
+                    addTransientView(icon, 0);
+                    icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
+                            () -> removeTransientView(icon));
+                }
             }
         }
     }
@@ -473,11 +508,16 @@
         mAnimationsEnabled = enabled;
     }
 
+    public void setReplacingIcons(ArrayMap<String, ArrayList<StatusBarIcon>> replacingIcons) {
+        mReplacingIcons = replacingIcons;
+    }
+
     public class IconState extends ViewState {
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
         public int visibleState;
         public boolean justAdded = true;
+        private boolean justReplaced;
         public boolean needsCannedAnimation;
         public boolean useFullTransitionAmount;
         public boolean useLinearTransitionAmount;
@@ -496,9 +536,9 @@
                         && !mDisallowNextAnimation
                         && !noAnimations;
                 if (animationsAllowed) {
-                    if (justAdded) {
+                    if (justAdded || justReplaced) {
                         super.applyToView(icon);
-                        if (iconAppearAmount != 0.0f) {
+                        if (justAdded && iconAppearAmount != 0.0f) {
                             icon.setAlpha(0.0f);
                             icon.setVisibleState(StatusBarIconView.STATE_HIDDEN,
                                     false /* animate */);
@@ -557,6 +597,7 @@
                 }
             }
             justAdded = false;
+            justReplaced = false;
             needsCannedAnimation = false;
             justUndarkened = false;
         }
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 acc9436..f4f48a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -6121,6 +6121,9 @@
     }
 
     public boolean isLockscreenPublicMode(int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            return mLockscreenPublicMode.get(mCurrentUserId, false);
+        }
         return mLockscreenPublicMode.get(userId, false);
     }
 
@@ -6799,7 +6802,7 @@
         entry.notification = notification;
         mGroupManager.onEntryUpdated(entry, oldNotification);
 
-        entry.updateIcons(mContext, n);
+        entry.updateIcons(mContext, notification);
         inflateViews(entry, mStackScroller);
 
         mForegroundServiceController.updateNotification(notification,
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 ff06b5b..b6964a03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -297,7 +297,7 @@
         } else {
             header.reapply(getContext(), mNotificationHeader);
         }
-        mNotificationHeaderWrapper.notifyContentUpdated(mContainingNotification);
+        mNotificationHeaderWrapper.onContentUpdated(mContainingNotification);
         recreateLowPriorityHeader(builder);
         recreateAmbientHeader(builder);
         updateHeaderVisibility(false /* animate */);
@@ -316,14 +316,14 @@
             mNotificationHeaderAmbient = (ViewGroup) header.apply(getContext(), this);
             mNotificationHeaderWrapperAmbient = NotificationViewWrapper.wrap(getContext(),
                     mNotificationHeaderAmbient, mContainingNotification);
-            mNotificationHeaderWrapperAmbient.notifyContentUpdated(mContainingNotification);
+            mNotificationHeaderWrapperAmbient.onContentUpdated(mContainingNotification);
             addView(mNotificationHeaderAmbient, 0);
             invalidate();
         } else {
             header.reapply(getContext(), mNotificationHeaderAmbient);
         }
         resetHeaderVisibilityIfNeeded(mNotificationHeaderAmbient, calculateDesiredHeader());
-        mNotificationHeaderWrapperAmbient.notifyContentUpdated(mContainingNotification);
+        mNotificationHeaderWrapperAmbient.onContentUpdated(mContainingNotification);
     }
 
     /**
@@ -354,7 +354,7 @@
             } else {
                 header.reapply(getContext(), mNotificationHeaderLowPriority);
             }
-            mNotificationHeaderWrapperLowPriority.notifyContentUpdated(mContainingNotification);
+            mNotificationHeaderWrapperLowPriority.onContentUpdated(mContainingNotification);
             resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, calculateDesiredHeader());
         } else {
             removeView(mNotificationHeaderLowPriority);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index d44f845..2e547e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -95,4 +95,11 @@
         row.setHideSensitive(true, false, 0, 0);
         verify(row).updateShelfIconColor();
     }
+
+    @Test
+    public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
+        ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
+        row.setDark(true, false, 0);
+        verify(row).updateShelfIconColor();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index fc9b608..917a9f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -53,11 +53,14 @@
         RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.custom_view_dark);
         View v = views.apply(mContext, null);
         NotificationViewWrapper wrap = NotificationCustomViewWrapper.wrap(mContext, v, mRow);
-        wrap.notifyContentUpdated(mRow);
-        Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+        wrap.onContentUpdated(mRow);
+        Assert.assertTrue("No background set, when applying custom background view",
+                wrap.getCustomBackgroundColor() != 0);
         views.reapply(mContext, v);
-        wrap.notifyContentUpdated(mRow);
-        Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+        wrap.onReinflated();
+        wrap.onContentUpdated(mRow);
+        Assert.assertTrue("Reapplying a custom remote view lost it's background!",
+                wrap.getCustomBackgroundColor() != 0);
     }
 
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
index ebeb24c8..9da28a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
@@ -24,6 +24,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -35,7 +36,9 @@
 
     @Test
     public void constructor_doesntUseViewContext() throws Exception {
-        new TestableNotificationViewWrapper(mContext, null /* view */, null /* row */);
+        new TestableNotificationViewWrapper(mContext,
+                new View(mContext),
+                new NotificationTestHelper(getContext()).createRow());
     }
 
     static class TestableNotificationViewWrapper extends NotificationViewWrapper {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ec4dc64..f0b1b3b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -751,6 +751,11 @@
         }
     }
 
+    private boolean isVisible(int visibility) {
+        return visibility == AccountManager.VISIBILITY_VISIBLE ||
+            visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
+    }
+
     /**
      * Updates visibility for given account name and package.
      *
@@ -803,8 +808,10 @@
                 if (notify) {
                     for (Entry<String, Integer> packageToVisibility : packagesToVisibility
                             .entrySet()) {
-                        if (shouldNotifyOnVisibilityChange(packageToVisibility.getValue(),
-                                resolveAccountVisibility(account, packageName, accounts))) {
+                        int oldVisibility = packageToVisibility.getValue();
+                        int currentVisibility =
+                            resolveAccountVisibility(account, packageName, accounts);
+                        if (isVisible(oldVisibility) != isVisible(currentVisibility)) {
                             notifyPackage(packageToVisibility.getKey(), accounts);
                         }
                     }
@@ -1181,8 +1188,7 @@
 
                             for (Entry<String, Integer> packageToVisibility :
                                     packagesToVisibility.entrySet()) {
-                                if (shouldNotifyOnVisibilityChange(packageToVisibility.getValue(),
-                                        AccountManager.VISIBILITY_NOT_VISIBLE)) {
+                                if (isVisible(packageToVisibility.getValue())) {
                                     notifyPackage(packageToVisibility.getKey(), accounts);
                                 }
                             }
@@ -1218,14 +1224,6 @@
         }
     }
 
-    private boolean shouldNotifyOnVisibilityChange(int oldVisibility, int newVisibility) {
-        boolean oldVisible = (oldVisibility == AccountManager.VISIBILITY_VISIBLE) ||
-            (oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
-        boolean newVisible = (newVisibility == AccountManager.VISIBILITY_VISIBLE) ||
-            (newVisibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
-        return oldVisible == newVisible;
-    }
-
     private SparseBooleanArray getUidsOfInstalledOrUpdatedPackagesAsUser(int userId) {
         // Get the UIDs of all apps that might have data on the device. We want
         // to preserve user data if the app might otherwise be storing data.
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index bad7091..c417484 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -813,7 +813,8 @@
             String title;
             String msg;
             String[] pkgs;
-            long oldestStartTime = System.currentTimeMillis(); // now
+            final long nowElapsed = SystemClock.elapsedRealtime();
+            long oldestStartTime = nowElapsed;
             if (active.size() == 1) {
                 intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                 intent.setData(Uri.fromParts("package", active.get(0).mPackageName, null));
@@ -846,8 +847,8 @@
                             .addExtras(notificationBundle)
                             .setSmallIcon(R.drawable.stat_sys_vitals)
                             .setOngoing(true)
-                            .setShowWhen(oldestStartTime > 0)
-                            .setWhen(oldestStartTime)
+                            .setShowWhen(oldestStartTime < nowElapsed)
+                            .setWhen(System.currentTimeMillis() - (nowElapsed - oldestStartTime))
                             .setColor(context.getColor(
                                     com.android.internal.R.color.system_notification_accent_color))
                             .setContentTitle(title)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f3ecfeb..c958313 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19158,10 +19158,11 @@
                     final Uri data = intent.getData();
                     final String ssp;
                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
-                        final ApplicationInfo aInfo =
-                                getPackageManagerInternalLocked().getApplicationInfo(
-                                        ssp,
-                                        userId);
+                        ApplicationInfo aInfo = null;
+                        try {
+                            aInfo = AppGlobals.getPackageManager()
+                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
+                        } catch (RemoteException ignore) {}
                         if (aInfo == null) {
                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
                                     + " ssp=" + ssp + " data=" + data);
@@ -24281,7 +24282,6 @@
     }
 
     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
-        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
             final ProcessRecord app = mLruProcesses.get(i);
@@ -24298,8 +24298,8 @@
                 final String packageName = app.pkgList.keyAt(j);
                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
                     try {
-                        final ApplicationInfo ai = packageManager.getApplicationInfo(
-                                packageName, app.userId);
+                        final ApplicationInfo ai = AppGlobals.getPackageManager()
+                                .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
                         if (ai != null) {
                             app.thread.scheduleApplicationInfoChanged(ai);
                         }
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 4b71cc1..3f825c5 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -859,23 +859,16 @@
                 ipServingMode = IControlsTethering.STATE_LOCAL_ONLY;
                 break;
             default:
-                // Resort to legacy "guessing" behaviour.
-                //
-                // When the AP comes up and we've been requested to tether it,
-                // do so. Otherwise, assume it's a local-only hotspot request.
-                //
-                // TODO: Once all AP broadcasts are known to include ifname and
-                // mode information delete this code path and log an error.
-                ipServingMode = mWifiTetherRequested
-                        ? IControlsTethering.STATE_TETHERED
-                        : IControlsTethering.STATE_LOCAL_ONLY;
-                break;
+                mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
+                return;
         }
 
         if (!TextUtils.isEmpty(ifname)) {
             changeInterfaceState(ifname, ipServingMode);
         } else {
-            tetherMatchingInterfaces(ipServingMode, ConnectivityManager.TETHERING_WIFI);
+            mLog.e(String.format(
+                   "Cannot enable IP serving in mode %s on missing interface name",
+                   ipServingMode));
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 6941193..e87d860 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -77,6 +77,9 @@
     public TetheringConfiguration(Context ctx) {
         tetherableUsbRegexs = ctx.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_usb_regexs);
+        // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
+        // us an interface name. Careful consideration needs to be given to
+        // implications for Settings and for provisioning checks.
         tetherableWifiRegexs = ctx.getResources().getStringArray(
                 com.android.internal.R.array.config_tether_wifi_regexs);
         tetherableBluetoothRegexs = ctx.getResources().getStringArray(
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 1504538..3ca65cd 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1858,7 +1858,7 @@
                     account.account.name, account.userId, account.account.type);
 
             pw.println("=======================================================================");
-            final PrintTable table = new PrintTable(12);
+            final PrintTable table = new PrintTable(13);
             table.set(0, 0,
                     "Authority", // 0
                     "Syncable",  // 1
@@ -1871,7 +1871,8 @@
                     "User",      // 8
                     "Tot",       // 9
                     "Time",      // 10
-                    "Last Sync" // 11
+                    "Last Sync", // 11
+                    "Etc"        // 12
             );
 
             final List<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> sorted =
@@ -1921,6 +1922,7 @@
                     }
                 }
 
+                row1 = row;
                 if (status.lastSuccessTime != 0) {
                     table.set(row1++, 11, SyncStorageEngine.SOURCES[status.lastSuccessSource]
                             + " " + "SUCCESS");
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 29f9f7c..4a5ce12 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -34,6 +34,7 @@
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
@@ -100,7 +101,6 @@
         private static final boolean DEBUG = false;
         private static final String TAG = "LauncherAppsService";
         private final Context mContext;
-        private final PackageManager mPm;
         private final UserManager mUm;
         private final ActivityManagerInternal mActivityManagerInternal;
         private final ShortcutServiceInternal mShortcutServiceInternal;
@@ -113,7 +113,6 @@
 
         public LauncherAppsImpl(Context context) {
             mContext = context;
-            mPm = mContext.getPackageManager();
             mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
             mActivityManagerInternal = Preconditions.checkNotNull(
                     LocalServices.getService(ActivityManagerInternal.class));
@@ -263,15 +262,17 @@
         void verifyCallingPackage(String callingPackage) {
             int packageUid = -1;
             try {
-                packageUid = mPm.getPackageUidAsUser(callingPackage,
+                packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                                 | PackageManager.MATCH_UNINSTALLED_PACKAGES,
                         UserHandle.getUserId(getCallingUid()));
-            } catch (NameNotFoundException e) {
+            } catch (RemoteException ignore) {
+            }
+            if (packageUid < 0) {
                 Log.e(TAG, "Package not found: " + callingPackage);
             }
-            if (packageUid != Binder.getCallingUid()) {
+            if (packageUid != injectBinderCallingUid()) {
                 throw new SecurityException("Calling package name mismatch");
             }
         }
@@ -315,13 +316,15 @@
                 return null;
             }
 
+            final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
-                IPackageManager pm = AppGlobals.getPackageManager();
-                return pm.getActivityInfo(component,
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                return pmInt.getActivityInfo(component,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -344,12 +347,15 @@
                 return null;
             }
 
+            final int callingUid = injectBinderCallingUid();
             long ident = injectClearCallingIdentity();
             try {
-                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent,
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
                 return new ParceledListSlice<>(apps);
             } finally {
                 injectRestoreCallingIdentity(ident);
@@ -390,13 +396,15 @@
                 return false;
             }
 
+            final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
-                IPackageManager pm = AppGlobals.getPackageManager();
-                PackageInfo info = pm.getPackageInfo(packageName,
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                PackageInfo info = pmInt.getPackageInfo(packageName,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
                 return info != null && info.applicationInfo.enabled;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -414,11 +422,13 @@
                 return null;
             }
 
+            final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
-                IPackageManager pm = AppGlobals.getPackageManager();
-                ApplicationInfo info = pm.getApplicationInfo(packageName, flags,
-                        user.getIdentifier());
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
+                        callingUid, user.getIdentifier());
                 return info;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -573,13 +583,15 @@
                 return false;
             }
 
+            final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
-                IPackageManager pm = AppGlobals.getPackageManager();
-                ActivityInfo info = pm.getActivityInfo(component,
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                ActivityInfo info = pmInt.getActivityInfo(component,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
                 return info != null;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -604,13 +616,15 @@
                     | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
             launchIntent.setPackage(component.getPackageName());
 
+            final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
-                IPackageManager pm = AppGlobals.getPackageManager();
-                ActivityInfo info = pm.getActivityInfo(component,
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                ActivityInfo info = pmInt.getActivityInfo(component,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
                 if (!info.exported) {
                     throw new SecurityException("Cannot launch non-exported components "
                             + component);
@@ -619,10 +633,10 @@
                 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
                 // as calling startActivityAsUser ignores the category and just
                 // resolves based on the component if present.
-                List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
+                List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
                         PackageManager.MATCH_DIRECT_BOOT_AWARE
                                 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        user.getIdentifier());
+                        callingUid, user.getIdentifier());
                 final int size = apps.size();
                 for (int i = 0; i < size; ++i) {
                     ActivityInfo activityInfo = apps.get(i).activityInfo;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index aad7df3..e62b107 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2186,12 +2186,12 @@
 
     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
             String[] grantedPermissions) {
-        SettingBase sb = (SettingBase) pkg.mExtras;
-        if (sb == null) {
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps == null) {
             return;
         }
 
-        PermissionsState permissionsState = sb.getPermissionsState();
+        PermissionsState permissionsState = ps.getPermissionsState();
 
         final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
                 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -3516,7 +3516,7 @@
      *     and {@code 0}</li>
      * <li>The calling application has the permission
      *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
-     * <li>[TODO] The calling application is the default launcher on the
+     * <li>The calling application is the default launcher on the
      *     system partition.</li>
      * </ol>
      */
@@ -3651,22 +3651,27 @@
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
         return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
-                flags, userId);
+                flags, Binder.getCallingUid(), userId);
     }
 
     @Override
     public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
             int flags, int userId) {
         return getPackageInfoInternal(versionedPackage.getPackageName(),
-                versionedPackage.getVersionCode(), flags, userId);
+                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
     }
 
+    /**
+     * Important: The provided filterCallingUid is used exclusively to filter out packages
+     * that can be seen based on user state. It's typically the original caller uid prior
+     * to clearing. Because it can only be provided by trusted code, it's value can be
+     * trusted and will be used as-is; unlike userId which will be validated by this method.
+     */
     private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
-            int flags, int userId) {
+            int flags, int filterCallingUid, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForPackage(flags, userId, packageName);
-        enforceCrossUserPermission(callingUid, userId,
+        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                 false /* requireFullPermission */, false /* checkShell */, "get package info");
 
         // reader
@@ -3678,10 +3683,10 @@
             if (matchFactoryOnly) {
                 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
                 if (ps != null) {
-                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                         return null;
                     }
-                    if (filterAppAccessLPr(ps, callingUid, userId)) {
+                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                         return null;
                     }
                     return generatePackageInfo(ps, flags, userId);
@@ -3696,10 +3701,10 @@
                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
             if (p != null) {
                 final PackageSetting ps = (PackageSetting) p.mExtras;
-                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                     return null;
                 }
-                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
+                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
                     return null;
                 }
                 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
@@ -3707,10 +3712,10 @@
             if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
                 final PackageSetting ps = mSettings.mPackages.get(packageName);
                 if (ps == null) return null;
-                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                     return null;
                 }
-                if (filterAppAccessLPr(ps, callingUid, userId)) {
+                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                     return null;
                 }
                 return generatePackageInfo(ps, flags, userId);
@@ -4071,14 +4076,14 @@
     }
 
     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
-            int uid, int userId) {
+            int filterCallingUid, int userId) {
         if (!sUserManager.exists(userId)) return null;
         PackageSetting ps = mSettings.mPackages.get(packageName);
         if (ps != null) {
-            if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
+            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                 return null;
             }
-            if (filterAppAccessLPr(ps, uid, userId)) {
+            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                 return null;
             }
             if (ps.pkg == null) {
@@ -4101,6 +4106,17 @@
 
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
+    }
+
+    /**
+     * Important: The provided filterCallingUid is used exclusively to filter out applications
+     * that can be seen based on user state. It's typically the original caller uid prior
+     * to clearing. Because it can only be provided by trusted code, it's value can be
+     * trusted and will be used as-is; unlike userId which will be validated by this method.
+     */
+    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+            int filterCallingUid, int userId) {
         if (!sUserManager.exists(userId)) return null;
         flags = updateFlagsForApplication(flags, userId, packageName);
         enforceCrossUserPermission(Binder.getCallingUid(), userId,
@@ -4119,10 +4135,10 @@
             if (p != null) {
                 PackageSetting ps = mSettings.mPackages.get(packageName);
                 if (ps == null) return null;
-                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                     return null;
                 }
-                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
                     return null;
                 }
                 // Note: isEnabledLP() does not apply here - always return info
@@ -4140,7 +4156,7 @@
             if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
                 // Already generates the external package name
                 return generateApplicationInfoFromSettingsLPw(packageName,
-                        Binder.getCallingUid(), flags, userId);
+                        flags, filterCallingUid, userId);
             }
         }
         return null;
@@ -4570,10 +4586,20 @@
 
     @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
+    }
+
+    /**
+     * Important: The provided filterCallingUid is used exclusively to filter out activities
+     * that can be seen based on user state. It's typically the original caller uid prior
+     * to clearing. Because it can only be provided by trusted code, it's value can be
+     * trusted and will be used as-is; unlike userId which will be validated by this method.
+     */
+    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+            int filterCallingUid, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        final int callingUid = Binder.getCallingUid();
         flags = updateFlagsForComponent(flags, userId, component);
-        enforceCrossUserPermission(callingUid, userId,
+        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                 false /* requireFullPermission */, false /* checkShell */, "get activity info");
         synchronized (mPackages) {
             PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -4582,7 +4608,7 @@
             if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                 if (ps == null) return null;
-                if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, userId)) {
+                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
                     return null;
                 }
                 return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
@@ -4878,9 +4904,13 @@
         }
     }
 
-    private void updateSequenceNumberLP(String packageName, int[] userList) {
+    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
         for (int i = userList.length - 1; i >= 0; --i) {
             final int userId = userList[i];
+            // don't add instant app to the list of updates
+            if (pkgSetting.getInstantApp(userId)) {
+                continue;
+            }
             SparseArray<String> changedPackages = mChangedPackages.get(userId);
             if (changedPackages == null) {
                 changedPackages = new SparseArray<>();
@@ -4891,12 +4921,12 @@
                 sequenceNumbers = new HashMap<>();
                 mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
             }
-            final Integer sequenceNumber = sequenceNumbers.get(packageName);
+            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
             if (sequenceNumber != null) {
                 changedPackages.remove(sequenceNumber);
             }
-            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
-            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
+            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
+            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
         }
         mChangedPackagesSequenceNumber++;
     }
@@ -5338,7 +5368,7 @@
                 "grantRuntimePermission");
 
         final int uid;
-        final SettingBase sb;
+        final PackageSetting ps;
 
         synchronized (mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
@@ -5349,12 +5379,9 @@
             if (bp == null) {
                 throw new IllegalArgumentException("Unknown permission: " + name);
             }
-            sb = (SettingBase) pkg.mExtras;
-            if (sb == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-            if (sb instanceof PackageSetting
-                    && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
+            ps = (PackageSetting) pkg.mExtras;
+            if (ps == null
+                    || filterAppAccessLPr(ps, callingUid, userId)) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
 
@@ -5372,7 +5399,7 @@
 
             uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
 
-            final PermissionsState permissionsState = sb.getPermissionsState();
+            final PermissionsState permissionsState = ps.getPermissionsState();
 
             final int flags = permissionsState.getPermissionFlags(name, userId);
             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5394,7 +5421,6 @@
                 return;
             }
 
-            final PackageSetting ps = mSettings.mPackages.get(packageName);
             if (ps.getInstantApp(userId) && !bp.isInstant()) {
                 throw new SecurityException("Cannot grant non-ephemeral permission"
                         + name + " for package " + packageName);
@@ -5478,7 +5504,11 @@
             if (pkg == null) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
-
+            final PackageSetting ps = (PackageSetting) pkg.mExtras;
+            if (ps == null
+                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
             final BasePermission bp = mSettings.mPermissions.get(name);
             if (bp == null) {
                 throw new IllegalArgumentException("Unknown permission: " + name);
@@ -5496,12 +5526,7 @@
                 return;
             }
 
-            SettingBase sb = (SettingBase) pkg.mExtras;
-            if (sb == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-
-            final PermissionsState permissionsState = sb.getPermissionsState();
+            final PermissionsState permissionsState = ps.getPermissionsState();
 
             final int flags = permissionsState.getPermissionFlags(name, userId);
             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5654,15 +5679,12 @@
             if (bp == null) {
                 return 0;
             }
-            final SettingBase sb = (SettingBase) pkg.mExtras;
-            if (sb == null) {
+            final PackageSetting ps = (PackageSetting) pkg.mExtras;
+            if (ps == null
+                    || filterAppAccessLPr(ps, callingUid, userId)) {
                 return 0;
             }
-            if (sb instanceof PackageSetting
-                    && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
-                return 0;
-            }
-            PermissionsState permissionsState = sb.getPermissionsState();
+            PermissionsState permissionsState = ps.getPermissionsState();
             return permissionsState.getPermissionFlags(name, userId);
         }
     }
@@ -5676,7 +5698,8 @@
 
         enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
 
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId,
                 true /* requireFullPermission */, true /* checkShell */,
                 "updatePermissionFlags");
 
@@ -5694,18 +5717,18 @@
             if (pkg == null) {
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
+            final PackageSetting ps = (PackageSetting) pkg.mExtras;
+            if (ps == null
+                    || filterAppAccessLPr(ps, callingUid, userId)) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
 
             final BasePermission bp = mSettings.mPermissions.get(name);
             if (bp == null) {
                 throw new IllegalArgumentException("Unknown permission: " + name);
             }
 
-            SettingBase sb = (SettingBase) pkg.mExtras;
-            if (sb == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-
-            PermissionsState permissionsState = sb.getPermissionsState();
+            PermissionsState permissionsState = ps.getPermissionsState();
 
             boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
 
@@ -5749,11 +5772,11 @@
             final int packageCount = mPackages.size();
             for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
                 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
-                SettingBase sb = (SettingBase) pkg.mExtras;
-                if (sb == null) {
+                final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                if (ps == null) {
                     continue;
                 }
-                PermissionsState permissionsState = sb.getPermissionsState();
+                PermissionsState permissionsState = ps.getPermissionsState();
                 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
                         userId, flagMask, flagValues);
             }
@@ -6303,7 +6326,7 @@
 
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
-                    flags, userId, resolveForStart);
+                    flags, callingUid, userId, resolveForStart);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             final ResolveInfo bestChoice =
@@ -6847,15 +6870,16 @@
 
     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
             String resolvedType, int flags, int userId) {
-        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
+        return queryIntentActivitiesInternal(
+                intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
     }
 
     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, int userId, boolean resolveForStart) {
+            String resolvedType, int flags, int filterCallingUid, int userId,
+            boolean resolveForStart) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
-        final int callingUid = Binder.getCallingUid();
-        final String instantAppPkgName = getInstantAppPackageName(callingUid);
-        enforceCrossUserPermission(callingUid, userId,
+        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
+        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                 false /* requireFullPermission */, false /* checkShell */,
                 "query intent activities");
         final String pkgName = intent.getPackage();
@@ -6867,7 +6891,7 @@
             }
         }
 
-        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
+        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
                 comp != null || pkgName != null /*onlyExposedExplicitly*/);
         if (comp != null) {
             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
@@ -9546,6 +9570,8 @@
     public void reconcileSecondaryDexFiles(String packageName) {
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return;
+        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+            return;
         }
         mDexManager.reconcileSecondaryDexFiles(packageName);
     }
@@ -14323,8 +14349,8 @@
             int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         PackageSetting pkgSetting;
-        final int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId,
+        final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId,
                 true /* requireFullPermission */, true /* checkShell */,
                 "setApplicationHiddenSetting for user " + userId);
 
@@ -14343,6 +14369,9 @@
                 if (pkgSetting == null) {
                     return false;
                 }
+                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
+                    return false;
+                }
                 // Do not allow "android" is being disabled
                 if ("android".equals(packageName)) {
                     Slog.w(TAG, "Cannot hide package: android");
@@ -14359,7 +14388,7 @@
                     return false;
                 }
                 // Only allow protected packages to hide themselves.
-                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
+                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
                         && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
                     Slog.w(TAG, "Not hiding protected package: " + packageName);
                     return false;
@@ -14476,6 +14505,20 @@
                 if (pkgSetting == null) {
                     return PackageManager.INSTALL_FAILED_INVALID_URI;
                 }
+                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
+                    // only allow the existing package to be used if it's installed as a full
+                    // application for at least one user
+                    boolean installAllowed = false;
+                    for (int checkUserId : sUserManager.getUserIds()) {
+                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
+                        if (installAllowed) {
+                            break;
+                        }
+                    }
+                    if (!installAllowed) {
+                        return PackageManager.INSTALL_FAILED_INVALID_URI;
+                    }
+                }
                 if (!pkgSetting.getInstalled(userId)) {
                     pkgSetting.setInstalled(true, userId);
                     pkgSetting.setHidden(false, userId);
@@ -14499,7 +14542,7 @@
                 }
                 sendPackageAddedForUser(packageName, pkgSetting, userId);
                 synchronized (mPackages) {
-                    updateSequenceNumberLP(packageName, new int[]{ userId });
+                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
                 }
             }
         } finally {
@@ -14545,7 +14588,8 @@
     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
             int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId,
+        final int callingUid = Binder.getCallingUid();
+        enforceCrossUserPermission(callingUid, userId,
                 true /* requireFullPermission */, true /* checkShell */,
                 "setPackagesSuspended for user " + userId);
 
@@ -14566,7 +14610,8 @@
                 final int appId;
                 synchronized (mPackages) {
                     final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
-                    if (pkgSetting == null) {
+                    if (pkgSetting == null
+                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
                         Slog.w(TAG, "Could not find package setting for package \"" + packageName
                                 + "\". Skipping suspending/un-suspending.");
                         unactionedPackages.add(packageName);
@@ -14976,6 +15021,10 @@
 
         boolean result = false;
         synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
+                return false;
+            }
             result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
         }
         if (result) {
@@ -15076,7 +15125,9 @@
         // writer
         synchronized (mPackages) {
             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
-            if (targetPackageSetting == null) {
+            if (targetPackageSetting == null
+                    || filterAppAccessLPr(
+                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
             }
 
@@ -15157,7 +15208,9 @@
             if (ps == null) {
                 throw new IllegalArgumentException("Unknown target package " + packageName);
             }
-
+            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
+                throw new IllegalArgumentException("Unknown target package " + packageName);
+            }
             if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
                 throw new IllegalArgumentException("Calling package " + callerPackageName
                         + " is not installer for " + packageName);
@@ -18178,7 +18231,7 @@
             }
 
             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                updateSequenceNumberLP(pkgName, res.newUsers);
+                updateSequenceNumberLP(ps, res.newUsers);
                 updateInstantAppInstallerLocked(pkgName);
             }
         }
@@ -18404,8 +18457,7 @@
         final int callingUid = Binder.getCallingUid();
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.DELETE_PACKAGES, null);
-        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.ACCESS_INSTANT_APPS);
+        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
         Preconditions.checkNotNull(versionedPackage);
         Preconditions.checkNotNull(observer);
         Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
@@ -18476,7 +18528,7 @@
                     final boolean targetIsInstantApp =
                             ps.getInstantApp(UserHandle.getUserId(callingUid));
                     doDeletePackage = !targetIsInstantApp
-                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
+                            || canViewInstantApps;
                 }
                 if (doDeletePackage) {
                     if (!deleteAllUsers) {
@@ -18779,7 +18831,7 @@
                     if (pkg != null) {
                         mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
                     }
-                    updateSequenceNumberLP(packageName, info.removedUsers);
+                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
                     updateInstantAppInstallerLocked(packageName);
                 }
             }
@@ -21135,7 +21187,8 @@
         // Limit who can change which apps
         if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
             // Don't allow apps that don't have permission to modify other apps
-            if (!allowedByPermission) {
+            if (!allowedByPermission
+                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
                 throw new SecurityException(
                         "Attempt to change component state; "
                         + "pid=" + Binder.getCallingPid()
@@ -21222,7 +21275,7 @@
                 }
             }
             scheduleWritePackageRestrictionsLocked(userId);
-            updateSequenceNumberLP(packageName, new int[] { userId });
+            updateSequenceNumberLP(pkgSetting, new int[] { userId });
             final long callingId = Binder.clearCallingIdentity();
             try {
                 updateInstantAppInstallerLocked(packageName);
@@ -21319,8 +21372,10 @@
                 true /* requireFullPermission */, true /* checkShell */, "stop package");
         // writer
         synchronized (mPackages) {
-            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
-                    allowedByPermission, callingUid, userId)) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (!filterAppAccessLPr(ps, callingUid, userId)
+                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
+                            allowedByPermission, callingUid, userId)) {
                 scheduleWritePackageRestrictionsLocked(userId);
             }
         }
@@ -21328,11 +21383,16 @@
 
     @Override
     public String getInstallerPackageName(String packageName) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return null;
         }
         // reader
         synchronized (mPackages) {
+            final PackageSetting ps = mSettings.mPackages.get(packageName);
+            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+                return null;
+            }
             return mSettings.getInstallerPackageNameLPr(packageName);
         }
     }
@@ -24081,7 +24141,8 @@
 
     @Override
     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return false;
         }
         if (packageName == null || ks == null) {
@@ -24089,7 +24150,9 @@
         }
         synchronized(mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
-            if (pkg == null) {
+            if (pkg == null
+                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
+                            UserHandle.getUserId(callingUid))) {
                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
@@ -24104,7 +24167,8 @@
 
     @Override
     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+        final int callingUid = Binder.getCallingUid();
+        if (getInstantAppPackageName(callingUid) != null) {
             return false;
         }
         if (packageName == null || ks == null) {
@@ -24112,7 +24176,9 @@
         }
         synchronized(mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
-            if (pkg == null) {
+            if (pkg == null
+                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
+                            UserHandle.getUserId(callingUid))) {
                 Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                 throw new IllegalArgumentException("Unknown package: " + packageName);
             }
@@ -24429,8 +24495,34 @@
         }
 
         @Override
-        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
-            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
+        public PackageInfo getPackageInfo(
+                String packageName, int flags, int filterCallingUid, int userId) {
+            return PackageManagerService.this
+                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
+                            flags, filterCallingUid, userId);
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo(
+                String packageName, int flags, int filterCallingUid, int userId) {
+            return PackageManagerService.this
+                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
+        }
+
+        @Override
+        public ActivityInfo getActivityInfo(
+                ComponentName component, int flags, int filterCallingUid, int userId) {
+            return PackageManagerService.this
+                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
+        }
+
+        @Override
+        public List<ResolveInfo> queryIntentActivities(
+                Intent intent, int flags, int filterCallingUid, int userId) {
+            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
+            return PackageManagerService.this
+                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
+                            userId, false /*resolveForStart*/);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
index 7d53310..3e5e57b 100644
--- a/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
+++ b/services/core/java/com/android/server/policy/AccessibilityShortcutController.java
@@ -233,7 +233,7 @@
 
     private AccessibilityServiceInfo getInfoForTargetService() {
         final String currentShortcutServiceString = getTargetServiceComponentNameString(
-                mContext, UserHandle.myUserId());
+                mContext, UserHandle.USER_CURRENT);
         if (currentShortcutServiceString == null) {
             return null;
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a8e0d76..ccc8f63 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1162,8 +1162,6 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
                 Configuration.ORIENTATION_LANDSCAPE;
-        config.setRotation(displayInfo.rotation);
-
         config.screenWidthDp =
                 (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
                         config.uiMode, mDisplayId) / mDisplayMetrics.density);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fb500bc..233e75b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -858,20 +858,14 @@
         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!!!");
+                        + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
+                        + Debug.getCallers(10));
             }
             if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
                 mScreenBrightness = w.mAttrs.screenBrightness;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 3a116bb..551e3bf 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -102,6 +102,8 @@
             | FLAG_SCALED
             | FLAG_SECURE;
 
+    private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+
     private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
     private static final int MSG_REPORT_DRAW = 0;
     private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s";
@@ -160,7 +162,8 @@
             layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
                     | FLAG_NOT_FOCUSABLE
                     | FLAG_NOT_TOUCHABLE;
-            layoutParams.privateFlags = PRIVATE_FLAG_TASK_SNAPSHOT;
+            layoutParams.privateFlags = PRIVATE_FLAG_TASK_SNAPSHOT
+                    | (windowPrivateFlags & PRIVATE_FLAG_INHERITS);
             layoutParams.token = token.token;
             layoutParams.width = LayoutParams.MATCH_PARENT;
             layoutParams.height = LayoutParams.MATCH_PARENT;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index eff8ed9..39878cc 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -109,6 +109,7 @@
 
     /** Application tokens that are exiting, but still on screen for animations. */
     final AppTokenList mExitingAppTokens = new AppTokenList();
+    final AppTokenList mTmpAppTokens = new AppTokenList();
 
     /** Detach this stack from its display when animation completes. */
     // TODO: maybe tie this to WindowContainer#removeChild some how...
@@ -1626,9 +1627,14 @@
 
         // TODO: Why aren't we just using the loop above for this? mAppAnimator.animating isn't set
         // below but is set in the loop above. See if it really matters...
-        final int exitingCount = mExitingAppTokens.size();
-        for (int i = 0; i < exitingCount; i++) {
-            final AppWindowAnimator appAnimator = mExitingAppTokens.get(i).mAppAnimator;
+
+        // Clear before using.
+        mTmpAppTokens.clear();
+        // We copy the list as things can be removed from the exiting token list while we are
+        // processing.
+        mTmpAppTokens.addAll(mExitingAppTokens);
+        for (int i = 0; i < mTmpAppTokens.size(); i++) {
+            final AppWindowAnimator appAnimator = mTmpAppTokens.get(i).mAppAnimator;
             appAnimator.wasAnimating = appAnimator.animating;
             if (appAnimator.stepAnimationLocked(currentTime)) {
                 mService.mAnimator.setAnimating(true);
@@ -1641,6 +1647,8 @@
                         "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
             }
         }
+        // Clear to avoid holding reference to tokens.
+        mTmpAppTokens.clear();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 4da9c06..6d5673e 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 = true;
+    static final boolean DEBUG_KEEP_SCREEN_ON = false;
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4b066c0..e5af9d2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -158,6 +158,7 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.text.format.DateUtils;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -3600,8 +3601,16 @@
     // only allow disables from pids which have count on, etc.
     @Override
     public void showStrictModeViolation(boolean on) {
-        int pid = Binder.getCallingPid();
-        mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
+        final int pid = Binder.getCallingPid();
+        if (on) {
+            // Show the visualization, and enqueue a second message to tear it
+            // down if we don't hear back from the app.
+            mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid));
+            mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid),
+                    DateUtils.SECOND_IN_MILLIS);
+        } else {
+            mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid));
+        }
     }
 
     private void showStrictModeViolation(int arg, int pid) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1d08c2e..f74948f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2231,14 +2231,15 @@
             mWinAnimator.applyEnterAnimationLocked();
         }
 
-        // always report back the new configuration
-        final Configuration globalConfig = mService.mRoot.getConfiguration();
-        final Configuration overrideConfig = getMergedOverrideConfiguration();
-        mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
-        if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
-                + " reporting new global config: " + globalConfig
-                + " merged override config: " + overrideConfig);
-        mLastReportedConfiguration.setTo(getConfiguration());
+        if (isConfigChanged()) {
+            final Configuration globalConfig = mService.mRoot.getConfiguration();
+            final Configuration overrideConfig = getMergedOverrideConfiguration();
+            mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
+            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
+                    + " visible with new global config: " + globalConfig
+                    + " merged override config: " + overrideConfig);
+            mLastReportedConfiguration.setTo(getConfiguration());
+        }
     }
 
     void adjustStartingWindowFlags() {
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 50d7f04..281223e 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -219,10 +219,7 @@
         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
-    private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception {
-        if (!ifnameKnown) {
-            verify(mNMService, times(1)).listInterfaces();
-        }
+    private void verifyInterfaceServingModeStarted() throws Exception {
         verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
         verify(mNMService, times(1))
                 .setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
@@ -238,21 +235,36 @@
         mIntents.remove(bcast);
     }
 
-    public void workingLocalOnlyHotspot(boolean enrichedApBroadcast) throws Exception {
+    @Test
+    public void failingLocalOnlyHotspotLegacyApBroadcast() throws Exception {
         when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
 
         // Emulate externally-visible WifiManager effects, causing the
         // per-interface state machine to start up, and telling us that
         // hotspot mode is to be started.
         mTethering.interfaceStatusChanged(mTestIfname, true);
-        if (enrichedApBroadcast) {
-            sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY);
-        } else {
-            sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
-        }
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
         mLooper.dispatchAll();
 
-        verifyInterfaceServingModeStarted(enrichedApBroadcast);
+        verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+        verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+        verifyNoMoreInteractions(mWifiManager);
+    }
+
+    @Test
+    public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception {
+        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+
+        // Emulate externally-visible WifiManager effects, causing the
+        // per-interface state machine to start up, and telling us that
+        // hotspot mode is to be started.
+        mTethering.interfaceStatusChanged(mTestIfname, true);
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY);
+        mLooper.dispatchAll();
+
+        verifyInterfaceServingModeStarted();
         verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
         verify(mNMService, times(1)).setIpForwardingEnabled(true);
         verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -293,16 +305,7 @@
     }
 
     @Test
-    public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception {
-        workingLocalOnlyHotspot(false);
-    }
-
-    @Test
-    public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception {
-        workingLocalOnlyHotspot(true);
-    }
-
-    public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception {
+    public void failingWifiTetheringLegacyApBroadcast() throws Exception {
         when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
 
@@ -318,14 +321,37 @@
         // per-interface state machine to start up, and telling us that
         // tethering mode is to be started.
         mTethering.interfaceStatusChanged(mTestIfname, true);
-        if (enrichedApBroadcast) {
-            sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
-        } else {
-            sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
-        }
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
         mLooper.dispatchAll();
 
-        verifyInterfaceServingModeStarted(enrichedApBroadcast);
+        verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+        verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+        verifyNoMoreInteractions(mWifiManager);
+    }
+
+    @Test
+    public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
+        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+        when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
+
+        // Emulate pressing the WiFi tethering button.
+        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+        mLooper.dispatchAll();
+        verify(mWifiManager, times(1)).startSoftAp(null);
+        verifyNoMoreInteractions(mWifiManager);
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+
+        // Emulate externally-visible WifiManager effects, causing the
+        // per-interface state machine to start up, and telling us that
+        // tethering mode is to be started.
+        mTethering.interfaceStatusChanged(mTestIfname, true);
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
+        mLooper.dispatchAll();
+
+        verifyInterfaceServingModeStarted();
         verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
         verify(mNMService, times(1)).setIpForwardingEnabled(true);
         verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -387,16 +413,6 @@
     }
 
     @Test
-    public void workingWifiTetheringLegacyApBroadcast() throws Exception {
-        workingWifiTethering(false);
-    }
-
-    @Test
-    public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
-        workingWifiTethering(true);
-    }
-
-    @Test
     public void failureEnablingIpForwarding() throws Exception {
         when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
@@ -414,11 +430,9 @@
         // per-interface state machine to start up, and telling us that
         // tethering mode is to be started.
         mTethering.interfaceStatusChanged(mTestIfname, true);
-        sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
+        sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
         mLooper.dispatchAll();
 
-        // Activity caused by test_wlan0 becoming available.
-        verify(mNMService, times(1)).listInterfaces();
         // We verify get/set called twice here: once for setup and once during
         // teardown because all events happen over the course of the single
         // dispatchAll() above.