Merge "Part of global strings change from cellular —> mobile." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index b51ea54..8a25ab4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12599,7 +12599,6 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
-    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12852,8 +12851,6 @@
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
     method public void getColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -12994,8 +12991,6 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13068,15 +13063,11 @@
     ctor public LightingColorFilter(int, int);
     method public int getColorAdd();
     method public int getColorMultiply();
-    method public void setColorAdd(int);
-    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -13586,10 +13577,6 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
-    method public int getColor();
-    method public android.graphics.PorterDuff.Mode getMode();
-    method public void setColor(int);
-    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -13599,8 +13586,6 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -13785,8 +13770,6 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
-    method public void set(float, float, int[], float[]);
-    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -37129,6 +37112,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -37141,9 +37125,9 @@
     ctor public SaveInfo.Builder(int, android.view.autofill.AutofillId[]);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
+    method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
-    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index dc4c21f..8749179 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13373,7 +13373,6 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
-    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -13626,8 +13625,6 @@
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
     method public void getColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13768,8 +13765,6 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13842,15 +13837,11 @@
     ctor public LightingColorFilter(int, int);
     method public int getColorAdd();
     method public int getColorMultiply();
-    method public void setColorAdd(int);
-    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -14360,10 +14351,6 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
-    method public int getColor();
-    method public android.graphics.PorterDuff.Mode getMode();
-    method public void setColor(int);
-    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -14373,8 +14360,6 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -14559,8 +14544,6 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
-    method public void set(float, float, int[], float[]);
-    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -40241,6 +40224,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -40253,9 +40237,9 @@
     ctor public SaveInfo.Builder(int, android.view.autofill.AutofillId[]);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
+    method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
-    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 88adb6e..7a73d4b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12641,7 +12641,6 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
-    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12894,8 +12893,6 @@
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
     method public void getColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrix(android.graphics.ColorMatrix);
-    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13036,8 +13033,6 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
-    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13110,15 +13105,11 @@
     ctor public LightingColorFilter(int, int);
     method public int getColorAdd();
     method public int getColorMultiply();
-    method public void setColorAdd(int);
-    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -13628,10 +13619,6 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
-    method public int getColor();
-    method public android.graphics.PorterDuff.Mode getMode();
-    method public void setColor(int);
-    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -13641,8 +13628,6 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
-    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -13827,8 +13812,6 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
-    method public void set(float, float, int[], float[]);
-    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -37282,6 +37265,7 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
+    field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -37294,9 +37278,9 @@
     ctor public SaveInfo.Builder(int, android.view.autofill.AutofillId[]);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
+    method public android.service.autofill.SaveInfo.Builder setFlags(int);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
-    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 666ba60..178b967 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -54,6 +54,7 @@
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.provider.Settings;
 import android.util.AndroidException;
 import android.util.Log;
 
@@ -3983,6 +3984,8 @@
      * <p>If no packages have been changed, returns <code>null</code>.
      * <p>The sequence number starts at <code>0</code> and is
      * reset every boot.
+     * @param sequenceNumber The first sequence number for which to retrieve package changes.
+     * @see Settings.Global#BOOT_COUNT
      */
     public abstract @Nullable ChangedPackages getChangedPackages(
             @IntRange(from=0) int sequenceNumber);
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 7f960df..915d4f7 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -153,13 +153,27 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface SaveDataType{}
 
+    /**
+     * Usually {@link AutofillService#onSaveRequest(AssistStructure, Bundle, SaveCallback)}
+     * is called once the activity finishes. If this flag is set it is called once all saved views
+     * become invisible.
+     */
+    public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 0x1;
+
+    /** @hide */
+    @IntDef(
+            flag = true,
+            value = {FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface SaveInfoFlags{}
+
     private final @SaveDataType int mType;
     private final CharSequence mNegativeActionTitle;
     private final IntentSender mNegativeActionListener;
     private final AutofillId[] mRequiredIds;
     private final AutofillId[] mOptionalIds;
     private final CharSequence mDescription;
-    private final boolean mSaveOnAllViewsInvisible;
+    private final int mFlags;
 
     private SaveInfo(Builder builder) {
         mType = builder.mType;
@@ -168,7 +182,7 @@
         mRequiredIds = builder.mRequiredIds;
         mOptionalIds = builder.mOptionalIds;
         mDescription = builder.mDescription;
-        mSaveOnAllViewsInvisible = builder.mSaveOnAllViewsInvisible;
+        mFlags = builder.mFlags;
     }
 
     /** @hide */
@@ -197,8 +211,8 @@
     }
 
     /** @hide */
-    public boolean saveOnAllViewsInvisible() {
-        return mSaveOnAllViewsInvisible;
+    public @SaveInfoFlags int getFlags() {
+        return mFlags;
     }
 
     /** @hide */
@@ -219,7 +233,7 @@
         private AutofillId[] mOptionalIds;
         private CharSequence mDescription;
         private boolean mDestroyed;
-        private boolean mSaveOnAllViewsInvisible;
+        private int mFlags;
 
         /**
          * Creates a new builder.
@@ -268,17 +282,15 @@
         }
 
         /**
-         * Usually {@link AutofillService#onSaveRequest(AssistStructure, Bundle, SaveCallback)}
-         * is called once the activity finishes. If this property is set it is called once all
-         * autofillable or saved views become invisible.
+         * Set flags changing the save behavior.
          *
-         * @param saveOnAllViewsInvisible Set to {@code true} if the data should be saved once
-         *                                all the views become invisible.
+         * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} or 0.
          * @return This builder.
          */
-        public @NonNull Builder setSaveOnAllViewsInvisible(boolean saveOnAllViewsInvisible) {
+        public @NonNull Builder setFlags(@SaveInfoFlags int flags) {
             throwIfDestroyed();
-            mSaveOnAllViewsInvisible = saveOnAllViewsInvisible;
+
+            mFlags = Preconditions.checkFlagsArgument(flags, FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE);
             return this;
         }
 
@@ -378,7 +390,7 @@
                 .append(", requiredIds=").append(Arrays.toString(mRequiredIds))
                 .append(", optionalIds=").append(Arrays.toString(mOptionalIds))
                 .append(", description=").append(mDescription)
-                .append(", saveOnNoVisibleTrackedViews=").append(mSaveOnAllViewsInvisible)
+                .append(", mFlags=").append(mFlags)
                 .append("]").toString();
     }
 
@@ -399,7 +411,7 @@
         parcel.writeParcelable(mNegativeActionListener, flags);
         parcel.writeParcelableArray(mOptionalIds, flags);
         parcel.writeCharSequence(mDescription);
-        parcel.writeBoolean(mSaveOnAllViewsInvisible);
+        parcel.writeInt(mFlags);
     }
 
     public static final Parcelable.Creator<SaveInfo> CREATOR = new Parcelable.Creator<SaveInfo>() {
@@ -413,7 +425,7 @@
             builder.setNegativeAction(parcel.readCharSequence(), parcel.readParcelable(null));
             builder.setOptionalIds(parcel.readParcelableArray(null, AutofillId.class));
             builder.setDescription(parcel.readCharSequence());
-            builder.setSaveOnAllViewsInvisible(parcel.readBoolean());
+            builder.setFlags(parcel.readInt());
             return builder.build();
         }
 
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index f47c355..1ccf16a 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -127,20 +127,23 @@
         if (focused == null || focused == root) {
             return root;
         }
-        ViewParent effective = focused.getParent();
+        ViewGroup effective = null;
+        ViewParent nextParent = focused.getParent();
         do {
-            if (effective == root) {
-                return root;
+            if (nextParent == root) {
+                return effective != null ? effective : root;
             }
-            ViewGroup vg = (ViewGroup) effective;
+            ViewGroup vg = (ViewGroup) nextParent;
             if (vg.getTouchscreenBlocksFocus()
                     && focused.getContext().getPackageManager().hasSystemFeature(
                             PackageManager.FEATURE_TOUCHSCREEN)
                     && vg.isKeyboardNavigationCluster()) {
-                return vg;
+                // Don't stop and return here because the cluster could be nested and we only
+                // care about the top-most one.
+                effective = vg;
             }
-            effective = effective.getParent();
-        } while (effective != null);
+            nextParent = nextParent.getParent();
+        } while (nextParent instanceof ViewGroup);
         return root;
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7d2d77e..928e3659 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9768,6 +9768,25 @@
     }
 
     /**
+     * Searches up the view hierarchy to find the top-most cluster. All deeper/nested clusters
+     * will be ignored.
+     *
+     * @return the keyboard navigation cluster that this view is in (can be this view)
+     *         or {@code null} if not in one
+     */
+    View findKeyboardNavigationCluster() {
+        if (mParent instanceof View) {
+            View cluster = ((View) mParent).findKeyboardNavigationCluster();
+            if (cluster != null) {
+                return cluster;
+            } else if (isKeyboardNavigationCluster()) {
+                return this;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Set whether this view is a root of a keyboard navigation cluster.
      *
      * @param isCluster If true, this view is a root of a cluster.
@@ -9789,9 +9808,20 @@
      *
      * @hide
      */
-    public void setFocusedInCluster() {
-        if (mParent instanceof ViewGroup) {
-            ((ViewGroup) mParent).setFocusInCluster(this);
+    public final void setFocusedInCluster() {
+        View top = findKeyboardNavigationCluster();
+        if (top == this) {
+            return;
+        }
+        ViewParent parent = mParent;
+        View child = this;
+        while (parent instanceof ViewGroup) {
+            ((ViewGroup) parent).setFocusedInCluster(child);
+            if (parent == top) {
+                return;
+            }
+            child = (View) parent;
+            parent = parent.getParent();
         }
     }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f9eb25d..d4000113 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -807,33 +807,27 @@
         return mDefaultFocus != null || super.hasDefaultFocus();
     }
 
-    void setFocusInCluster(View child) {
-        // Stop at the root of the cluster
-        if (child.isKeyboardNavigationCluster()) {
-            return;
-        }
-
+    void setFocusedInCluster(View child) {
         mFocusedInCluster = child;
-
-        if (mParent instanceof ViewGroup) {
-            ((ViewGroup) mParent).setFocusInCluster(this);
-        }
     }
 
-    void clearFocusInCluster(View child) {
+    /**
+     * Removes {@code child} (and associated focusedInCluster chain) from the cluster containing
+     * it.
+     * <br>
+     * This is intended to be run on {@code child}'s immediate parent. This is necessary because
+     * the chain is sometimes cleared after {@code child} has been detached.
+     */
+    void clearFocusedInCluster(View child) {
         if (mFocusedInCluster != child) {
             return;
         }
-
-        if (child.isKeyboardNavigationCluster()) {
-            return;
-        }
-
-        mFocusedInCluster = null;
-
-        if (mParent instanceof ViewGroup) {
-            ((ViewGroup) mParent).clearFocusInCluster(this);
-        }
+        View top = findKeyboardNavigationCluster();
+        ViewParent parent = this;
+        do {
+            ((ViewGroup) parent).mFocusedInCluster = null;
+            parent = parent.getParent();
+        } while (parent != top && parent instanceof ViewGroup);
     }
 
     @Override
@@ -1281,7 +1275,7 @@
     public void setTouchscreenBlocksFocus(boolean touchscreenBlocksFocus) {
         if (touchscreenBlocksFocus) {
             mGroupFlags |= FLAG_TOUCHSCREEN_BLOCKS_FOCUS;
-            if (hasFocus()) {
+            if (hasFocus() && !isKeyboardNavigationCluster()) {
                 final View focusedChild = getDeepestFocusedChild();
                 if (!focusedChild.isFocusableInTouchMode()) {
                     final View newFocus = focusSearch(FOCUS_FORWARD);
@@ -1316,7 +1310,8 @@
         // cluster, focus is free to move around within it.
         return getTouchscreenBlocksFocus() &&
                 mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
-                && (!hasFocus() || !isKeyboardNavigationCluster());
+                && !(isKeyboardNavigationCluster()
+                        && (hasFocus() || (findKeyboardNavigationCluster() != this)));
     }
 
     @Override
@@ -3217,8 +3212,7 @@
     }
 
     private boolean restoreFocusInClusterInternal(@FocusRealDirection int direction) {
-        if (mFocusedInCluster != null && !mFocusedInCluster.isKeyboardNavigationCluster()
-                && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS
+        if (mFocusedInCluster != null && getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS
                 && (mFocusedInCluster.mViewFlags & VISIBILITY_MASK) == VISIBLE
                 && mFocusedInCluster.restoreFocusInCluster(direction)) {
             return true;
@@ -5182,7 +5176,7 @@
             clearChildFocus = true;
         }
         if (view == mFocusedInCluster) {
-            clearFocusInCluster(view);
+            clearFocusedInCluster(view);
         }
 
         view.clearAccessibilityFocus();
@@ -5302,7 +5296,7 @@
                 clearDefaultFocus = view;
             }
             if (view == mFocusedInCluster) {
-                clearFocusInCluster(view);
+                clearFocusedInCluster(view);
             }
 
             view.clearAccessibilityFocus();
@@ -5458,7 +5452,7 @@
             clearDefaultFocus(child);
         }
         if (child == mFocusedInCluster) {
-            clearFocusInCluster(child);
+            clearFocusedInCluster(child);
         }
 
         child.clearAccessibilityFocus();
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 7e6756e..5577f53 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -41,35 +41,16 @@
      * @param tileY The tiling mode for y to draw the bitmap in.
      */
     public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
-        set(bitmap, tileX, tileY);
+        this(bitmap, tileX.nativeInt, tileY.nativeInt);
     }
 
     private BitmapShader(Bitmap bitmap, int tileX, int tileY) {
-        setInternal(bitmap, tileX, tileY);
-    }
-
-    /**
-     * Reinitialize the BitmapShader's Bitmap and tile modes.
-     *
-     * @param bitmap The bitmap to use inside the shader
-     * @param tileX The tiling mode for x to draw the bitmap in.
-     * @param tileY The tiling mode for y to draw the bitmap in.
-     */
-    public void set(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
-        if (tileX == null || tileY == null) {
-            throw new IllegalArgumentException();
-        }
-        setInternal(bitmap, tileX.nativeInt, tileY.nativeInt);
-    }
-
-    private void setInternal(Bitmap bitmap, int tileX, int tileY) {
         if (bitmap == null) {
             throw new IllegalArgumentException("Bitmap must be non-null");
         }
         if (bitmap == mBitmap && tileX == mTileX && tileY == mTileY) {
             return;
         }
-        discardNativeInstance();
         mBitmap = bitmap;
         mTileX = tileX;
         mTileY = tileY;
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 61f6cc5..9201a2e 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -73,6 +73,8 @@
      * @see #getColorMatrix(ColorMatrix)
      * @see #setColorMatrixArray(float[])
      * @see ColorMatrix#reset()
+     *
+     * @hide
      */
     public void setColorMatrix(@Nullable ColorMatrix matrix) {
         discardNativeInstance();
@@ -99,6 +101,8 @@
      *
      * @throws ArrayIndexOutOfBoundsException if the specified array's
      *         length is < 20
+     *
+     * @hide
      */
     public void setColorMatrixArray(@Nullable float[] array) {
         // called '...Array' so that passing null isn't ambiguous
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 8438bf2..e107ea7 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -59,43 +59,10 @@
     }
 
     private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
-        setInternal(shaderA, shaderB, nativeMode);
-    }
-
-    /**
-     * Reinitialize the ComposeShader's component Shaders and blend mode.
-     *
-     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
-     * @param shaderB  The colors from this shader are seen as the "src" by the mode
-     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
-     */
-    public void set(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
-        setInternal(shaderA, shaderB, mode.porterDuffMode);
-    }
-
-    /**
-     * Reinitialize the ComposeShader's component Shaders and blend mode.
-     *
-     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
-     * @param shaderB  The colors from this shader are seen as the "src" by the mode
-     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
-     */
-    public void set(@NonNull Shader shaderA, @NonNull Shader shaderB,
-            @NonNull PorterDuff.Mode mode) {
-        setInternal(shaderA, shaderB, mode.nativeInt);
-    }
-
-    private void setInternal(Shader shaderA, Shader shaderB, int nativeMode) {
         if (shaderA == null || shaderB == null) {
             throw new IllegalArgumentException("Shader parameters must not be null");
         }
 
-        if (shaderA == mShaderA && shaderB == mShaderB && mPorterDuffMode == nativeMode) {
-            // no work to do...
-            return;
-        }
-
-        discardNativeInstance();
         mShaderA = shaderA;
         mShaderB = shaderB;
         mPorterDuffMode = nativeMode;
@@ -109,16 +76,6 @@
                 mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode);
     }
 
-    @Override
-    void verifyNativeInstance() {
-        if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
-                || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
-            // Child shader native instance has been updated,
-            // so our cached native instance is no longer valid - discard it
-            discardNativeInstance();
-        }
-    }
-
     /**
      * @hide
      */
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index b0c145b..1578ffb 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -57,8 +57,6 @@
     /**
      * Returns the RGB color used to multiply the source color when the
      * color filter is applied.
-     *
-     * @see #setColorMultiply(int)
      */
     @ColorInt
     public int getColorMultiply() {
@@ -71,6 +69,8 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorMultiply()
+     *
+     * @hide
      */
     public void setColorMultiply(@ColorInt int mul) {
         if (mMul != mul) {
@@ -82,8 +82,6 @@
     /**
      * Returns the RGB color that will be added to the source color
      * when the color filter is applied.
-     *
-     * @see #setColorAdd(int)
      */
     @ColorInt
     public int getColorAdd() {
@@ -96,6 +94,8 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorAdd()
+     *
+     * @hide
      */
     public void setColorAdd(@ColorInt int add) {
         if (mAdd != add) {
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 0e4cd0a..7139efe 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -57,7 +57,20 @@
     */
     public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
             @Nullable float positions[], @NonNull TileMode tile) {
-        set(x0, y0, x1, y1, colors, positions, tile);
+        if (colors.length < 2) {
+            throw new IllegalArgumentException("needs >= 2 number of colors");
+        }
+        if (positions != null && colors.length != positions.length) {
+            throw new IllegalArgumentException("color and position arrays must be of equal length");
+        }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mX0 = x0;
+        mY0 = y0;
+        mX1 = x1;
+        mY1 = y1;
+        mColors = colors.clone();
+        mPositions = positions != null ? positions.clone() : null;
+        mTileMode = tile;
     }
 
     /**
@@ -74,56 +87,6 @@
     public LinearGradient(float x0, float y0, float x1, float y1,
             @ColorInt int color0, @ColorInt int color1,
             @NonNull TileMode tile) {
-        set(x0, y0, x1, y1, color0, color1, tile);
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param x0           The x-coordinate for the start of the gradient line
-     * @param y0           The y-coordinate for the start of the gradient line
-     * @param x1           The x-coordinate for the end of the gradient line
-     * @param y1           The y-coordinate for the end of the gradient line
-     * @param colors       The colors to be distributed along the gradient line
-     * @param positions    May be null. The relative positions [0..1] of
-     *                     each corresponding color in the colors array. If this is null,
-     *                     the the colors are distributed evenly along the gradient line.
-     * @param  tile        The Shader tiling mode
-     */
-    public void set(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
-            @Nullable float positions[], @NonNull TileMode tile) {
-        if (colors.length < 2) {
-            throw new IllegalArgumentException("needs >= 2 number of colors");
-        }
-        if (positions != null && colors.length != positions.length) {
-            throw new IllegalArgumentException("color and position arrays must be of equal length");
-        }
-        discardNativeInstance();
-        mType = TYPE_COLORS_AND_POSITIONS;
-        mX0 = x0;
-        mY0 = y0;
-        mX1 = x1;
-        mY1 = y1;
-        mColors = colors.clone();
-        mPositions = positions != null ? positions.clone() : null;
-        mTileMode = tile;
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param x0       The x-coordinate for the start of the gradient line
-     * @param y0       The y-coordinate for the start of the gradient line
-     * @param x1       The x-coordinate for the end of the gradient line
-     * @param y1       The y-coordinate for the end of the gradient line
-     * @param color0   The color at the start of the gradient line.
-     * @param color1   The color at the end of the gradient line.
-     * @param tile     The Shader tiling mode
-    */
-    public void set(float x0, float y0, float x1, float y1,
-            @ColorInt int color0, @ColorInt int color1,
-            @NonNull TileMode tile) {
-        discardNativeInstance();
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mX0 = x0;
         mY0 = y0;
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index ccc6ead..01d5825 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -49,6 +49,8 @@
      *
      * @see Color
      * @see #setColor(int)
+     *
+     * @hide
      */
     @ColorInt
     public int getColor() {
@@ -64,6 +66,8 @@
      * @see Color
      * @see #getColor()
      * @see #getMode()
+     *
+     * @hide
      */
     public void setColor(@ColorInt int color) {
         if (mColor != color) {
@@ -78,6 +82,8 @@
      *
      * @see PorterDuff
      * @see #setMode(android.graphics.PorterDuff.Mode)
+     *
+     * @hide
      */
     public PorterDuff.Mode getMode() {
         return mMode;
@@ -90,6 +96,8 @@
      * @see PorterDuff
      * @see #getMode()
      * @see #getColor()
+     *
+     * @hide
      */
     public void setMode(@NonNull PorterDuff.Mode mode) {
         if (mode == null) {
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index ae8f7da..f4b1191 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -57,7 +57,22 @@
     public RadialGradient(float centerX, float centerY, float radius,
             @NonNull @ColorInt int colors[], @Nullable float stops[],
             @NonNull TileMode tileMode) {
-        set(centerX, centerY, radius, colors, stops, tileMode);
+        if (radius <= 0) {
+            throw new IllegalArgumentException("radius must be > 0");
+        }
+        if (colors.length < 2) {
+            throw new IllegalArgumentException("needs >= 2 number of colors");
+        }
+        if (stops != null && colors.length != stops.length) {
+            throw new IllegalArgumentException("color and position arrays must be of equal length");
+        }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mX = centerX;
+        mY = centerY;
+        mRadius = radius;
+        mColors = colors.clone();
+        mPositions = stops != null ? stops.clone() : null;
+        mTileMode = tileMode;
     }
 
     /**
@@ -72,59 +87,9 @@
      */
     public RadialGradient(float centerX, float centerY, float radius,
             @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
-        set(centerX, centerY, radius, centerColor, edgeColor, tileMode);
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param centerX  The x-coordinate of the center of the radius
-     * @param centerY  The y-coordinate of the center of the radius
-     * @param radius   Must be positive. The radius of the circle for this gradient.
-     * @param colors   The colors to be distributed between the center and edge of the circle
-     * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
-     *                 <code>1.0f</code>. The relative position of each corresponding color in
-     *                 the colors array. If <code>null</code>, colors are distributed evenly
-     *                 between the center and edge of the circle.
-     * @param tileMode The Shader tiling mode
-     */
-    public void set(float centerX, float centerY, float radius,
-            @NonNull @ColorInt int colors[], @Nullable float stops[], @NonNull TileMode tileMode) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
-        if (colors.length < 2) {
-            throw new IllegalArgumentException("needs >= 2 number of colors");
-        }
-        if (stops != null && colors.length != stops.length) {
-            throw new IllegalArgumentException("color and position arrays must be of equal length");
-        }
-        discardNativeInstance();
-        mType = TYPE_COLORS_AND_POSITIONS;
-        mX = centerX;
-        mY = centerY;
-        mRadius = radius;
-        mColors = colors.clone();
-        mPositions = stops != null ? stops.clone() : null;
-        mTileMode = tileMode;
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param centerX     The x-coordinate of the center of the radius
-     * @param centerY     The y-coordinate of the center of the radius
-     * @param radius      Must be positive. The radius of the circle for this gradient
-     * @param centerColor The color at the center of the circle.
-     * @param edgeColor   The color at the edge of the circle.
-     * @param tileMode    The Shader tiling mode
-     */
-    public void set(float centerX, float centerY, float radius,
-            @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
-        if (radius <= 0) {
-            throw new IllegalArgumentException("radius must be > 0");
-        }
-        discardNativeInstance();
         mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
         mX = centerX;
         mY = centerY;
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 8410ab2..c744757 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -105,20 +105,13 @@
         return 0;
     }
 
-    void discardNativeInstance() {
+    private void discardNativeInstance() {
         if (mNativeInstance != 0) {
             nativeSafeUnref(mNativeInstance);
             mNativeInstance = 0;
         }
     }
 
-    /**
-     * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently
-     * constructed native instance is no longer valid.
-     */
-    void verifyNativeInstance() {
-    }
-
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -155,9 +148,6 @@
             throw new IllegalStateException("attempting to use a finalized Shader");
         }
 
-        // verify mNativeInstance is valid
-        verifyNativeInstance();
-
         if (mNativeInstance == 0) {
             mNativeInstance = createNativeInstance(mLocalMatrix == null
                     ? 0 : mLocalMatrix.native_instance);
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 0a1aef6..b6b80b4 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -54,7 +54,18 @@
      */
     public SweepGradient(float cx, float cy,
             @NonNull @ColorInt int colors[], @Nullable float positions[]) {
-        set(cx, cy, colors, positions);
+        if (colors.length < 2) {
+            throw new IllegalArgumentException("needs >= 2 number of colors");
+        }
+        if (positions != null && colors.length != positions.length) {
+            throw new IllegalArgumentException(
+                    "color and position arrays must be of equal length");
+        }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mCx = cx;
+        mCy = cy;
+        mColors = colors.clone();
+        mPositions = positions != null ? positions.clone() : null;
     }
 
     /**
@@ -66,50 +77,6 @@
      * @param color1   The color to use at the end of the sweep
      */
     public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
-        set(cx, cy, color0, color1);
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    public void set(float cx, float cy,
-            @NonNull @ColorInt int colors[], @Nullable float positions[]) {
-        if (colors.length < 2) {
-            throw new IllegalArgumentException("needs >= 2 number of colors");
-        }
-        if (positions != null && colors.length != positions.length) {
-            throw new IllegalArgumentException(
-                    "color and position arrays must be of equal length");
-        }
-        discardNativeInstance();
-        mType = TYPE_COLORS_AND_POSITIONS;
-        mCx = cx;
-        mCy = cy;
-        mColors = colors.clone();
-        mPositions = positions != null ? positions.clone() : null;
-    }
-
-    /**
-     * Reinitialize the shader.
-     *
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param color0   The color to use at the start of the sweep
-     * @param color1   The color to use at the end of the sweep
-     */
-    public void set(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
-        discardNativeInstance();
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mCx = cx;
         mCy = cy;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index 86bb0de..4b3cdfb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -39,7 +39,8 @@
     // This delay controls how long to wait before we show the target when the user first moves
     // the PIP, to prevent the target from animating if the user just wants to fling the PIP
     private static final int SHOW_TARGET_DELAY = 100;
-    private static final int SHOW_TARGET_DURATION = 200;
+    private static final int SHOW_TARGET_DURATION = 350;
+    private static final int HIDE_TARGET_DURATION = 225;
 
     private Context mContext;
     private WindowManager mWindowManager;
@@ -96,7 +97,7 @@
     public void showDismissTarget() {
         mDismissView.animate()
                 .alpha(1f)
-                .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+                .setInterpolator(Interpolators.LINEAR)
                 .setStartDelay(SHOW_TARGET_DELAY)
                 .setDuration(SHOW_TARGET_DURATION)
                 .start();
@@ -109,9 +110,9 @@
         if (mDismissView != null) {
             mDismissView.animate()
                     .alpha(0f)
-                    .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
+                    .setInterpolator(Interpolators.LINEAR)
                     .setStartDelay(0)
-                    .setDuration(SHOW_TARGET_DURATION)
+                    .setDuration(HIDE_TARGET_DURATION)
                     .withEndAction(new Runnable() {
                         @Override
                         public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index fbf7ff2..3223f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -63,7 +63,7 @@
     private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
     private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1;
 
-    private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 200;
+    private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 225;
 
     // Allow dragging the PIP to a location to close it
     private static final boolean ENABLE_DISMISS_DRAG_TO_EDGE = true;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 7c3f324..c92c52f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -442,7 +442,7 @@
      */
     public boolean showSaveLocked() {
         if (mStructure == null) {
-            Slog.wtf(TAG, "showSaveLocked(): no mStructure");
+            Slog.d(TAG, "showSaveLocked(): no mStructure");
             return true;
         }
         if (mResponses == null) {
@@ -764,7 +764,8 @@
         boolean saveOnAllViewsInvisible = false;
         SaveInfo saveInfo = mResponses.valueAt(getLastResponseIndex()).getSaveInfo();
         if (saveInfo != null) {
-            saveOnAllViewsInvisible = saveInfo.saveOnAllViewsInvisible();
+            saveOnAllViewsInvisible =
+                    (saveInfo.getFlags() & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0;
 
             // We only need to track views if we want to save once they become invisible.
             if (saveOnAllViewsInvisible) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 43ae4b2..152d5f4 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2878,6 +2878,10 @@
 
         mWindowManager.deferSurfaceLayout();
 
+        // This will clear the pinned stack by moving an existing task to the full screen stack,
+        // ensuring only one task is present.
+        moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
+
         // Need to make sure the pinned stack exist so we can resize it below...
         final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index f8a4d4b..d42b6a7 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -48,6 +48,7 @@
 import android.util.DisplayMetrics;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.util.XmlUtils;
 
@@ -445,10 +446,23 @@
 
         final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
         final Configuration overrideConfig = getOverrideConfiguration();
-        mWindowContainerController = new TaskWindowContainerController(taskId, this,
+        setWindowContainerController(new TaskWindowContainerController(taskId, this,
                 getStack().getWindowContainerController(), userId, bounds, overrideConfig,
                 mResizeMode, mSupportsPictureInPicture, isHomeTask(), onTop, showForAllUsers,
-                lastTaskDescription);
+                lastTaskDescription));
+    }
+
+    /**
+     * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
+     */
+    @VisibleForTesting
+    protected void setWindowContainerController(TaskWindowContainerController controller) {
+        if (mWindowContainerController != null) {
+            throw new IllegalArgumentException("Window container=" + mWindowContainerController
+                    + " already created for task=" + this);
+        }
+
+        mWindowContainerController = controller;
     }
 
     void removeWindowContainer() {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index 54ecab3..f75d49c 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -16,7 +16,8 @@
 
 package com.android.server.am;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
@@ -36,50 +37,61 @@
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class ActivityRecordTests extends ActivityTestsBase {
+    private static final int TEST_STACK_ID = 100;
+
     private final ComponentName testActivityComponent =
             ComponentName.unflattenFromString("com.foo/.BarActivity");
     @Test
     public void testStackCleanupOnClearingTask() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord task = createTask(service, testActivityComponent, testStack);
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
         final ActivityRecord record = createActivity(service, testActivityComponent, task);
 
         record.setTask(null);
-        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
+        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 1);
     }
 
     @Test
     public void testStackCleanupOnActivityRemoval() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord task = createTask(service, testActivityComponent, testStack);
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
         final ActivityRecord record = createActivity(service, testActivityComponent, task);
 
         task.removeActivity(record);
-        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
+        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID),  1);
     }
 
     @Test
     public void testStackCleanupOnTaskRemoval() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord task = createTask(service, testActivityComponent, testStack);
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
         final ActivityRecord record = createActivity(service, testActivityComponent, task);
 
-        testStack.removeTask(task, null /*reason*/, ActivityStack.REMOVE_TASK_MODE_MOVING);
-        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
+        service.mStackSupervisor.getStack(TEST_STACK_ID)
+                .removeTask(task, null /*reason*/, ActivityStack.REMOVE_TASK_MODE_MOVING);
+
+        // Stack should be gone on task removal.
+        assertNull(service.mStackSupervisor.getStack(TEST_STACK_ID));
     }
 
     @Test
     public void testNoCleanupMovingActivityInSameStack() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord oldTask = createTask(service, testActivityComponent, testStack);
+        final TaskRecord oldTask = createTask(service, testActivityComponent, TEST_STACK_ID);
         final ActivityRecord record = createActivity(service, testActivityComponent, oldTask);
-        final TaskRecord newTask = createTask(service, testActivityComponent, testStack);
+        final TaskRecord newTask = createTask(service, testActivityComponent, TEST_STACK_ID);
 
         record.reparent(newTask, 0, null /*reason*/);
-        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 0);
+        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 0);
+    }
+
+    private static int getActivityRemovedFromStackCount(ActivityManagerService service,
+            int stackId) {
+        final ActivityStack stack = service.mStackSupervisor.getStack(stackId);
+        if (stack instanceof ActivityStackReporter) {
+            return ((ActivityStackReporter) stack).onActivityRemovedFromStackInvocationCount();
+        }
+
+        return -1;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 8423aff..fc9ab96 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -16,8 +16,14 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
+import android.content.ComponentName;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -25,6 +31,10 @@
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 
 /**
@@ -37,6 +47,9 @@
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class ActivityStackSupervisorTests extends ActivityTestsBase {
+    private final ComponentName testActivityComponent =
+            ComponentName.unflattenFromString("com.foo/.BarActivity");
+
     /**
      * This test ensures that we do not try to restore a task based off an invalid task id. The
      * stack supervisor is a test version so there will be no tasks present. We should expect
@@ -49,4 +62,59 @@
                 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 0 /*stackId*/);
         assertNull(task);
     }
+
+    /**
+     * This test ensures that an existing task in the pinned stack is moved to the fullscreen
+     * activity stack when a new task is added.
+     */
+    @Test
+    public void testReplacingTaskInPinnedStack() throws Exception {
+        final ActivityManagerService service = createActivityManagerService();
+        final TaskRecord firstTask = createTask(service, testActivityComponent,
+                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ActivityRecord firstActivity = createActivity(service, testActivityComponent,
+                firstTask);
+        // Create a new task on the full screen stack
+        final TaskRecord secondTask = createTask(service, testActivityComponent,
+                FULLSCREEN_WORKSPACE_STACK_ID);
+        final ActivityRecord secondActivity = createActivity(service, testActivityComponent,
+                secondTask);
+        service.mStackSupervisor.setFocusStackUnchecked("testReplacingTaskInPinnedStack",
+                service.mStackSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID));
+
+        // Ensure full screen stack has both tasks.
+        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask,
+                secondTask);
+
+        // Move first activity to pinned stack.
+        service.mStackSupervisor.moveActivityToPinnedStackLocked(firstActivity,
+                new Rect() /*sourceBounds*/, 0f /*aspectRatio*/, false, "initialMove");
+
+        // Ensure a task has moved over.
+        ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, firstTask);
+        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, secondTask);
+
+        // Move second activity to pinned stack.
+        service.mStackSupervisor.moveActivityToPinnedStackLocked(secondActivity,
+                new Rect() /*sourceBounds*/, 0f /*aspectRatio*/ /*destBounds*/, false, "secondMove");
+
+        // Ensure stacks have swapped tasks.
+        ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, secondTask);
+        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask);
+    }
+
+    private static void ensureStackPlacement(ActivityStackSupervisor supervisor, int stackId,
+            TaskRecord... tasks) {
+        final ActivityStack stack = supervisor.getStack(stackId);
+        final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
+        assertEquals(stackTasks.size(), tasks != null ? tasks.length : 0);
+
+        if (tasks == null) {
+            return;
+        }
+
+        for (TaskRecord task : tasks) {
+            assertTrue(stackTasks.contains(task));
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index 1d80b33..f42abf1 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -37,28 +37,27 @@
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class ActivityStackTests extends ActivityTestsBase {
-    private final ComponentName testActivityComponent =
+    private static final int TEST_STACK_ID = 100;
+    private static final ComponentName testActivityComponent =
             ComponentName.unflattenFromString("com.foo/.BarActivity");
 
     @Test
     public void testEmptyTaskCleanupOnRemove() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord task = createTask(service, testActivityComponent, testStack);
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
         assertNotNull(task.getWindowContainerController());
-        testStack.removeTask(task, "testEmptyTaskCleanupOnRemove",
-                ActivityStack.REMOVE_TASK_MODE_DESTROYING);
+        service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
+                "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
         assertNull(task.getWindowContainerController());
     }
     @Test
     public void testOccupiedTaskCleanupOnRemove() throws Exception {
         final ActivityManagerService service = createActivityManagerService();
-        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
-        final TaskRecord task = createTask(service, testActivityComponent, testStack);
+        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
         final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
         assertNotNull(task.getWindowContainerController());
-        testStack.removeTask(task, "testOccupiedTaskCleanupOnRemove",
-                ActivityStack.REMOVE_TASK_MODE_DESTROYING);
+        service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
+                "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
         assertNotNull(task.getWindowContainerController());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 3bf0e5f..0827084 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -17,6 +17,11 @@
 package com.android.server.am;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
+
+import org.mockito.invocation.InvocationOnMock;
 
 import android.app.ActivityManager;
 import android.content.ComponentName;
@@ -33,6 +38,7 @@
 import com.android.server.wm.AppWindowContainerController;
 import com.android.server.wm.StackWindowController;
 
+import com.android.server.wm.TaskWindowContainerController;
 import com.android.server.wm.WindowManagerService;
 import com.android.server.wm.WindowTestUtils;
 import org.junit.After;
@@ -64,16 +70,15 @@
 
     protected ActivityManagerService createActivityManagerService() {
         final ActivityManagerService service = new TestActivityManagerService(mContext);
-        service.mWindowManager = WindowTestUtils.getWindowManagerService(mContext);
+        service.mWindowManager = WindowTestUtils.getMockWindowManagerService();
         return service;
     }
 
-    protected static TestActivityStack createActivityStack(ActivityManagerService service,
+    protected static ActivityStack createActivityStack(ActivityManagerService service,
             int stackId, int displayId, boolean onTop) {
         if (service.mStackSupervisor instanceof TestActivityStackSupervisor) {
-            final TestActivityStack stack = ((TestActivityStackSupervisor) service.mStackSupervisor)
+            return ((TestActivityStackSupervisor) service.mStackSupervisor)
                     .createTestStack(service, stackId, onTop);
-            return stack;
         }
 
         return null;
@@ -103,7 +108,7 @@
     }
 
     protected static TaskRecord createTask(ActivityManagerService service,
-            ComponentName component, ActivityStack stack) {
+            ComponentName component, int stackId) {
         final ActivityInfo aInfo = new ActivityInfo();
         aInfo.applicationInfo = new ApplicationInfo();
         aInfo.applicationInfo.packageName = component.getPackageName();
@@ -113,13 +118,16 @@
 
         final TaskRecord task = new TaskRecord(service, 0, aInfo, intent /*intent*/,
                 null /*_taskDescription*/, new ActivityManager.TaskThumbnailInfo());
+        final ActivityStack stack = service.mStackSupervisor.getStack(stackId,
+                true /*createStaticStackIfNeeded*/, true /*onTop*/);
         stack.addTask(task, true, "creating test task");
         task.setStack(stack);
-        task.createWindowContainer(true, true);
+        task.setWindowContainerController(mock(TaskWindowContainerController.class));
 
         return task;
     }
 
+
     /**
      * An {@link ActivityManagerService} subclass which provides a test
      * {@link ActivityStackSupervisor}.
@@ -127,6 +135,9 @@
     protected static class TestActivityManagerService extends ActivityManagerService {
         public TestActivityManagerService(Context context) {
             super(context);
+            mSupportsMultiWindow = true;
+            mSupportsMultiDisplay = true;
+            mWindowManager = WindowTestUtils.getWindowManagerService(context);
         }
 
         @Override
@@ -142,6 +153,12 @@
     protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
         public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
             super(service, looper);
+            mWindowManager = prepareMockWindowManager();
+        }
+
+        // No home stack is set.
+        @Override
+        void moveHomeStackToFront(String reason) {
         }
 
         // Invoked during {@link ActivityStack} creation.
@@ -149,18 +166,45 @@
         void updateUIDsPresentOnDisplay() {
         }
 
-        public TestActivityStack createTestStack(ActivityManagerService service, int stackId,
-                boolean onTop) {
+        // Just return the current front task.
+        @Override
+        ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus) {
+            return mFocusedStack;
+        }
+
+        // Called when moving activity to pinned stack.
+        @Override
+        void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+                boolean preserveWindows) {
+        }
+
+        public <T extends ActivityStack> T createTestStack(ActivityManagerService service,
+                int stackId, boolean onTop) {
             final ActivityDisplay display = new ActivityDisplay();
             final TestActivityContainer container =
                     new TestActivityContainer(service, stackId, display, onTop);
-            return container.getStack();
+            mActivityContainers.put(stackId, container);
+            return (T) container.getStack();
+        }
+
+        @Override
+        protected <T extends ActivityStack> T getStack(int stackId,
+                boolean createStaticStackIfNeeded, boolean createOnTop) {
+            final T stack = super.getStack(stackId, createStaticStackIfNeeded, createOnTop);
+
+            if (stack != null || !createStaticStackIfNeeded) {
+                return stack;
+            }
+
+            return createTestStack(mService, stackId, createOnTop);
         }
 
         private class TestActivityContainer extends ActivityContainer {
-            private ActivityManagerService mService;
-            private TestActivityStack mStack;
+            private final ActivityManagerService mService;
+
             private boolean mOnTop;
+            private int mStackId;
+            private ActivityStack mStack;
 
             TestActivityContainer(ActivityManagerService service, int stackId,
                     ActivityDisplay activityDisplay, boolean onTop) {
@@ -174,12 +218,16 @@
                 // we cannot set {@link mService} by the time the super constructor calling this
                 // method is invoked.
                 mOnTop = onTop;
+                mStackId = stackId;
             }
 
-            public TestActivityStack getStack() {
+            public ActivityStack getStack() {
                 if (mStack == null) {
-                    mStack = new TestActivityStack(this,
-                            new RecentTasks(mService, mService.mStackSupervisor), mOnTop);
+                    final RecentTasks recents =
+                            new RecentTasks(mService, mService.mStackSupervisor);
+                    mStack = mStackId == ActivityManager.StackId.PINNED_STACK_ID
+                    ? new PinnedActivityStack(this, recents, mOnTop)
+                    : new TestActivityStack(this, recents, mOnTop);
                 }
 
                 return mStack;
@@ -187,13 +235,31 @@
         }
     }
 
+    private static WindowManagerService prepareMockWindowManager() {
+        final WindowManagerService service = mock(WindowManagerService.class);
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
+            if (runnable != null) {
+                runnable.run();
+            }
+            return null;
+        }).when(service).inSurfaceTransaction(any());
+
+        return service;
+    }
+
+    protected interface ActivityStackReporter {
+        int onActivityRemovedFromStackInvocationCount();
+    }
+
     /**
      * Override of {@link ActivityStack} that tracks test metrics, such as the number of times a
      * method is called. Note that its functionality depends on the implementations of the
      * construction arguments.
      */
     protected static class TestActivityStack<T extends StackWindowController>
-            extends ActivityStack<T> {
+            extends ActivityStack<T> implements ActivityStackReporter {
         private int mOnActivityRemovedFromStackCount = 0;
         private T mContainerController;
         TestActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer,
@@ -208,6 +274,7 @@
         }
 
         // Returns the number of times {@link #onActivityRemovedFromStack} has been called
+        @Override
         public int onActivityRemovedFromStackInvocationCount() {
             return mOnActivityRemovedFromStackCount;
         }
@@ -225,6 +292,7 @@
         }
     }
 
+
     protected static class ActivityStackBuilder {
         private boolean mOnTop = true;
         private int mStackId = 0;
@@ -251,7 +319,7 @@
             return this;
         }
 
-        public TestActivityStack build() {
+        public ActivityStack build() {
             return createActivityStack(mService, mStackId, mDisplayId, mOnTop);
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index fbeda0a..9392e8e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -90,6 +90,7 @@
                     return null;
                 }).when(am).notifyKeyguardFlagsChanged(any());
             }
+
             sWm = WindowManagerService.main(context, mock(InputManagerService.class), true, false,
                     false, new TestWindowManagerPolicy());
         }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index 3a44357..ae3eb52 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -48,6 +48,13 @@
     }
 
     /**
+     * Retrieves an instance of a mock {@link WindowManagerService}.
+     */
+    public static WindowManagerService getMockWindowManagerService() {
+        return mock(WindowManagerService.class);
+    }
+
+    /**
      * Creates a mock instance of {@link StackWindowController}.
      */
     public static StackWindowController createMockStackWindowContainerController() {