Merge "Some Autofill API changes." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 6b55a4d..afb4569 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10940,12 +10940,13 @@
     method public android.content.pm.VersionedPackage getDeclaringPackage();
     method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
     method public java.lang.String getName();
-    method public int getVersion();
-    method public boolean isBuiltin();
-    method public boolean isDynamic();
-    method public boolean isStatic();
+    method public int getType();
+    method public long getVersion();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
+    field public static final int TYPE_BUILTIN = 0; // 0x0
+    field public static final int TYPE_DYNAMIC = 1; // 0x1
+    field public static final int TYPE_STATIC = 2; // 0x2
     field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
   }
 
@@ -20783,13 +20784,10 @@
     method public boolean hasSpeedAccuracy();
     method public boolean hasVerticalAccuracy();
     method public boolean isFromMockProvider();
-    method public void removeAccuracy();
-    method public void removeAltitude();
-    method public void removeBearing();
-    method public void removeBearingAccuracy();
-    method public void removeSpeed();
-    method public void removeSpeedAccuracy();
-    method public void removeVerticalAccuracy();
+    method public deprecated void removeAccuracy();
+    method public deprecated void removeAltitude();
+    method public deprecated void removeBearing();
+    method public deprecated void removeSpeed();
     method public void reset();
     method public void set(android.location.Location);
     method public void setAccuracy(float);
@@ -37033,6 +37031,7 @@
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
     method public final deprecated void disableSelf();
+    method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
@@ -37055,6 +37054,7 @@
     ctor public Dataset.Builder();
     method public android.service.autofill.Dataset build();
     method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setId(java.lang.String);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
   }
@@ -37072,6 +37072,23 @@
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
   }
 
+  public final class FillEventHistory implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getClientState();
+    method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
+  }
+
+  public static final class FillEventHistory.Event {
+    method public java.lang.String getDatasetId();
+    method public int getType();
+    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
+    field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
+    field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
+    field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
+  }
+
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
diff --git a/api/removed.txt b/api/removed.txt
index 0f5b81a..b6c2a98 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -63,6 +63,12 @@
     field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
   }
 
+  public final class SharedLibraryInfo implements android.os.Parcelable {
+    method public boolean isBuiltin();
+    method public boolean isDynamic();
+    method public boolean isStatic();
+  }
+
 }
 
 package android.database {
@@ -126,6 +132,16 @@
 
 }
 
+package android.location {
+
+  public class Location implements android.os.Parcelable {
+    method public deprecated void removeBearingAccuracy();
+    method public deprecated void removeSpeedAccuracy();
+    method public deprecated void removeVerticalAccuracy();
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 1228698..84b9da9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -11700,12 +11700,13 @@
     method public android.content.pm.VersionedPackage getDeclaringPackage();
     method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
     method public java.lang.String getName();
-    method public int getVersion();
-    method public boolean isBuiltin();
-    method public boolean isDynamic();
-    method public boolean isStatic();
+    method public int getType();
+    method public long getVersion();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
+    field public static final int TYPE_BUILTIN = 0; // 0x0
+    field public static final int TYPE_DYNAMIC = 1; // 0x1
+    field public static final int TYPE_STATIC = 2; // 0x2
     field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
   }
 
@@ -22517,13 +22518,10 @@
     method public boolean isComplete();
     method public boolean isFromMockProvider();
     method public void makeComplete();
-    method public void removeAccuracy();
-    method public void removeAltitude();
-    method public void removeBearing();
-    method public void removeBearingAccuracy();
-    method public void removeSpeed();
-    method public void removeSpeedAccuracy();
-    method public void removeVerticalAccuracy();
+    method public deprecated void removeAccuracy();
+    method public deprecated void removeAltitude();
+    method public deprecated void removeBearing();
+    method public deprecated void removeSpeed();
     method public void reset();
     method public void set(android.location.Location);
     method public void setAccuracy(float);
@@ -40145,6 +40143,7 @@
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
     method public final deprecated void disableSelf();
+    method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
@@ -40167,6 +40166,7 @@
     ctor public Dataset.Builder();
     method public android.service.autofill.Dataset build();
     method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setId(java.lang.String);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
   }
@@ -40184,6 +40184,23 @@
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
   }
 
+  public final class FillEventHistory implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getClientState();
+    method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
+  }
+
+  public static final class FillEventHistory.Event {
+    method public java.lang.String getDatasetId();
+    method public int getType();
+    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
+    field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
+    field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
+    field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
+  }
+
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 823d88f..6d82a49 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -61,6 +61,12 @@
     field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
   }
 
+  public final class SharedLibraryInfo implements android.os.Parcelable {
+    method public boolean isBuiltin();
+    method public boolean isDynamic();
+    method public boolean isStatic();
+  }
+
 }
 
 package android.database {
@@ -124,6 +130,16 @@
 
 }
 
+package android.location {
+
+  public class Location implements android.os.Parcelable {
+    method public deprecated void removeBearingAccuracy();
+    method public deprecated void removeSpeedAccuracy();
+    method public deprecated void removeVerticalAccuracy();
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3d1de55..0ca882a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -10981,12 +10981,13 @@
     method public android.content.pm.VersionedPackage getDeclaringPackage();
     method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
     method public java.lang.String getName();
-    method public int getVersion();
-    method public boolean isBuiltin();
-    method public boolean isDynamic();
-    method public boolean isStatic();
+    method public int getType();
+    method public long getVersion();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
+    field public static final int TYPE_BUILTIN = 0; // 0x0
+    field public static final int TYPE_DYNAMIC = 1; // 0x1
+    field public static final int TYPE_STATIC = 2; // 0x2
     field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
   }
 
@@ -20889,13 +20890,10 @@
     method public boolean hasSpeedAccuracy();
     method public boolean hasVerticalAccuracy();
     method public boolean isFromMockProvider();
-    method public void removeAccuracy();
-    method public void removeAltitude();
-    method public void removeBearing();
-    method public void removeBearingAccuracy();
-    method public void removeSpeed();
-    method public void removeSpeedAccuracy();
-    method public void removeVerticalAccuracy();
+    method public deprecated void removeAccuracy();
+    method public deprecated void removeAltitude();
+    method public deprecated void removeBearing();
+    method public deprecated void removeSpeed();
     method public void reset();
     method public void set(android.location.Location);
     method public void setAccuracy(float);
@@ -37186,6 +37184,7 @@
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
     method public final deprecated void disableSelf();
+    method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
@@ -37208,6 +37207,7 @@
     ctor public Dataset.Builder();
     method public android.service.autofill.Dataset build();
     method public android.service.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
+    method public android.service.autofill.Dataset.Builder setId(java.lang.String);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue);
     method public android.service.autofill.Dataset.Builder setValue(android.view.autofill.AutofillId, android.view.autofill.AutofillValue, android.widget.RemoteViews);
   }
@@ -37225,6 +37225,23 @@
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillContext> CREATOR;
   }
 
+  public final class FillEventHistory implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getClientState();
+    method public java.util.List<android.service.autofill.FillEventHistory.Event> getEvents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillEventHistory> CREATOR;
+  }
+
+  public static final class FillEventHistory.Event {
+    method public java.lang.String getDatasetId();
+    method public int getType();
+    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
+    field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
+    field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
+    field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
+  }
+
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 0f5b81a..b6c2a98 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -63,6 +63,12 @@
     field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
   }
 
+  public final class SharedLibraryInfo implements android.os.Parcelable {
+    method public boolean isBuiltin();
+    method public boolean isDynamic();
+    method public boolean isStatic();
+  }
+
 }
 
 package android.database {
@@ -126,6 +132,16 @@
 
 }
 
+package android.location {
+
+  public class Location implements android.os.Parcelable {
+    method public deprecated void removeBearingAccuracy();
+    method public deprecated void removeSpeedAccuracy();
+    method public deprecated void removeVerticalAccuracy();
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e07b7e4..027ddf5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -79,6 +79,8 @@
 import android.os.storage.VolumeInfo;
 import android.provider.Settings;
 import android.util.ArrayMap;
+import android.util.IconDrawableFactory;
+import android.util.LauncherIcons;
 import android.util.Log;
 import android.view.Display;
 
@@ -1245,16 +1247,9 @@
         if (!isManagedProfile(user.getIdentifier())) {
             return icon;
         }
-        Drawable badgeShadow = getDrawable("system",
-                com.android.internal.R.drawable.ic_corp_icon_badge_shadow, null);
-        Drawable badgeColor = getDrawable("system",
-                com.android.internal.R.drawable.ic_corp_icon_badge_color, null);
-        badgeColor.setTint(getUserBadgeColor(user));
-        Drawable badgeForeground = getDrawable("system",
-                com.android.internal.R.drawable.ic_corp_icon_badge_case, null);
-
-        Drawable badge = new LayerDrawable(
-                new Drawable[] {badgeShadow, badgeColor, badgeForeground });
+        Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
+                com.android.internal.R.drawable.ic_corp_icon_badge_case,
+                getUserBadgeColor(user));
         return getBadgedDrawable(icon, badge, null, true);
     }
 
@@ -1268,14 +1263,6 @@
         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
     }
 
-    // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
-    @VisibleForTesting
-    public static final int[] CORP_BADGE_COLORS = new int[] {
-        com.android.internal.R.color.profile_badge_1,
-        com.android.internal.R.color.profile_badge_2,
-        com.android.internal.R.color.profile_badge_3
-    };
-
     @VisibleForTesting
     public static final int[] CORP_BADGE_LABEL_RES_ID = new int[] {
         com.android.internal.R.string.managed_profile_label_badge,
@@ -1284,12 +1271,7 @@
     };
 
     private int getUserBadgeColor(UserHandle user) {
-        int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
-        if (badge < 0) {
-            badge = 0;
-        }
-        int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
-        return Resources.getSystem().getColor(resourceId, null);
+        return IconDrawableFactory.getUserBadgeColor(getUserManager(), user.getIdentifier());
     }
 
     @Override
diff --git a/core/java/android/content/pm/ChangedPackages.java b/core/java/android/content/pm/ChangedPackages.java
index 94b8a5d..78c057d 100644
--- a/core/java/android/content/pm/ChangedPackages.java
+++ b/core/java/android/content/pm/ChangedPackages.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -26,6 +27,7 @@
 /**
  * Packages that have been changed since the last time they
  * were requested.
+ * @see PackageManager#getChangedPackages(int)
  */
 public final class ChangedPackages implements Parcelable {
     /** The last known sequence number for these changes */
@@ -33,6 +35,7 @@
     /** The names of the packages that have changed */
     private final List<String> mPackageNames;
 
+    @TestApi
     public ChangedPackages(int sequenceNumber, @NonNull List<String> packageNames) {
         this.mSequenceNumber = sequenceNumber;
         this.mPackageNames = packageNames;
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index d79deb2..0ad4874 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -16,11 +16,14 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Collections;
 import java.util.List;
 
@@ -31,28 +34,37 @@
  * static - updatable non backwards-compatible emulating static linking.
  */
 public final class SharedLibraryInfo implements Parcelable {
+
+    /** @hide */
+    @IntDef(
+        flag = true,
+        value = {
+                TYPE_BUILTIN,
+                TYPE_DYNAMIC,
+                TYPE_STATIC,
+        })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Type{}
+
     /**
      * Shared library type: this library is a part of the OS
      * and cannot be updated or uninstalled.
-     * @hide
      */
-    public static final int TYPE_BUILTIN = 0x1<<0;
+    public static final int TYPE_BUILTIN = 0;
 
     /**
      * Shared library type: this library is backwards-compatible, can
      * be updated, and updates can be uninstalled. Clients link against
      * the latest version of the library.
-     * @hide
      */
-    public static final int TYPE_DYNAMIC = 0x1<<1;
+    public static final int TYPE_DYNAMIC = 1;
 
     /**
      * Shared library type: this library is <strong>not</strong> backwards
      * -compatible, can be updated and updates can be uninstalled. Clients
      * link against a specific version of the library.
-     * @hide
      */
-    public static final int TYPE_STATIC = 0x1<<2;
+    public static final int TYPE_STATIC = 2;
 
     /**
      * Constant for referring to an undefined version.
@@ -60,8 +72,10 @@
     public static final int VERSION_UNDEFINED = -1;
 
     private final String mName;
+
+    // TODO: Make long when we change the paltform to use longs
     private final int mVersion;
-    private final int mType;
+    private final @Type int mType;
     private final VersionedPackage mDeclaringPackage;
     private final List<VersionedPackage> mDependentPackages;
 
@@ -90,13 +104,18 @@
                 parcel.readParcelable(null), parcel.readArrayList(null));
     }
 
-    /** @hide */
-    public int getType() {
+    /**
+     * Gets the type of this library.
+     *
+     * @return The library type.
+     */
+    public @Type int getType() {
         return mType;
     }
 
     /**
-     * Gets the library name.
+     * Gets the library name an app defines in its manifest
+     * to depend on the library.
      *
      * @return The name.
      */
@@ -105,40 +124,36 @@
     }
 
     /**
-     * Gets the version of the library. For {@link #isStatic()}  static} libraries
-     * this is the declared version and for {@link #isDynamic()} dynamic} and
-     * {@link #isBuiltin()} builtin} it is {@link #VERSION_UNDEFINED} as these
+     * Gets the version of the library. For {@link #TYPE_STATIC static} libraries
+     * this is the declared version and for {@link #TYPE_DYNAMIC dynamic} and
+     * {@link #TYPE_BUILTIN builtin} it is {@link #VERSION_UNDEFINED} as these
      * are not versioned.
      *
      * @return The version.
      */
-    public @IntRange(from = -1) int getVersion() {
+    public @IntRange(from = -1) long getVersion() {
         return mVersion;
     }
 
     /**
-     * @return whether this library is builtin which means that it
-     * is a part of the OS and cannot be updated or uninstalled.
+     * @hide
+     * @removed
      */
     public boolean isBuiltin() {
         return mType == TYPE_BUILTIN;
     }
 
     /**
-     * @return whether this library is dynamic which means that it
-     * is backwards-compatible, can be updated, and updates can be
-     * uninstalled. Clients link against the latest version of the
-     * library.
+     * @hide
+     * @removed
      */
     public boolean isDynamic() {
         return mType == TYPE_DYNAMIC;
     }
 
     /**
-     * @return whether this library is dynamic which means that it
-     * is <strong>not</strong> backwards-compatible, can be updated
-     * and updates can be uninstalled. Clients link against a specific
-     * version of the library.
+     * @hide
+     * @removed
      */
     public boolean isStatic() {
         return mType == TYPE_STATIC;
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index b3d5522..813c54f 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -285,4 +285,22 @@
         // TODO(b/33197203): Remove when GCore has migrated off this API
         getSystemService(AutofillManager.class).disableOwnedAutofillServices();
     }
+
+    /**
+     * Returns the {@link FillEventHistory.Event events} since the last {@link FillResponse} was
+     * returned.
+     *
+     * <p>The history is not persisted over reboots.
+     *
+     * @return The history or {@code null} if there are not events.
+     */
+    @Nullable public final FillEventHistory getFillEventHistory() {
+        AutofillManager afm = getSystemService(AutofillManager.class);
+
+        if (afm == null) {
+            return null;
+        } else {
+            return afm.getFillEventHistory();
+        }
+    }
 }
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index e77bd0d..e04fae7 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -24,6 +24,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 import android.widget.RemoteViews;
 import com.android.internal.util.Preconditions;
@@ -50,6 +51,7 @@
     private final ArrayList<RemoteViews> mFieldPresentations;
     private final RemoteViews mPresentation;
     private final IntentSender mAuthentication;
+    @Nullable String mId;
 
     private Dataset(Builder builder) {
         mFieldIds = builder.mFieldIds;
@@ -57,6 +59,7 @@
         mFieldPresentations = builder.mFieldPresentations;
         mPresentation = builder.mPresentation;
         mAuthentication = builder.mAuthentication;
+        mId = builder.mId;
     }
 
     /** @hide */
@@ -89,7 +92,7 @@
     public String toString() {
         if (!DEBUG) return super.toString();
 
-        return new StringBuilder("Dataset [")
+        return new StringBuilder("Dataset " + mId + " [")
                 .append("fieldIds=").append(mFieldIds)
                 .append(", fieldValues=").append(mFieldValues)
                 .append(", fieldPresentations=")
@@ -100,6 +103,17 @@
     }
 
     /**
+     * Gets the id of this dataset.
+     *
+     * @return The id of this dataset or {@code null} if not set
+     *
+     * @hide
+     */
+    public String getId() {
+        return mId;
+    }
+
+    /**
      * A builder for {@link Dataset} objects. You must to provide at least
      * one value for a field or set an authentication intent.
      */
@@ -110,6 +124,7 @@
         private RemoteViews mPresentation;
         private IntentSender mAuthentication;
         private boolean mDestroyed;
+        @Nullable private String mId;
 
         /**
          * Creates a new builder.
@@ -173,6 +188,25 @@
         }
 
         /**
+         * Sets the id for the dataset.
+         *
+         * <p>The id of the last selected dataset can be read from
+         * {@link AutofillService#getFillEventHistory()}. If the id is not set it will not be clear
+         * if a dataset was selected as {@link AutofillService#getFillEventHistory()} uses
+         * {@code null} to indicate that no dataset was selected.
+         *
+         * @param id id for this dataset or {@code null} to unset.
+
+         * @return This builder.
+         */
+        public @NonNull Builder setId(@Nullable String id) {
+            throwIfDestroyed();
+
+            mId = id;
+            return this;
+        }
+
+        /**
          * Sets the value of a field.
          *
          * @param id id returned by {@link
@@ -269,6 +303,7 @@
         parcel.writeTypedArrayList(mFieldValues, flags);
         parcel.writeParcelableList(mFieldPresentations, flags);
         parcel.writeParcelable(mAuthentication, flags);
+        parcel.writeString(mId);
     }
 
     public static final Creator<Dataset> CREATOR = new Creator<Dataset>() {
@@ -295,6 +330,7 @@
                 builder.setValueAndPresentation(id, value, fieldPresentation);
             }
             builder.setAuthentication(parcel.readParcelable(null));
+            builder.setId(parcel.readString());
             return builder.build();
         }
 
diff --git a/core/java/android/service/autofill/FillEventHistory.aidl b/core/java/android/service/autofill/FillEventHistory.aidl
new file mode 100644
index 0000000..3c48524
--- /dev/null
+++ b/core/java/android/service/autofill/FillEventHistory.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.autofill;
+
+parcelable FillEventHistory;
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
new file mode 100644
index 0000000..3d72fcc
--- /dev/null
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.autofill;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.IntentSender;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.autofill.AutofillId;
+import android.widget.RemoteViews;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Describes what happened after the latest call to {@link FillCallback#onSuccess(FillResponse)}.
+ */
+public final class FillEventHistory implements Parcelable {
+    /**
+     * Not in parcel. The UID of the {@link AutofillService} that created the {@link FillResponse}.
+     */
+    private final int mServiceUid;
+
+    @Nullable private final Bundle mClientState;
+    @Nullable List<Event> mEvents;
+
+    /**
+     * Gets the UID of the {@link AutofillService} that created the {@link FillResponse}.
+     *
+     * @return The UID of the {@link AutofillService}
+     *
+     * @hide
+     */
+    public int getServiceUid() {
+        return mServiceUid;
+    }
+
+    /**
+     * Returns the client state of the {@link FillResponse}.
+     *
+     * @return The client state set by the last {@link FillResponse}
+     */
+    @Nullable public Bundle getClientState() {
+        return mClientState;
+    }
+
+    /**
+     * Returns the events occurred after the latest call to
+     * {@link FillCallback#onSuccess(FillResponse)}.
+     *
+     * @return The list of events or {@code null} if non occurred.
+     */
+    @Nullable public List<Event> getEvents() {
+        return mEvents;
+    }
+
+    /**
+     * @hide
+     */
+    public void addEvent(Event event) {
+        if (mEvents == null) {
+            mEvents = new ArrayList<>(1);
+        }
+        mEvents.add(event);
+    }
+
+    /**
+     * @hide
+     */
+    public FillEventHistory(int serviceUid, @Nullable Bundle clientState) {
+        mClientState = clientState;
+        mServiceUid = serviceUid;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mClientState);
+
+        if (mEvents == null) {
+            dest.writeInt(0);
+        } else {
+            dest.writeInt(mEvents.size());
+
+            int numEvents = mEvents.size();
+            for (int i = 0; i < numEvents; i++) {
+                Event event = mEvents.get(i);
+                dest.writeInt(event.getType());
+                dest.writeString(event.getDatasetId());
+            }
+        }
+    }
+
+    /**
+     * Description of an event that occured after the latest call to
+     * {@link FillCallback#onSuccess(FillResponse)}.
+     */
+    public static final class Event {
+        /**
+         * A dataset was selected. The dataset selected can be read from {@link #getDatasetId()}.
+         */
+        public static final int TYPE_DATASET_SELECTED = 0;
+
+        /**
+         * A {@link Dataset.Builder#setAuthentication(IntentSender) dataset authentication} was
+         * selected. The dataset authenticated can be read from {@link #getDatasetId()}.
+         */
+        public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1;
+
+        /**
+         * A {@link FillResponse.Builder#setAuthentication(AutofillId[], IntentSender, RemoteViews)
+         * fill response authentication} was selected.
+         */
+        public static final int TYPE_AUTHENTICATION_SELECTED = 2;
+
+        /** A save UI was shown. */
+        public static final int TYPE_SAVE_SHOWN = 3;
+
+        /** @hide */
+        @IntDef(
+                value = {TYPE_DATASET_SELECTED,
+                        TYPE_DATASET_AUTHENTICATION_SELECTED,
+                        TYPE_AUTHENTICATION_SELECTED,
+                        TYPE_SAVE_SHOWN})
+        @Retention(RetentionPolicy.SOURCE)
+        @interface EventIds{}
+
+        @EventIds private final int mEventType;
+        @Nullable private final String mDatasetId;
+
+        /**
+         * Returns the type of the event.
+         *
+         * @return The type of the event
+         */
+        public int getType() {
+            return mEventType;
+        }
+
+        /**
+         * Returns the id of dataset the id was on.
+         *
+         * @return The id of dataset, or {@code null} the event is not associated with a dataset.
+         */
+        @Nullable public String getDatasetId() {
+            return mDatasetId;
+        }
+
+        /**
+         * Creates a new event.
+         *
+         * @param eventType The type of the event
+         * @param datasetId The dataset the event was on, or {@code null} if the event was on the
+         *                  whole response.
+         *
+         * @hide
+         */
+        public Event(int eventType, String datasetId) {
+            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_SAVE_SHOWN,
+                    "eventType");
+            mDatasetId = datasetId;
+        }
+    }
+
+    public static final Parcelable.Creator<FillEventHistory> CREATOR =
+            new Parcelable.Creator<FillEventHistory>() {
+                @Override
+                public FillEventHistory createFromParcel(Parcel parcel) {
+                    FillEventHistory selection = new FillEventHistory(0, parcel.readBundle());
+
+                    int numEvents = parcel.readInt();
+                    for (int i = 0; i < numEvents; i++) {
+                        selection.addEvent(new Event(parcel.readInt(), parcel.readString()));
+                    }
+
+                    return selection;
+                }
+
+                @Override
+                public FillEventHistory[] newArray(int size) {
+                    return new FillEventHistory[size];
+                }
+            };
+}
diff --git a/core/java/android/util/IconDrawableFactory.java b/core/java/android/util/IconDrawableFactory.java
new file mode 100644
index 0000000..b07942f
--- /dev/null
+++ b/core/java/android/util/IconDrawableFactory.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Utility class to load app drawables with appropriate badging.
+ *
+ * @hide
+ */
+public class IconDrawableFactory {
+
+    protected final Context mContext;
+    protected final PackageManager mPm;
+    protected final UserManager mUm;
+    protected final LauncherIcons mLauncherIcons;
+    protected final boolean mEmbedShadow;
+
+    private IconDrawableFactory(Context context, boolean embedShadow) {
+        mContext = context;
+        mPm = context.getPackageManager();
+        mUm = context.getSystemService(UserManager.class);
+        mLauncherIcons = new LauncherIcons(context);
+        mEmbedShadow = embedShadow;
+    }
+
+    protected boolean needsBadging(ApplicationInfo appInfo, @UserIdInt int userId) {
+        return appInfo.isInstantApp() || mUm.isManagedProfile(userId);
+    }
+
+    public Drawable getBadgedIcon(ApplicationInfo appInfo) {
+        return getBadgedIcon(appInfo, UserHandle.getUserId(appInfo.uid));
+    }
+
+    public Drawable getBadgedIcon(ApplicationInfo appInfo, @UserIdInt int userId) {
+        return getBadgedIcon(appInfo, appInfo, userId);
+    }
+
+    public Drawable getBadgedIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo,
+            @UserIdInt int userId) {
+        Drawable icon = mPm.loadUnbadgedItemIcon(itemInfo, appInfo);
+        if (!mEmbedShadow && !needsBadging(appInfo, userId)) {
+            return icon;
+        }
+
+        // Before badging, add shadow to adaptive icon if needed.
+        icon = mLauncherIcons.wrapIconDrawableWithShadow(icon);
+        if (appInfo.isInstantApp()) {
+            int badgeColor = Resources.getSystem().getColor(
+                    com.android.internal.R.color.instant_app_badge, null);
+            icon = mLauncherIcons.getBadgedDrawable(icon,
+                    com.android.internal.R.drawable.ic_instant_icon_badge_bolt,
+                    badgeColor);
+        }
+        if (mUm.isManagedProfile(userId)) {
+            icon = mLauncherIcons.getBadgedDrawable(icon,
+                    com.android.internal.R.drawable.ic_corp_icon_badge_case,
+                    getUserBadgeColor(mUm, userId));
+        }
+        return icon;
+    }
+
+    // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
+    @VisibleForTesting
+    public static final int[] CORP_BADGE_COLORS = new int[] {
+            com.android.internal.R.color.profile_badge_1,
+            com.android.internal.R.color.profile_badge_2,
+            com.android.internal.R.color.profile_badge_3
+    };
+
+    public static int getUserBadgeColor(UserManager um, @UserIdInt int userId) {
+        int badge = um.getManagedProfileBadge(userId);
+        if (badge < 0) {
+            badge = 0;
+        }
+        int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
+        return Resources.getSystem().getColor(resourceId, null);
+    }
+
+    public static IconDrawableFactory newInstance(Context context) {
+        return new IconDrawableFactory(context, true);
+    }
+
+    public static IconDrawableFactory newInstance(Context context, boolean embedShadow) {
+        return new IconDrawableFactory(context, embedShadow);
+    }
+}
diff --git a/core/java/android/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
index 89b9646..402bef9 100644
--- a/core/java/android/util/LauncherIcons.java
+++ b/core/java/android/util/LauncherIcons.java
@@ -21,10 +21,11 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableWrapper;
+import android.graphics.drawable.LayerDrawable;
 
 /**
  * Utility class to handle icon treatments (e.g., shadow generation) for the Launcher icons.
@@ -32,78 +33,152 @@
  */
 public final class LauncherIcons {
 
-    private final Paint mPaint = new Paint();
-    private final Canvas mCanvas = new Canvas();
+    // Percent of actual icon size
+    private static final float ICON_SIZE_BLUR_FACTOR = 0.5f/48;
+    // Percent of actual icon size
+    private static final float ICON_SIZE_KEY_SHADOW_DELTA_FACTOR = 1f/48;
 
     private static final int KEY_SHADOW_ALPHA = 61;
     private static final int AMBIENT_SHADOW_ALPHA = 30;
-    private static final float BLUR_FACTOR = 0.5f / 48;
-    private int mShadowInset;
-    private Bitmap mShadowBitmap;
-    private int mIconSize;
-    private Resources mRes;
+
+    private final SparseArray<Bitmap> mShadowCache = new SparseArray<>();
+    private final int mIconSize;
+    private final Resources mRes;
 
     public LauncherIcons(Context context) {
         mRes = context.getResources();
-        DisplayMetrics metrics = mRes.getDisplayMetrics();
-        mShadowInset = (int)(2 * metrics.density);
-        mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
-            Paint.FILTER_BITMAP_FLAG));
-        mIconSize = (int) mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
-    }
-
-    /**
-     * Draw the drawable into a bitmap.
-     */
-    public Bitmap createIconBitmap(Drawable icon) {
-        final Bitmap bitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
-        mPaint.setAlpha(255);
-        mCanvas.setBitmap(bitmap);
-        int iconInset = 0;
-        if (mShadowBitmap != null) {
-            mCanvas.drawBitmap(mShadowBitmap, 0, 0, mPaint);
-            iconInset = mShadowInset;
-        }
-
-        icon.setBounds(iconInset, iconInset, mIconSize - iconInset,
-            mIconSize - iconInset);
-        icon.draw(mCanvas);
-        mCanvas.setBitmap(null);
-        return bitmap;
+        mIconSize = mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
     }
 
     public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
         if (!(drawable instanceof AdaptiveIconDrawable)) {
             return drawable;
         }
-        AdaptiveIconDrawable d =
-            (AdaptiveIconDrawable) drawable.getConstantState().newDrawable().mutate();
-        getShadowBitmap(d);
-        Bitmap iconbitmap = createIconBitmap(d);
-        return new BitmapDrawable(mRes, iconbitmap);
+        Bitmap shadow = getShadowBitmap((AdaptiveIconDrawable) drawable);
+        return new ShadowDrawable(shadow, drawable);
     }
 
     private Bitmap getShadowBitmap(AdaptiveIconDrawable d) {
-        if (mShadowBitmap != null) {
-            return mShadowBitmap;
+        int shadowSize = Math.max(mIconSize, d.getIntrinsicHeight());
+        synchronized (mShadowCache) {
+            Bitmap shadow = mShadowCache.get(shadowSize);
+            if (shadow != null) {
+                return shadow;
+            }
         }
 
-        mShadowBitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ALPHA_8);
-        mCanvas.setBitmap(mShadowBitmap);
+        d.setBounds(0, 0, shadowSize, shadowSize);
 
-        // Draw key shadow
-        mPaint.setColor(Color.TRANSPARENT);
-        float blur = BLUR_FACTOR * mIconSize;
-        mPaint.setShadowLayer(blur, 0, mShadowInset, KEY_SHADOW_ALPHA << 24);
-        d.setBounds(mShadowInset, mShadowInset, mIconSize - mShadowInset, mIconSize - mShadowInset);
-        mCanvas.drawPath(d.getIconMask(), mPaint);
+        float blur = ICON_SIZE_BLUR_FACTOR * shadowSize;
+        float keyShadowDistance = ICON_SIZE_KEY_SHADOW_DELTA_FACTOR * shadowSize;
+
+        int bitmapSize = (int) (shadowSize + 2 * blur + keyShadowDistance);
+        Bitmap shadow = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
+
+        Canvas canvas = new Canvas(shadow);
+        canvas.translate(blur + keyShadowDistance / 2, blur);
+
+        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        paint.setColor(Color.TRANSPARENT);
 
         // Draw ambient shadow
-        mPaint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
-        d.setBounds(mShadowInset, 2 * mShadowInset, mIconSize - mShadowInset, mIconSize);
-        mCanvas.drawPath(d.getIconMask(), mPaint);
-        mPaint.clearShadowLayer();
+        paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
+        canvas.drawPath(d.getIconMask(), paint);
 
-        return mShadowBitmap;
+        // Draw key shadow
+        canvas.translate(0, keyShadowDistance);
+        paint.setShadowLayer(blur, 0, 0, KEY_SHADOW_ALPHA << 24);
+        canvas.drawPath(d.getIconMask(), paint);
+
+        canvas.setBitmap(null);
+        synchronized (mShadowCache) {
+            mShadowCache.put(shadowSize, shadow);
+        }
+        return shadow;
+    }
+
+    public Drawable getBadgeDrawable(int foregroundRes, int backgroundColor) {
+        return getBadgedDrawable(null, foregroundRes, backgroundColor);
+    }
+
+    public Drawable getBadgedDrawable(Drawable base, int foregroundRes, int backgroundColor) {
+        Resources sysRes = Resources.getSystem();
+
+        Drawable badgeShadow = sysRes.getDrawable(
+                com.android.internal.R.drawable.ic_corp_icon_badge_shadow);
+
+        Drawable badgeColor = sysRes.getDrawable(
+                com.android.internal.R.drawable.ic_corp_icon_badge_color)
+                .getConstantState().newDrawable().mutate();
+        badgeColor.setTint(backgroundColor);
+
+        Drawable badgeForeground = sysRes.getDrawable(foregroundRes);
+
+        Drawable[] drawables = base == null
+                ? new Drawable[] {badgeShadow, badgeColor, badgeForeground }
+                : new Drawable[] {base, badgeShadow, badgeColor, badgeForeground };
+        return new LayerDrawable(drawables);
+    }
+
+    /**
+     * A drawable which draws a shadow bitmap behind a drawable
+     */
+    private static class ShadowDrawable extends DrawableWrapper {
+
+        final MyConstantState mState;
+
+        public ShadowDrawable(Bitmap shadow, Drawable dr) {
+            super(dr);
+            mState = new MyConstantState(shadow, dr.getConstantState());
+        }
+
+        ShadowDrawable(MyConstantState state) {
+            super(state.mChildState.newDrawable());
+            mState = state;
+        }
+
+        @Override
+        public ConstantState getConstantState() {
+            return mState;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            Rect bounds = getBounds();
+            canvas.drawBitmap(mState.mShadow, null, bounds, mState.mPaint);
+            canvas.save();
+            // Ratio of child drawable size to shadow bitmap size
+            float factor = 1 / (1 + 2 * ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR);
+
+            canvas.translate(
+                    bounds.width() * factor *
+                            (ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR / 2),
+                    bounds.height() * factor * ICON_SIZE_BLUR_FACTOR);
+            canvas.scale(factor, factor);
+            super.draw(canvas);
+            canvas.restore();
+        }
+
+        private static class MyConstantState extends ConstantState {
+
+            final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+            final Bitmap mShadow;
+            final ConstantState mChildState;
+
+            MyConstantState(Bitmap shadow, ConstantState childState) {
+                mShadow = shadow;
+                mChildState = childState;
+            }
+
+            @Override
+            public Drawable newDrawable() {
+                return new ShadowDrawable(this);
+            }
+
+            @Override
+            public int getChangingConfigurations() {
+                return mChildState.getChangingConfigurations();
+            }
+        }
     }
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1a71679..9d40895 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -295,7 +295,15 @@
 
     @Override
     protected void onDetachedFromWindow() {
-        getViewRootImpl().removeWindowStoppedCallback(this);
+        ViewRootImpl viewRoot = getViewRootImpl();
+        // It's possible to create a SurfaceView using the default constructor and never
+        // attach it to a view hierarchy, this is a common use case when dealing with
+        // OpenGL. A developer will probably create a new GLSurfaceView, and let it manage
+        // the lifecycle. Instead of attaching it to a view, he/she can just pass
+        // the SurfaceHolder forward, most live wallpapers do it.
+        if (viewRoot != null) {
+            viewRoot.removeWindowStoppedCallback(this);
+        }
 
         mAttachedToWindow = false;
         if (mGlobalListenersAdded) {
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 8f0b6c1..8ed0762 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -31,6 +31,8 @@
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.service.autofill.AutofillService;
+import android.service.autofill.FillEventHistory;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -335,6 +337,20 @@
     }
 
     /**
+     * Should always be called from {@link AutofillService#getFillEventHistory()}.
+     *
+     * @hide
+     */
+    @Nullable public FillEventHistory getFillEventHistory() {
+        try {
+            return mService.getFillEventHistory();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return null;
+        }
+    }
+
+    /**
      * Explicitly requests a new autofill context.
      *
      * <p>Normally, the autofill context is automatically started when autofillable views are
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 68b3ccabc..df777c4 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -19,6 +19,7 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.service.autofill.FillEventHistory;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
@@ -33,6 +34,7 @@
     int startSession(IBinder activityToken, IBinder windowToken, in IBinder appCallback,
             in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
             boolean hasCallback, int flags, String packageName);
+    FillEventHistory getFillEventHistory();
     boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
     void setWindow(int sessionId, in IBinder windowToken);
     void updateSession(int sessionId, in AutofillId id, in Rect bounds,
diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml
deleted file mode 100644
index 8917431..0000000
--- a/core/res/res/drawable/ic_corp_badge.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="20.0dp"
-        android:height="20.0dp"
-        android:viewportWidth="20.0"
-        android:viewportHeight="20.0">
-    <path
-        android:pathData="M10.0,10.0m-10.0,0.0a10.0,10.0 0.0,1.0 1.0,20.0 0.0a10.0,10.0 0.0,1.0 1.0,-20.0 0.0"
-        android:fillColor="#FF5722"/>
-    <path
-        android:pathData="M15.2,6.2L4.8,6.2c-0.5,0.0 -0.9,0.4 -0.9,1.0L3.9,10.0c0.0,0.5 0.4,1.0 0.9,1.0l3.8,0.0l0.0,-1.0l2.9,0.0l0.0,1.0l3.8,0.0c0.5,0.0 1.0,-0.4 1.0,-1.0L16.3,7.1C16.2,6.6 15.8,6.2 15.2,6.2z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M8.6,12.9l0.0,-1.0L4.3,11.9l0.0,2.4c0.0,0.5 0.4,0.9 0.9,0.9l9.5,0.0c0.5,0.0 0.9,-0.4 0.9,-0.9l0.0,-2.4l-4.3,0.0l0.0,1.0L8.6,12.9z"
-        android:fillColor="#FFFFFF"/>
-    <path
-        android:pathData="M7.1,5.2l0.0,1.0 1.0,0.0 0.0,-1.0 3.799999,0.0 0.0,1.0 1.0,0.0 0.0,-1.0 -1.0,-0.9 -3.799999,0.0z"
-        android:fillColor="#FFFFFF"/>
-</vector>
diff --git a/core/res/res/drawable/ic_instant_icon_badge_bolt.xml b/core/res/res/drawable/ic_instant_icon_badge_bolt.xml
new file mode 100644
index 0000000..08512b7
--- /dev/null
+++ b/core/res/res/drawable/ic_instant_icon_badge_bolt.xml
@@ -0,0 +1,29 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="64.0dp"
+        android:height="64.0dp"
+        android:viewportWidth="64.0"
+        android:viewportHeight="64.0">
+
+    <!--
+     The path is similar to ic_corp_icon_badge_case, such that it positions on top of
+     ic_corp_icon_badge_shadow.
+    -->
+    <path
+        android:pathData="M43.9 50.9h4v8l6-12h-4v-8l-6 12z"
+        android:fillColor="#757575"/>
+</vector>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 937fc6f..536906c 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -171,6 +171,9 @@
     <color name="profile_badge_2">#ff000000</color><!-- Black -->
     <color name="profile_badge_3">#ff22f033</color><!-- Green -->
 
+    <!-- Default instant app badge color -->
+    <color name="instant_app_badge">#FFFFFFFF</color><!-- White -->
+
     <!-- Multi-sim sim colors -->
     <color name="Teal_700">#ff00796b</color>
     <color name="Teal_800">#ff00695c</color>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f2da845..907294d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1322,6 +1322,7 @@
   <java-symbol type="drawable" name="ic_corp_user_badge" />
   <java-symbol type="drawable" name="ic_corp_badge_no_background" />
   <java-symbol type="drawable" name="ic_corp_statusbar_icon" />
+  <java-symbol type="drawable" name="ic_instant_icon_badge_bolt" />
   <java-symbol type="drawable" name="emulator_circular_window_overlay" />
 
   <java-symbol type="drawable" name="sim_light_blue" />
@@ -1353,6 +1354,7 @@
   <java-symbol type="color" name="profile_badge_1" />
   <java-symbol type="color" name="profile_badge_2" />
   <java-symbol type="color" name="profile_badge_3" />
+  <java-symbol type="color" name="instant_app_badge" />
 
   <java-symbol type="layout" name="action_bar_home" />
   <java-symbol type="layout" name="action_bar_title_item" />
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index b222a6d..68f46ad 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -646,7 +646,10 @@
      *
      * <p>Following this call {@link #hasAltitude} will return false,
      * and {@link #getAltitude} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
      */
+    @Deprecated
     public void removeAltitude() {
         mAltitude = 0.0f;
         mFieldsMask &= ~HAS_ALTITUDE_MASK;
@@ -683,7 +686,10 @@
      *
      * <p>Following this call {@link #hasSpeed} will return false,
      * and {@link #getSpeed} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
      */
+    @Deprecated
     public void removeSpeed() {
         mSpeed = 0.0f;
         mFieldsMask &= ~HAS_SPEED_MASK;
@@ -733,7 +739,10 @@
      *
      * <p>Following this call {@link #hasBearing} will return false,
      * and {@link #getBearing} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
      */
+    @Deprecated
     public void removeBearing() {
         mBearing = 0.0f;
         mFieldsMask &= ~HAS_BEARING_MASK;
@@ -790,7 +799,10 @@
      *
      * <p>Following this call {@link #hasAccuracy} will return false, and
      * {@link #getAccuracy} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
      */
+    @Deprecated
     public void removeAccuracy() {
         mHorizontalAccuracyMeters = 0.0f;
         mFieldsMask &= ~HAS_HORIZONTAL_ACCURACY_MASK;
@@ -839,7 +851,11 @@
      *
      * <p>Following this call {@link #hasVerticalAccuracy} will return false, and
      * {@link #getVerticalAccuracyMeters} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
      */
+    @Deprecated
     public void removeVerticalAccuracy() {
         mVerticalAccuracyMeters = 0.0f;
         mFieldsMask &= ~HAS_VERTICAL_ACCURACY_MASK;
@@ -883,7 +899,11 @@
      *
      * <p>Following this call {@link #hasSpeedAccuracy} will return false, and
      * {@link #getSpeedAccuracyMetersPerSecond} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
      */
+    @Deprecated
     public void removeSpeedAccuracy() {
         mSpeedAccuracyMetersPerSecond = 0.0f;
         mFieldsMask &= ~HAS_SPEED_ACCURACY_MASK;
@@ -927,7 +947,11 @@
      *
      * <p>Following this call {@link #hasBearingAccuracy} will return false, and
      * {@link #getBearingAccuracyDegrees} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
      */
+    @Deprecated
     public void removeBearingAccuracy() {
         mBearingAccuracyDegrees = 0.0f;
         mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 10f3b63..c109704 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -46,6 +46,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.format.Formatter;
+import android.util.IconDrawableFactory;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -95,6 +96,7 @@
 
     final Context mContext;
     final PackageManager mPm;
+    final IconDrawableFactory mDrawableFactory;
     final IPackageManager mIpm;
     final UserManager mUm;
     final StorageStatsManager mStats;
@@ -132,6 +134,7 @@
     private ApplicationsState(Application app) {
         mContext = app;
         mPm = mContext.getPackageManager();
+        mDrawableFactory = IconDrawableFactory.newInstance(mContext);
         mIpm = AppGlobals.getPackageManager();
         mUm = mContext.getSystemService(UserManager.class);
         mStats = mContext.getSystemService(StorageStatsManager.class);
@@ -327,7 +330,7 @@
             return;
         }
         synchronized (entry) {
-            entry.ensureIconLocked(mContext, mPm);
+            entry.ensureIconLocked(mContext, mDrawableFactory);
         }
     }
 
@@ -943,7 +946,7 @@
                             AppEntry entry = mAppEntries.get(i);
                             if (entry.icon == null || !entry.mounted) {
                                 synchronized (entry) {
-                                    if (entry.ensureIconLocked(mContext, mPm)) {
+                                    if (entry.ensureIconLocked(mContext, mDrawableFactory)) {
                                         if (!mRunning) {
                                             mRunning = true;
                                             Message m = mMainHandler.obtainMessage(
@@ -1266,10 +1269,10 @@
             }
         }
 
-        boolean ensureIconLocked(Context context, PackageManager pm) {
+        boolean ensureIconLocked(Context context, IconDrawableFactory drawableFactory) {
             if (this.icon == null) {
                 if (this.apkFile.exists()) {
-                    this.icon = getBadgedIcon(pm);
+                    this.icon = drawableFactory.getBadgedIcon(info);
                     return true;
                 } else {
                     this.mounted = false;
@@ -1281,19 +1284,13 @@
                 // its icon.
                 if (this.apkFile.exists()) {
                     this.mounted = true;
-                    this.icon = getBadgedIcon(pm);
+                    this.icon = drawableFactory.getBadgedIcon(info);
                     return true;
                 }
             }
             return false;
         }
 
-        private Drawable getBadgedIcon(PackageManager pm) {
-            // Do badging ourself so that it comes from the user of the app not the current user.
-            return pm.getUserBadgedIcon(pm.loadUnbadgedItemIcon(info, info),
-                    new UserHandle(UserHandle.getUserId(info.uid)));
-        }
-
         public String getVersion(Context context) {
             try {
                 return context.getPackageManager().getPackageInfo(info.packageName, 0).versionName;
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 231fc69..3f826cc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -27,6 +27,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.IconDrawableFactory;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -48,10 +49,12 @@
 
     private final PackageManager mPackageManager;
     private final Context mContext;
+    private final IconDrawableFactory mDrawableFactory;
 
     public RecentLocationApps(Context context) {
         mContext = context;
         mPackageManager = context.getPackageManager();
+        mDrawableFactory = IconDrawableFactory.newInstance(context);
     }
 
     /**
@@ -146,8 +149,7 @@
             }
 
             final UserHandle userHandle = new UserHandle(userId);
-            Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
-            Drawable icon = mPackageManager.getUserBadgedIcon(appIcon, userHandle);
+            Drawable icon = mDrawableFactory.getBadgedIcon(appInfo, userId);
             CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
             CharSequence badgedAppLabel = mPackageManager.getUserBadgedLabel(appLabel, userHandle);
             if (appLabel.toString().contentEquals(badgedAppLabel)) {
diff --git a/packages/SystemUI/res/drawable/ic_pause_white_24dp.xml b/packages/SystemUI/res/drawable/ic_pause_white.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_pause_white_24dp.xml
rename to packages/SystemUI/res/drawable/ic_pause_white.xml
diff --git a/packages/SystemUI/res/drawable/ic_play_arrow_white_24dp.xml b/packages/SystemUI/res/drawable/ic_play_arrow_white.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_play_arrow_white_24dp.xml
rename to packages/SystemUI/res/drawable/ic_play_arrow_white.xml
diff --git a/packages/SystemUI/res/drawable/ic_skip_next_white.xml b/packages/SystemUI/res/drawable/ic_skip_next_white.xml
new file mode 100644
index 0000000..040c7e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_skip_next_white.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_skip_previous_white.xml b/packages/SystemUI/res/drawable/ic_skip_previous_white.xml
new file mode 100644
index 0000000..b9b94b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_skip_previous_white.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/tv_pip_controls.xml b/packages/SystemUI/res/layout/tv_pip_controls.xml
index c6bcd32..61ac6f6 100644
--- a/packages/SystemUI/res/layout/tv_pip_controls.xml
+++ b/packages/SystemUI/res/layout/tv_pip_controls.xml
@@ -40,7 +40,7 @@
         android:layout_width="100dp"
         android:layout_height="wrap_content"
         android:layout_marginStart="-50dp"
-        android:src="@drawable/ic_pause_white_24dp"
+        android:src="@drawable/ic_pause_white"
         android:text="@string/pip_pause"
         android:visibility="gone" />
 </merge>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 734b9ee..b87da27 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1897,6 +1897,18 @@
     <!-- PiP minimize description. [CHAR LIMIT=NONE] -->
     <string name="pip_minimize_description" translatable="false">Drag or fling the PIP to the edges of the screen to minimize it.</string>
 
+    <!-- Button to play the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
+    <string name="pip_play">Play</string>
+
+    <!-- Button to pause the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
+    <string name="pip_pause">Pause</string>
+
+    <!-- Button to skip to the next media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
+    <string name="pip_skip_to_next">Skip to next</string>
+
+    <!-- Button to skip to the prev media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
+    <string name="pip_skip_to_prev">Skip to previous</string>
+
     <!-- Tuner string -->
     <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
     <!-- Tuner string -->
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index 41626fc..e578068 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -23,8 +23,4 @@
     <string name="pip_close">Close PIP</string>
     <!-- Button to move picture-in-picture (PIP) screen to the fullscreen in PIP menu [CHAR LIMIT=30] -->
     <string name="pip_fullscreen">Full screen</string>
-    <!-- Button to play the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
-    <string name="pip_play">Play</string>
-    <!-- Button to pause the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
-    <string name="pip_pause">Pause</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
index 3a4caa9..62ec09b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMediaController.java
@@ -48,6 +48,8 @@
 
     private static final String ACTION_PLAY = "com.android.systemui.pip.phone.PLAY";
     private static final String ACTION_PAUSE = "com.android.systemui.pip.phone.PAUSE";
+    private static final String ACTION_NEXT = "com.android.systemui.pip.phone.NEXT";
+    private static final String ACTION_PREV = "com.android.systemui.pip.phone.PREV";
 
     /**
      * A listener interface to receive notification on changes to the media actions.
@@ -67,6 +69,8 @@
 
     private RemoteAction mPauseAction;
     private RemoteAction mPlayAction;
+    private RemoteAction mNextAction;
+    private RemoteAction mPrevAction;
 
     private BroadcastReceiver mPlayPauseActionReceiver = new BroadcastReceiver() {
         @Override
@@ -76,6 +80,10 @@
                 mMediaController.getTransportControls().play();
             } else if (action.equals(ACTION_PAUSE)) {
                 mMediaController.getTransportControls().pause();
+            } else if (action.equals(ACTION_NEXT)) {
+                mMediaController.getTransportControls().skipToNext();
+            } else if (action.equals(ACTION_PREV)) {
+                mMediaController.getTransportControls().skipToPrevious();
             }
         }
     };
@@ -95,6 +103,8 @@
         IntentFilter mediaControlFilter = new IntentFilter();
         mediaControlFilter.addAction(ACTION_PLAY);
         mediaControlFilter.addAction(ACTION_PAUSE);
+        mediaControlFilter.addAction(ACTION_NEXT);
+        mediaControlFilter.addAction(ACTION_PREV);
         mContext.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter);
 
         createMediaActions();
@@ -143,11 +153,21 @@
         int state = mMediaController.getPlaybackState().getState();
         boolean isPlaying = MediaSession.isActiveState(state);
         long actions = mMediaController.getPlaybackState().getActions();
+
+        // Prev action
+        mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
+        mediaActions.add(mPrevAction);
+
+        // Play/pause action
         if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) {
             mediaActions.add(mPlayAction);
         } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) {
             mediaActions.add(mPauseAction);
         }
+
+        // Next action
+        mNextAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0);
+        mediaActions.add(mNextAction);
         return mediaActions;
     }
 
@@ -157,15 +177,27 @@
     private void createMediaActions() {
         String pauseDescription = mContext.getString(R.string.pip_pause);
         mPauseAction = new RemoteAction(Icon.createWithResource(mContext,
-                R.drawable.ic_pause_white_24dp), pauseDescription, pauseDescription,
+                R.drawable.ic_pause_white), pauseDescription, pauseDescription,
                         PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PAUSE),
                                 FLAG_UPDATE_CURRENT));
 
         String playDescription = mContext.getString(R.string.pip_play);
         mPlayAction = new RemoteAction(Icon.createWithResource(mContext,
-                R.drawable.ic_play_arrow_white_24dp), playDescription, playDescription,
+                R.drawable.ic_play_arrow_white), playDescription, playDescription,
                         PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PLAY),
                                 FLAG_UPDATE_CURRENT));
+
+        String nextDescription = mContext.getString(R.string.pip_skip_to_next);
+        mNextAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.ic_skip_next_white), nextDescription, nextDescription,
+                        PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NEXT),
+                                FLAG_UPDATE_CURRENT));
+
+        String prevDescription = mContext.getString(R.string.pip_skip_to_prev);
+        mPrevAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.ic_skip_previous_white), prevDescription, prevDescription,
+                        PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PREV),
+                                FLAG_UPDATE_CURRENT));
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 982b808..79ac816 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -412,16 +412,26 @@
         } else {
             actionsContainer.setVisibility(View.VISIBLE);
             if (mActionsGroup != null) {
-                mActionsGroup.removeAllViews();
+                // Hide extra views
+                for (int i = mActions.size(); i < mActionsGroup.getChildCount(); i++) {
+                    mActionsGroup.getChildAt(i).setVisibility(View.GONE);
+                }
+                // Add needed views
+                final LayoutInflater inflater = LayoutInflater.from(this);
+                while (mActionsGroup.getChildCount() < mActions.size()) {
+                    final ImageView actionView = (ImageView) inflater.inflate(
+                            R.layout.pip_menu_action, mActionsGroup, false);
+                    mActionsGroup.addView(actionView);
+                }
 
                 // Recreate the layout
                 final boolean isLandscapePip = stackBounds != null &&
                         (stackBounds.width() > stackBounds.height());
-                final LayoutInflater inflater = LayoutInflater.from(this);
                 for (int i = 0; i < mActions.size(); i++) {
                     final RemoteAction action = mActions.get(i);
-                    final ImageView actionView = (ImageView) inflater.inflate(
-                            R.layout.pip_menu_action, mActionsGroup, false);
+                    final ImageView actionView = (ImageView) mActionsGroup.getChildAt(i);
+
+                    // TODO: Check if the action drawable has changed before we reload it
                     action.getIcon().loadDrawableAsync(this, d -> {
                         d.setTint(Color.WHITE);
                         actionView.setImageDrawable(d);
@@ -439,12 +449,11 @@
                         actionView.setAlpha(DISABLED_ACTION_ALPHA);
                         actionView.setEnabled(false);
                     }
-                    if (isLandscapePip && i > 0) {
-                        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
-                                actionView.getLayoutParams();
-                        lp.leftMargin = mBetweenActionPaddingLand;
-                    }
-                    mActionsGroup.addView(actionView);
+
+                    // Update the margin between actions
+                    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
+                            actionView.getLayoutParams();
+                    lp.leftMargin = (isLandscapePip && i > 0) ? mBetweenActionPaddingLand : 0;
                 }
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
index 4c81907..acea3b6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
@@ -186,10 +186,10 @@
         } else {
             mPlayPauseButtonView.setVisibility(View.VISIBLE);
             if (state == PipManager.PLAYBACK_STATE_PLAYING) {
-                mPlayPauseButtonView.setImageResource(R.drawable.ic_pause_white_24dp);
+                mPlayPauseButtonView.setImageResource(R.drawable.ic_pause_white);
                 mPlayPauseButtonView.setText(R.string.pip_pause);
             } else {
-                mPlayPauseButtonView.setImageResource(R.drawable.ic_play_arrow_white_24dp);
+                mPlayPauseButtonView.setImageResource(R.drawable.ic_play_arrow_white);
                 mPlayPauseButtonView.setText(R.string.pip_play);
             }
         }
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 4289790..429ace6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -65,7 +65,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.ArraySet;
-import android.util.LauncherIcons;
+import android.util.IconDrawableFactory;
 import android.util.Log;
 import android.util.MutableBoolean;
 import android.view.Display;
@@ -121,6 +121,7 @@
     ActivityManager mAm;
     IActivityManager mIam;
     PackageManager mPm;
+    IconDrawableFactory mDrawableFactory;
     IPackageManager mIpm;
     AssistUtils mAssistUtils;
     WindowManager mWm;
@@ -139,7 +140,6 @@
     int mDummyThumbnailHeight;
     Paint mBgProtectionPaint;
     Canvas mBgProtectionCanvas;
-    LauncherIcons mLauncherIcons;
 
     private final Handler mHandler = new H();
 
@@ -258,6 +258,7 @@
         mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         mIam = ActivityManager.getService();
         mPm = context.getPackageManager();
+        mDrawableFactory = IconDrawableFactory.newInstance(context);
         mIpm = AppGlobals.getPackageManager();
         mAssistUtils = new AssistUtils(context);
         mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -296,8 +297,6 @@
 
         Collections.addAll(sRecentsBlacklist,
                 res.getStringArray(R.array.recents_blacklist_array));
-
-        mLauncherIcons = new LauncherIcons(context);
     }
 
     /**
@@ -840,8 +839,7 @@
             return new ColorDrawable(0xFF666666);
         }
 
-        Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(info.loadIcon(mPm));
-        return getBadgedIcon(icon, userId);
+        return mDrawableFactory.getBadgedIcon(info, info.applicationInfo, userId);
     }
 
     /**
@@ -856,8 +854,7 @@
             return new ColorDrawable(0xFF666666);
         }
 
-        Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(appInfo.loadIcon(mPm));
-        return getBadgedIcon(icon, userId);
+        return mDrawableFactory.getBadgedIcon(appInfo, userId);
     }
 
     /**
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index ad7ff1b..1b5b2c6 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -48,6 +48,7 @@
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.provider.Settings;
+import android.service.autofill.FillEventHistory;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.Slog;
@@ -398,6 +399,21 @@
         }
 
         @Override
+        public FillEventHistory getFillEventHistory() throws RemoteException {
+            UserHandle user = getCallingUserHandle();
+            int uid = getCallingUid();
+
+            synchronized (mLock) {
+                AutofillManagerServiceImpl service = peekServiceForUserLocked(user.getIdentifier());
+                if (service != null) {
+                    return service.getFillEventHistory(uid);
+                }
+            }
+
+            return null;
+        }
+
+        @Override
         public boolean restoreSession(int sessionId, IBinder activityToken, IBinder appCallback)
                 throws RemoteException {
             activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 57ef6d0..e274e18 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -48,7 +48,9 @@
 import android.provider.Settings;
 import android.service.autofill.AutofillService;
 import android.service.autofill.AutofillServiceInfo;
+import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillRequest;
+import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.text.TextUtils;
 import android.util.LocalLog;
@@ -122,6 +124,10 @@
     @GuardedBy("mLock")
     private final SparseArray<Session> mSessions = new SparseArray<>();
 
+    /** The last selection */
+    @GuardedBy("mLock")
+    private FillEventHistory mEventHistory;
+
     /**
      * Receiver of assist data from the app's {@link Activity}.
      */
@@ -500,6 +506,72 @@
         return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
     }
 
+    /**
+     * Initializes the last fill selection after an autofill service returned a new
+     * {@link FillResponse}.
+     */
+    void setLastResponse(int serviceUid, @NonNull FillResponse response) {
+        synchronized (mLock) {
+            mEventHistory = new FillEventHistory(serviceUid, response.getClientState());
+        }
+    }
+
+    /**
+     * Updates the last fill selection when an authentication was selected.
+     */
+    void setAuthenticationSelected() {
+        synchronized (mLock) {
+            mEventHistory.addEvent(
+                    new FillEventHistory.Event(FillEventHistory.Event.TYPE_AUTHENTICATION_SELECTED, null));
+        }
+    }
+
+    /**
+     * Updates the last fill selection when an dataset authentication was selected.
+     */
+    void setDatasetAuthenticationSelected(@Nullable String selectedDataset) {
+        synchronized (mLock) {
+            mEventHistory.addEvent(new FillEventHistory.Event(
+                    FillEventHistory.Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
+        }
+    }
+
+    /**
+     * Updates the last fill selection when an save Ui is shown.
+     */
+    void setSaveShown() {
+        synchronized (mLock) {
+            mEventHistory.addEvent(new FillEventHistory.Event(FillEventHistory.Event.TYPE_SAVE_SHOWN, null));
+        }
+    }
+
+    /**
+     * Updates the last fill response when a dataset was selected.
+     */
+    void setDatasetSelected(@Nullable String selectedDataset) {
+        synchronized (mLock) {
+            mEventHistory.addEvent(
+                    new FillEventHistory.Event(FillEventHistory.Event.TYPE_DATASET_SELECTED, selectedDataset));
+        }
+    }
+
+    /**
+     * Gets the fill event history.
+     *
+     * @param callingUid The calling uid
+     *
+     * @return The history or {@code null} if there is none.
+     */
+    FillEventHistory getFillEventHistory(int callingUid) {
+        synchronized (mLock) {
+            if (mEventHistory != null && mEventHistory.getServiceUid() == callingUid) {
+                return mEventHistory;
+            }
+        }
+
+        return null;
+    }
+
     void dumpLocked(String prefix, PrintWriter pw) {
         final String prefix2 = prefix + "  ";
 
@@ -528,6 +600,20 @@
                 mSessions.valueAt(i).dumpLocked(prefix2, pw);
             }
         }
+
+        if (mEventHistory == null || mEventHistory.getEvents().size() == 0) {
+            pw.print(prefix); pw.println("No event on last fill response");
+        } else {
+            pw.print(prefix); pw.println("Events of last fill response:");
+            pw.print(prefix);
+
+            int numEvents = mEventHistory.getEvents().size();
+            for (int i = 0; i < numEvents; i++) {
+                FillEventHistory.Event event = mEventHistory.getEvents().get(i);
+                pw.println("  " + i + ": eventType=" + event.getType() + " datasetId="
+                        + event.getDatasetId());
+            }
+        }
     }
 
     void destroySessionsLocked() {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 3badcfc..4d0f380 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -87,7 +87,7 @@
     private PendingRequest mPendingRequest;
 
     public interface FillServiceCallbacks {
-        void onFillRequestSuccess(@Nullable FillResponse response,
+        void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
                 @NonNull String servicePackageName, int requestId);
         void onFillRequestFailure(@Nullable CharSequence message,
                 @NonNull String servicePackageName);
@@ -252,11 +252,11 @@
     }
 
     private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
-            FillResponse response, int requestId) {
+            int callingUid, FillResponse response, int requestId) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
-                mCallbacks.onFillRequestSuccess(response, mComponentName.getPackageName(),
-                        requestId);
+                mCallbacks.onFillRequestSuccess(response, callingUid,
+                        mComponentName.getPackageName(), requestId);
             }
         });
     }
@@ -424,7 +424,7 @@
                     RemoteFillService remoteService = mWeakService.get();
                     if (remoteService != null) {
                         remoteService.dispatchOnFillRequestSuccess(
-                                PendingFillRequest.this, response, requestId);
+                                PendingFillRequest.this, getCallingUid(), response, requestId);
                     }
                 }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c92c52f..2b99614 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -229,7 +229,7 @@
 
     // FillServiceCallbacks
     @Override
-    public void onFillRequestSuccess(@Nullable FillResponse response,
+    public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
             @NonNull String servicePackageName, int requestId) {
         if (response == null) {
             if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
@@ -241,6 +241,8 @@
             return;
         }
 
+        mService.setLastResponse(serviceUid, response);
+
         if ((response.getDatasets() == null || response.getDatasets().isEmpty())
                         && response.getAuthentication() == null) {
             // Response is "empty" from an UI point of view, need to notify client.
@@ -314,6 +316,9 @@
         synchronized (mLock) {
             fillInIntent = createAuthFillInIntent(mStructure, extras);
         }
+
+        mService.setAuthenticationSelected();
+
         mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
     }
 
@@ -542,6 +547,7 @@
                 }
             }
             if (atLeastOneChanged) {
+                mService.setSaveShown();
                 getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName);
                 return false;
             }
@@ -882,12 +888,15 @@
         synchronized (mLock) {
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
+                mService.setDatasetSelected(dataset.getId());
+
                 autoFillApp(dataset);
                 return;
             }
 
             // ...or handle authentication.
             // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
+            mService.setDatasetAuthenticationSelected(dataset.getId());
             mDatasetWaitingAuth = dataset;
             setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
             final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d43fa01..8f1afa8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10685,6 +10685,13 @@
             return;
         }
 
+        // When a task is locked, dismiss the pinned stack if it exists
+        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
+                PINNED_STACK_ID);
+        if (pinnedStack != null) {
+            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
+        }
+
         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
         // is initiated by system after the pinning request was shown and locked mode is initiated
         // by an authorized app directly
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 312c310..5535d17 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4218,8 +4218,10 @@
                     }
 
                     SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
-                            libInfo.getVersion(), libInfo.getType(), libInfo.getDeclaringPackage(),
-                            getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
+                            // TODO: Remove cast for lib version once internally we support longs.
+                            (int) libInfo.getVersion(), libInfo.getType(),
+                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
+                            flags, userId));
 
                     if (result == null) {
                         result = new ArrayList<>();
@@ -17593,7 +17595,8 @@
         for (int i = 0; i < versionCount; i++) {
             SharedLibraryEntry libEntry = versionedLib.valueAt(i);
             if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
-                    libEntry.info.getVersion()) < 0) {
+                    // TODO: Remove cast for lib version once internally we support longs.
+                    (int) libEntry.info.getVersion()) < 0) {
                 continue;
             }
             // TODO: We will change version code to long, so in the new API it is long
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
index 929a73d..c314de4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceCreateProfileTest.java
@@ -27,6 +27,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.IconDrawableFactory;
 
 import com.android.server.LocalServices;
 
@@ -155,9 +156,9 @@
     public void testNumberOfBadges() {
         assertTrue("Max profiles greater than number of badges",
                 UserManagerService.MAX_MANAGED_PROFILES
-                <= ApplicationPackageManager.CORP_BADGE_COLORS.length);
+                <= IconDrawableFactory.CORP_BADGE_COLORS.length);
         assertEquals("Num colors doesn't match number of badge labels",
-                ApplicationPackageManager.CORP_BADGE_COLORS.length,
+                IconDrawableFactory.CORP_BADGE_COLORS.length,
                 ApplicationPackageManager.CORP_BADGE_LABEL_RES_ID.length);
     }