Merge "Switching Native MIDI API to an "opaque pointers" model."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 71e6af7..e728897 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -242,7 +242,7 @@
 $(call add-clean-step, rm -f $(OUT_DIR)/target/common/obj/APPS/FeatureSplit2_intermediates/src/com/android/test/split/feature/R.java)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
-
+$(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/platformprotos_intermediates)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index d837786..4c900b7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,6 +20,7 @@
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+    field public static final java.lang.String BIND_AUTOFILL = "android.permission.BIND_AUTOFILL";
     field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL";
     field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
@@ -298,8 +299,6 @@
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
-    field public static final int autoFillHint = 16844121; // 0x1010559
-    field public static final int autoFillMode = 16844116; // 0x1010554
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
     field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -312,6 +311,8 @@
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
     field public static final int autoVerify = 16844014; // 0x10104ee
+    field public static final int autofillHint = 16844121; // 0x1010559
+    field public static final int autofillMode = 16844116; // 0x1010554
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -1778,6 +1779,7 @@
   public static final class R.id {
     ctor public R.id();
     field public static final int accessibilityActionContextClick = 16908348; // 0x102003c
+    field public static final int accessibilityActionMoveWindow = 16908354; // 0x1020042
     field public static final int accessibilityActionScrollDown = 16908346; // 0x102003a
     field public static final int accessibilityActionScrollLeft = 16908345; // 0x1020039
     field public static final int accessibilityActionScrollRight = 16908347; // 0x102003b
@@ -6551,9 +6553,12 @@
   public class AssistStructure implements android.os.Parcelable {
     ctor public AssistStructure();
     method public int describeContents();
+    method public long getAcquisitionEndTime();
+    method public long getAcquisitionStartTime();
     method public android.content.ComponentName getActivityComponent();
     method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int);
     method public int getWindowNodeCount();
+    method public boolean isHomeActivity();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR;
   }
@@ -6561,11 +6566,10 @@
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
     method public int getAutoFillHint();
-    method public android.view.autofill.AutoFillId getAutoFillId();
-    method public java.lang.String[] getAutoFillOptions();
-    method public deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public android.view.autofill.AutofillId getAutofillId();
+    method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -6607,6 +6611,7 @@
     method public boolean isFocusable();
     method public boolean isFocused();
     method public boolean isLongClickable();
+    method public boolean isOpaque();
     method public boolean isSelected();
     field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
     field public static final int TEXT_STYLE_BOLD = 1; // 0x1
@@ -7986,7 +7991,7 @@
   public static final class AdvertisingSetParameters.Builder {
     ctor public AdvertisingSetParameters.Builder();
     method public android.bluetooth.le.AdvertisingSetParameters build();
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
@@ -8183,18 +8188,17 @@
 
 package android.companion {
 
-  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+  public final class AssociationRequest implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
   }
 
-  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
-    method public android.companion.AssociationRequest<F> build();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
-    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
-    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  public static final class AssociationRequest.Builder {
+    ctor public AssociationRequest.Builder();
+    method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
+    method public android.companion.AssociationRequest build();
+    method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
   }
 
   public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8213,6 +8217,7 @@
 
   public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
     method public int describeContents();
+    method public static int getRenamePrefixLengthLimit();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
   }
@@ -8221,11 +8226,13 @@
     ctor public BluetoothLEDeviceFilter.Builder();
     method public android.companion.BluetoothLEDeviceFilter build();
     method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
     method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
   }
 
   public final class CompanionDeviceManager {
-    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
     method public void disassociate(java.lang.String);
     method public java.util.List<java.lang.String> getAssociations();
     field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8240,6 +8247,18 @@
   public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
   }
 
+  public final class WifiDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
+  }
+
+  public static final class WifiDeviceFilter.Builder {
+    ctor public WifiDeviceFilter.Builder();
+    method public android.companion.WifiDeviceFilter build();
+    method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
 }
 
 package android.content {
@@ -12504,6 +12523,7 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
+    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12905,6 +12925,8 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -12980,6 +13002,8 @@
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -13498,6 +13522,8 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -13637,7 +13663,7 @@
   }
 
   public class Shader {
-    ctor public Shader();
+    ctor public deprecated Shader();
     method public boolean getLocalMatrix(android.graphics.Matrix);
     method public void setLocalMatrix(android.graphics.Matrix);
   }
@@ -13682,6 +13708,8 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
+    method public void set(float, float, int[], float[]);
+    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -13709,9 +13737,12 @@
   public static abstract interface Typeface.FontRequestCallback {
     method public abstract void onTypefaceRequestFailed(int);
     method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
   }
 
   public class Xfermode {
@@ -20986,7 +21017,7 @@
   }
 
   public class AudioManager {
-    method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
+    method public deprecated int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
     method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
@@ -21023,7 +21054,7 @@
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
-    method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public deprecated int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public deprecated void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
@@ -26479,7 +26510,8 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifier(android.net.wifi.aware.PeerHandle, byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -26567,7 +26599,8 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifier(int, byte[], byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
+    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
@@ -34090,7 +34123,7 @@
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
-    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
+    method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -34206,6 +34239,11 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
     field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
@@ -36688,15 +36726,15 @@
 
 package android.service.autofill {
 
-  public abstract class AutoFillService extends android.app.Service {
-    ctor public AutoFillService();
+  public abstract class AutofillService extends android.app.Service {
+    ctor public AutofillService();
     method public final void disableSelf();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
@@ -36710,7 +36748,7 @@
     ctor public Dataset.Builder(android.widget.RemoteViews);
     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 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);
   }
 
   public final class FillCallback {
@@ -36750,7 +36788,7 @@
 
   public static final class SaveInfo.Builder {
     ctor public SaveInfo.Builder(int);
-    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
@@ -39788,7 +39826,7 @@
     method public int getSimState();
     method public int getSimState(int);
     method public java.lang.String getSubscriberId();
-    method public java.lang.String getVisualVoicemailPackageName(android.telecom.PhoneAccountHandle);
+    method public java.lang.String getVisualVoicemailPackageName();
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public int getVoiceNetworkType();
@@ -39928,9 +39966,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
-    field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
-    field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
-    field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
     field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
     field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
     field public final java.lang.String clientPrefix;
@@ -44961,8 +44996,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public void autoFill(android.view.autofill.AutoFillValue);
-    method public void autoFillVirtual(int, android.view.autofill.AutoFillValue);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofillVirtual(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -45016,7 +45051,7 @@
     method public boolean dispatchNestedScroll(int, int, int, int, int[]);
     method public void dispatchPointerCaptureChanged(boolean);
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void dispatchProvideAutoFillStructure(android.view.ViewStructure, int);
+    method public void dispatchProvideAutofillStructure(android.view.ViewStructure, int);
     method public void dispatchProvideStructure(android.view.ViewStructure);
     method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
@@ -45052,11 +45087,10 @@
     method public float getAlpha();
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
-    method public int getAutoFillHint();
-    method public int getAutoFillMode();
-    method public final deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public int getAutofillHint();
+    method public int getAutofillMode();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
     method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -45142,7 +45176,7 @@
     method public float getPivotX();
     method public float getPivotY();
     method public android.view.PointerIcon getPointerIcon();
-    method public int getResolvedAutoFillMode();
+    method public int getResolvedAutofillMode();
     method public android.content.res.Resources getResources();
     method public final boolean getRevealOnFocusHint();
     method public final int getRight();
@@ -45301,8 +45335,8 @@
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void onProvideAutoFillStructure(android.view.ViewStructure, int);
-    method public void onProvideAutoFillVirtualStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int);
     method public void onProvideStructure(android.view.ViewStructure);
     method public void onProvideVirtualStructure(android.view.ViewStructure);
     method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int);
@@ -45374,8 +45408,8 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutoFillHint(int);
-    method public void setAutoFillMode(int);
+    method public void setAutofillHint(int);
+    method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -45517,28 +45551,28 @@
     field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
     field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
     field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
+    field public static final int AUTOFILL_HINT_EMAIL_ADDRESS = 1; // 0x1
+    field public static final int AUTOFILL_HINT_NAME = 2; // 0x2
+    field public static final int AUTOFILL_HINT_NONE = 0; // 0x0
+    field public static final int AUTOFILL_HINT_PASSWORD = 8; // 0x8
+    field public static final int AUTOFILL_HINT_PHONE = 16; // 0x10
+    field public static final int AUTOFILL_HINT_POSTAL_ADDRESS = 32; // 0x20
+    field public static final int AUTOFILL_HINT_POSTAL_CODE = 64; // 0x40
+    field public static final int AUTOFILL_HINT_USERNAME = 4; // 0x4
+    field public static final int AUTOFILL_MODE_AUTO = 1; // 0x1
+    field public static final int AUTOFILL_MODE_INHERIT = 0; // 0x0
+    field public static final int AUTOFILL_MODE_MANUAL = 2; // 0x2
     field public static final int AUTOFILL_TYPE_DATE = 4; // 0x4
     field public static final int AUTOFILL_TYPE_LIST = 3; // 0x3
     field public static final int AUTOFILL_TYPE_NONE = 0; // 0x0
     field public static final int AUTOFILL_TYPE_TEXT = 1; // 0x1
     field public static final int AUTOFILL_TYPE_TOGGLE = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
-    field public static final int AUTO_FILL_HINT_EMAIL_ADDRESS = 1; // 0x1
-    field public static final int AUTO_FILL_HINT_NAME = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_NONE = 0; // 0x0
-    field public static final int AUTO_FILL_HINT_PASSWORD = 8; // 0x8
-    field public static final int AUTO_FILL_HINT_PHONE = 16; // 0x10
-    field public static final int AUTO_FILL_HINT_POSTAL_ADDRESS = 32; // 0x20
-    field public static final int AUTO_FILL_HINT_POSTAL_CODE = 64; // 0x40
-    field public static final int AUTO_FILL_HINT_USERNAME = 4; // 0x4
-    field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
-    field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
-    field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
     field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
     field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
     field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -46100,7 +46134,7 @@
     method public abstract int getLayoutDirection();
     method public abstract android.view.ViewParent getParent();
     method public abstract android.view.ViewParent getParentForAccessibility();
-    method public default int getResolvedAutoFillMode();
+    method public default int getResolvedAutofillMode();
     method public abstract int getTextAlignment();
     method public abstract int getTextDirection();
     method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -46179,7 +46213,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure asyncNewChildForAutofill(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46188,15 +46222,14 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure newChildForAutofill(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
-    method public abstract void setAutoFillHint(int);
-    method public abstract void setAutoFillOptions(java.lang.String[]);
-    method public abstract deprecated void setAutoFillType(android.view.autofill.AutoFillType);
-    method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
+    method public abstract void setAutofillHint(int);
+    method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
+    method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
     method public abstract void setCheckable(boolean);
     method public abstract void setChecked(boolean);
     method public abstract void setChildCount(int);
@@ -46213,6 +46246,7 @@
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
     method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setOpaque(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
@@ -46930,6 +46964,8 @@
     field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_X = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_X";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_Y = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_Y";
     field public static final java.lang.String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
     field public static final java.lang.String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
@@ -46986,6 +47022,7 @@
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_EXPAND;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_FOCUS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_LONG_CLICK;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_MOVE_WINDOW;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_HTML_ELEMENT;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PASTE;
@@ -47110,6 +47147,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo getRoot();
     method public java.lang.CharSequence getTitle();
     method public int getType();
+    method public boolean inPictureInPicture();
     method public boolean isAccessibilityFocused();
     method public boolean isActive();
     method public boolean isFocused();
@@ -47445,60 +47483,46 @@
 
 package android.view.autofill {
 
-  public final class AutoFillId implements android.os.Parcelable {
+  public final class AutofillId implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillId> CREATOR;
   }
 
-  public final class AutoFillManager {
-    method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+  public final class AutofillManager {
+    method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void reset();
-    method public void startAutoFillRequest(android.view.View);
-    method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutoFillRequest(android.view.View);
-    method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
-    method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+    method public void startAutofillRequest(android.view.View);
+    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
+    method public void stopAutofillRequest(android.view.View);
+    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
+    method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
-  public static abstract class AutoFillManager.AutofillCallback {
-    ctor public AutoFillManager.AutofillCallback();
+  public static abstract class AutofillManager.AutofillCallback {
+    ctor public AutofillManager.AutofillCallback();
     method public void onAutofillEvent(android.view.View, int);
     method public void onAutofillEventVirtual(android.view.View, int, int);
     field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
     field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
   }
 
-  public final class AutoFillType implements android.os.Parcelable {
+  public final class AutofillValue implements android.os.Parcelable {
     method public int describeContents();
-    method public static android.view.autofill.AutoFillType forDate();
-    method public static android.view.autofill.AutoFillType forList();
-    method public static android.view.autofill.AutoFillType forText();
-    method public static android.view.autofill.AutoFillType forToggle();
-    method public boolean isDate();
-    method public boolean isList();
-    method public boolean isText();
-    method public boolean isToggle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillType> CREATOR;
-  }
-
-  public final class AutoFillValue implements android.os.Parcelable {
-    method public int describeContents();
-    method public static android.view.autofill.AutoFillValue forDate(long);
-    method public static android.view.autofill.AutoFillValue forList(int);
-    method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
-    method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public static android.view.autofill.AutofillValue forDate(long);
+    method public static android.view.autofill.AutofillValue forList(int);
+    method public static android.view.autofill.AutofillValue forText(java.lang.CharSequence);
+    method public static android.view.autofill.AutofillValue forToggle(boolean);
     method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillValue> CREATOR;
   }
 
 }
diff --git a/api/system-current.txt b/api/system-current.txt
index e9af523..959adf58 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -30,6 +30,7 @@
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+    field public static final java.lang.String BIND_AUTOFILL = "android.permission.BIND_AUTOFILL";
     field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL";
     field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
@@ -159,6 +160,7 @@
     field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
     field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
     field public static final java.lang.String NFC = "android.permission.NFC";
+    field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
     field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
     field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
@@ -410,8 +412,6 @@
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
-    field public static final int autoFillHint = 16844121; // 0x1010559
-    field public static final int autoFillMode = 16844116; // 0x1010554
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
     field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -424,6 +424,8 @@
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
     field public static final int autoVerify = 16844014; // 0x10104ee
+    field public static final int autofillHint = 16844121; // 0x1010559
+    field public static final int autofillMode = 16844116; // 0x1010554
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -1894,6 +1896,7 @@
   public static final class R.id {
     ctor public R.id();
     field public static final int accessibilityActionContextClick = 16908348; // 0x102003c
+    field public static final int accessibilityActionMoveWindow = 16908354; // 0x1020042
     field public static final int accessibilityActionScrollDown = 16908346; // 0x102003a
     field public static final int accessibilityActionScrollLeft = 16908345; // 0x1020039
     field public static final int accessibilityActionScrollRight = 16908347; // 0x102003b
@@ -6800,9 +6803,12 @@
   public class AssistStructure implements android.os.Parcelable {
     ctor public AssistStructure();
     method public int describeContents();
+    method public long getAcquisitionEndTime();
+    method public long getAcquisitionStartTime();
     method public android.content.ComponentName getActivityComponent();
     method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int);
     method public int getWindowNodeCount();
+    method public boolean isHomeActivity();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR;
   }
@@ -6810,11 +6816,10 @@
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
     method public int getAutoFillHint();
-    method public android.view.autofill.AutoFillId getAutoFillId();
-    method public java.lang.String[] getAutoFillOptions();
-    method public deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public android.view.autofill.AutofillId getAutofillId();
+    method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -6856,6 +6861,7 @@
     method public boolean isFocusable();
     method public boolean isFocused();
     method public boolean isLongClickable();
+    method public boolean isOpaque();
     method public boolean isSelected();
     field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
     field public static final int TEXT_STYLE_BOLD = 1; // 0x1
@@ -8464,7 +8470,7 @@
   public static final class AdvertisingSetParameters.Builder {
     ctor public AdvertisingSetParameters.Builder();
     method public android.bluetooth.le.AdvertisingSetParameters build();
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
@@ -8683,18 +8689,17 @@
 
 package android.companion {
 
-  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+  public final class AssociationRequest implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
   }
 
-  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
-    method public android.companion.AssociationRequest<F> build();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
-    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
-    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  public static final class AssociationRequest.Builder {
+    ctor public AssociationRequest.Builder();
+    method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
+    method public android.companion.AssociationRequest build();
+    method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
   }
 
   public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8713,6 +8718,7 @@
 
   public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
     method public int describeContents();
+    method public static int getRenamePrefixLengthLimit();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
   }
@@ -8721,11 +8727,13 @@
     ctor public BluetoothLEDeviceFilter.Builder();
     method public android.companion.BluetoothLEDeviceFilter build();
     method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
     method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
   }
 
   public final class CompanionDeviceManager {
-    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
     method public void disassociate(java.lang.String);
     method public java.util.List<java.lang.String> getAssociations();
     field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8740,6 +8748,18 @@
   public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
   }
 
+  public final class WifiDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
+  }
+
+  public static final class WifiDeviceFilter.Builder {
+    ctor public WifiDeviceFilter.Builder();
+    method public android.companion.WifiDeviceFilter build();
+    method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
 }
 
 package android.content {
@@ -13240,6 +13260,7 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
+    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -13641,6 +13662,8 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13716,6 +13739,8 @@
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -14234,6 +14259,8 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -14373,7 +14400,7 @@
   }
 
   public class Shader {
-    ctor public Shader();
+    ctor public deprecated Shader();
     method public boolean getLocalMatrix(android.graphics.Matrix);
     method public void setLocalMatrix(android.graphics.Matrix);
   }
@@ -14418,6 +14445,8 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
+    method public void set(float, float, int[], float[]);
+    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -14445,9 +14474,12 @@
   public static abstract interface Typeface.FontRequestCallback {
     method public abstract void onTypefaceRequestFailed(int);
     method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
   }
 
   public class Xfermode {
@@ -22750,7 +22782,7 @@
   }
 
   public class AudioManager {
-    method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
+    method public deprecated int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
     method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
@@ -22790,7 +22822,7 @@
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
-    method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public deprecated int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
@@ -26957,7 +26989,6 @@
     method public android.metrics.LogMaker clearPackageName();
     method public android.metrics.LogMaker clearSubtype();
     method public android.metrics.LogMaker clearTaggedData(int);
-    method public android.metrics.LogMaker clearTimestamp();
     method public android.metrics.LogMaker clearType();
     method public void deserialize(java.lang.Object[]);
     method public int getCategory();
@@ -26965,6 +26996,7 @@
     method public java.lang.String getCounterName();
     method public int getCounterValue();
     method public java.lang.String getPackageName();
+    method public int getProcessId();
     method public int getSubtype();
     method public java.lang.Object getTaggedData(int);
     method public long getTimestamp();
@@ -26974,13 +27006,8 @@
     method public boolean isValidValue(java.lang.Object);
     method public java.lang.Object[] serialize();
     method public android.metrics.LogMaker setCategory(int);
-    method public android.metrics.LogMaker setCounterBucket(int);
-    method public android.metrics.LogMaker setCounterBucket(long);
-    method public android.metrics.LogMaker setCounterName(java.lang.String);
-    method public android.metrics.LogMaker setCounterValue(int);
     method public android.metrics.LogMaker setPackageName(java.lang.String);
     method public android.metrics.LogMaker setSubtype(int);
-    method public android.metrics.LogMaker setTimestamp(long);
     method public android.metrics.LogMaker setType(int);
   }
 
@@ -29179,7 +29206,9 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifier(android.net.wifi.aware.PeerHandle, byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
+    method public java.lang.String createNetworkSpecifierPmk(android.net.wifi.aware.PeerHandle, byte[]);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -29267,7 +29296,9 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifier(int, byte[], byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
+    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
+    method public java.lang.String createNetworkSpecifierPmk(int, byte[], byte[]);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
@@ -36997,7 +37028,7 @@
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
-    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
+    method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -37113,6 +37144,11 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
     field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
@@ -39723,15 +39759,15 @@
 
 package android.service.autofill {
 
-  public abstract class AutoFillService extends android.app.Service {
-    ctor public AutoFillService();
+  public abstract class AutofillService extends android.app.Service {
+    ctor public AutofillService();
     method public final void disableSelf();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
@@ -39745,7 +39781,7 @@
     ctor public Dataset.Builder(android.widget.RemoteViews);
     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 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);
   }
 
   public final class FillCallback {
@@ -39785,7 +39821,7 @@
 
   public static final class SaveInfo.Builder {
     ctor public SaveInfo.Builder(int);
-    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
@@ -43193,7 +43229,7 @@
     method public int getSimState(int);
     method public java.lang.String getSubscriberId();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
-    method public java.lang.String getVisualVoicemailPackageName(android.telecom.PhoneAccountHandle);
+    method public java.lang.String getVisualVoicemailPackageName();
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public int getVoiceNetworkType();
@@ -43359,9 +43395,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
-    field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
-    field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
-    field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
     field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
     field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
     field public final java.lang.String clientPrefix;
@@ -48423,8 +48456,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public void autoFill(android.view.autofill.AutoFillValue);
-    method public void autoFillVirtual(int, android.view.autofill.AutoFillValue);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofillVirtual(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -48478,7 +48511,7 @@
     method public boolean dispatchNestedScroll(int, int, int, int, int[]);
     method public void dispatchPointerCaptureChanged(boolean);
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void dispatchProvideAutoFillStructure(android.view.ViewStructure, int);
+    method public void dispatchProvideAutofillStructure(android.view.ViewStructure, int);
     method public void dispatchProvideStructure(android.view.ViewStructure);
     method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
@@ -48514,11 +48547,10 @@
     method public float getAlpha();
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
-    method public int getAutoFillHint();
-    method public int getAutoFillMode();
-    method public final deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public int getAutofillHint();
+    method public int getAutofillMode();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
     method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -48604,7 +48636,7 @@
     method public float getPivotX();
     method public float getPivotY();
     method public android.view.PointerIcon getPointerIcon();
-    method public int getResolvedAutoFillMode();
+    method public int getResolvedAutofillMode();
     method public android.content.res.Resources getResources();
     method public final boolean getRevealOnFocusHint();
     method public final int getRight();
@@ -48763,8 +48795,8 @@
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void onProvideAutoFillStructure(android.view.ViewStructure, int);
-    method public void onProvideAutoFillVirtualStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int);
     method public void onProvideStructure(android.view.ViewStructure);
     method public void onProvideVirtualStructure(android.view.ViewStructure);
     method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int);
@@ -48836,8 +48868,8 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutoFillHint(int);
-    method public void setAutoFillMode(int);
+    method public void setAutofillHint(int);
+    method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -48979,28 +49011,28 @@
     field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
     field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
     field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
+    field public static final int AUTOFILL_HINT_EMAIL_ADDRESS = 1; // 0x1
+    field public static final int AUTOFILL_HINT_NAME = 2; // 0x2
+    field public static final int AUTOFILL_HINT_NONE = 0; // 0x0
+    field public static final int AUTOFILL_HINT_PASSWORD = 8; // 0x8
+    field public static final int AUTOFILL_HINT_PHONE = 16; // 0x10
+    field public static final int AUTOFILL_HINT_POSTAL_ADDRESS = 32; // 0x20
+    field public static final int AUTOFILL_HINT_POSTAL_CODE = 64; // 0x40
+    field public static final int AUTOFILL_HINT_USERNAME = 4; // 0x4
+    field public static final int AUTOFILL_MODE_AUTO = 1; // 0x1
+    field public static final int AUTOFILL_MODE_INHERIT = 0; // 0x0
+    field public static final int AUTOFILL_MODE_MANUAL = 2; // 0x2
     field public static final int AUTOFILL_TYPE_DATE = 4; // 0x4
     field public static final int AUTOFILL_TYPE_LIST = 3; // 0x3
     field public static final int AUTOFILL_TYPE_NONE = 0; // 0x0
     field public static final int AUTOFILL_TYPE_TEXT = 1; // 0x1
     field public static final int AUTOFILL_TYPE_TOGGLE = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
-    field public static final int AUTO_FILL_HINT_EMAIL_ADDRESS = 1; // 0x1
-    field public static final int AUTO_FILL_HINT_NAME = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_NONE = 0; // 0x0
-    field public static final int AUTO_FILL_HINT_PASSWORD = 8; // 0x8
-    field public static final int AUTO_FILL_HINT_PHONE = 16; // 0x10
-    field public static final int AUTO_FILL_HINT_POSTAL_ADDRESS = 32; // 0x20
-    field public static final int AUTO_FILL_HINT_POSTAL_CODE = 64; // 0x40
-    field public static final int AUTO_FILL_HINT_USERNAME = 4; // 0x4
-    field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
-    field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
-    field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
     field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
     field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
     field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -49562,7 +49594,7 @@
     method public abstract int getLayoutDirection();
     method public abstract android.view.ViewParent getParent();
     method public abstract android.view.ViewParent getParentForAccessibility();
-    method public default int getResolvedAutoFillMode();
+    method public default int getResolvedAutofillMode();
     method public abstract int getTextAlignment();
     method public abstract int getTextDirection();
     method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -49641,7 +49673,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure asyncNewChildForAutofill(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -49650,15 +49682,14 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure newChildForAutofill(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
-    method public abstract void setAutoFillHint(int);
-    method public abstract void setAutoFillOptions(java.lang.String[]);
-    method public abstract deprecated void setAutoFillType(android.view.autofill.AutoFillType);
-    method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
+    method public abstract void setAutofillHint(int);
+    method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
+    method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
     method public abstract void setCheckable(boolean);
     method public abstract void setChecked(boolean);
     method public abstract void setChildCount(int);
@@ -49675,6 +49706,7 @@
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
     method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setOpaque(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
@@ -50395,6 +50427,8 @@
     field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_X = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_X";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_Y = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_Y";
     field public static final java.lang.String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
     field public static final java.lang.String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
@@ -50451,6 +50485,7 @@
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_EXPAND;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_FOCUS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_LONG_CLICK;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_MOVE_WINDOW;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_HTML_ELEMENT;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PASTE;
@@ -50575,6 +50610,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo getRoot();
     method public java.lang.CharSequence getTitle();
     method public int getType();
+    method public boolean inPictureInPicture();
     method public boolean isAccessibilityFocused();
     method public boolean isActive();
     method public boolean isFocused();
@@ -50910,60 +50946,46 @@
 
 package android.view.autofill {
 
-  public final class AutoFillId implements android.os.Parcelable {
+  public final class AutofillId implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillId> CREATOR;
   }
 
-  public final class AutoFillManager {
-    method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+  public final class AutofillManager {
+    method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void reset();
-    method public void startAutoFillRequest(android.view.View);
-    method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutoFillRequest(android.view.View);
-    method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
-    method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+    method public void startAutofillRequest(android.view.View);
+    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
+    method public void stopAutofillRequest(android.view.View);
+    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
+    method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
-  public static abstract class AutoFillManager.AutofillCallback {
-    ctor public AutoFillManager.AutofillCallback();
+  public static abstract class AutofillManager.AutofillCallback {
+    ctor public AutofillManager.AutofillCallback();
     method public void onAutofillEvent(android.view.View, int);
     method public void onAutofillEventVirtual(android.view.View, int, int);
     field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
     field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
   }
 
-  public final class AutoFillType implements android.os.Parcelable {
+  public final class AutofillValue implements android.os.Parcelable {
     method public int describeContents();
-    method public static android.view.autofill.AutoFillType forDate();
-    method public static android.view.autofill.AutoFillType forList();
-    method public static android.view.autofill.AutoFillType forText();
-    method public static android.view.autofill.AutoFillType forToggle();
-    method public boolean isDate();
-    method public boolean isList();
-    method public boolean isText();
-    method public boolean isToggle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillType> CREATOR;
-  }
-
-  public final class AutoFillValue implements android.os.Parcelable {
-    method public int describeContents();
-    method public static android.view.autofill.AutoFillValue forDate(long);
-    method public static android.view.autofill.AutoFillValue forList(int);
-    method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
-    method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public static android.view.autofill.AutofillValue forDate(long);
+    method public static android.view.autofill.AutofillValue forList(int);
+    method public static android.view.autofill.AutofillValue forText(java.lang.CharSequence);
+    method public static android.view.autofill.AutofillValue forToggle(boolean);
     method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillValue> CREATOR;
   }
 
 }
@@ -52573,7 +52595,7 @@
     method public abstract boolean onKeyUp(int, android.view.KeyEvent);
     method public abstract void onMeasure(int, int);
     method public abstract void onOverScrolled(int, int, boolean, boolean);
-    method public default void onProvideAutoFillVirtualStructure(android.view.ViewStructure, int);
+    method public default void onProvideAutofillVirtualStructure(android.view.ViewStructure, int);
     method public abstract void onProvideVirtualStructure(android.view.ViewStructure);
     method public abstract void onScrollChanged(int, int, int, int);
     method public abstract void onSizeChanged(int, int, int, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 51ff912..80b6379 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -20,6 +20,7 @@
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+    field public static final java.lang.String BIND_AUTOFILL = "android.permission.BIND_AUTOFILL";
     field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL";
     field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
@@ -298,8 +299,6 @@
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
-    field public static final int autoFillHint = 16844121; // 0x1010559
-    field public static final int autoFillMode = 16844116; // 0x1010554
     field public static final int autoLink = 16842928; // 0x10100b0
     field public static final int autoMirrored = 16843754; // 0x10103ea
     field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -312,6 +311,8 @@
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
     field public static final int autoVerify = 16844014; // 0x10104ee
+    field public static final int autofillHint = 16844121; // 0x1010559
+    field public static final int autofillMode = 16844116; // 0x1010554
     field public static final int background = 16842964; // 0x10100d4
     field public static final int backgroundDimAmount = 16842802; // 0x1010032
     field public static final int backgroundDimEnabled = 16843295; // 0x101021f
@@ -1778,6 +1779,7 @@
   public static final class R.id {
     ctor public R.id();
     field public static final int accessibilityActionContextClick = 16908348; // 0x102003c
+    field public static final int accessibilityActionMoveWindow = 16908354; // 0x1020042
     field public static final int accessibilityActionScrollDown = 16908346; // 0x102003a
     field public static final int accessibilityActionScrollLeft = 16908345; // 0x1020039
     field public static final int accessibilityActionScrollRight = 16908347; // 0x102003b
@@ -6578,9 +6580,12 @@
   public class AssistStructure implements android.os.Parcelable {
     ctor public AssistStructure();
     method public int describeContents();
+    method public long getAcquisitionEndTime();
+    method public long getAcquisitionStartTime();
     method public android.content.ComponentName getActivityComponent();
     method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int);
     method public int getWindowNodeCount();
+    method public boolean isHomeActivity();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR;
   }
@@ -6588,11 +6593,10 @@
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
     method public int getAutoFillHint();
-    method public android.view.autofill.AutoFillId getAutoFillId();
-    method public java.lang.String[] getAutoFillOptions();
-    method public deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public android.view.autofill.AutofillId getAutofillId();
+    method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.app.assist.AssistStructure.ViewNode getChildAt(int);
     method public int getChildCount();
     method public java.lang.String getClassName();
@@ -6634,6 +6638,7 @@
     method public boolean isFocusable();
     method public boolean isFocused();
     method public boolean isLongClickable();
+    method public boolean isOpaque();
     method public boolean isSelected();
     field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1
     field public static final int TEXT_STYLE_BOLD = 1; // 0x1
@@ -8013,7 +8018,7 @@
   public static final class AdvertisingSetParameters.Builder {
     ctor public AdvertisingSetParameters.Builder();
     method public android.bluetooth.le.AdvertisingSetParameters build();
-    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+    method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
     method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
@@ -8210,18 +8215,17 @@
 
 package android.companion {
 
-  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+  public final class AssociationRequest implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
   }
 
-  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
-    method public android.companion.AssociationRequest<F> build();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
-    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
-    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
-    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  public static final class AssociationRequest.Builder {
+    ctor public AssociationRequest.Builder();
+    method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
+    method public android.companion.AssociationRequest build();
+    method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
   }
 
   public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8240,6 +8244,7 @@
 
   public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
     method public int describeContents();
+    method public static int getRenamePrefixLengthLimit();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
   }
@@ -8248,11 +8253,13 @@
     ctor public BluetoothLEDeviceFilter.Builder();
     method public android.companion.BluetoothLEDeviceFilter build();
     method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
     method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
   }
 
   public final class CompanionDeviceManager {
-    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
     method public void disassociate(java.lang.String);
     method public java.util.List<java.lang.String> getAssociations();
     field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8267,6 +8274,18 @@
   public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
   }
 
+  public final class WifiDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
+  }
+
+  public static final class WifiDeviceFilter.Builder {
+    ctor public WifiDeviceFilter.Builder();
+    method public android.companion.WifiDeviceFilter build();
+    method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
 }
 
 package android.content {
@@ -12542,6 +12561,7 @@
 
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
+    method public void set(android.graphics.Bitmap, android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
   }
 
   public class BlurMaskFilter extends android.graphics.MaskFilter {
@@ -12943,6 +12963,8 @@
   public class ComposeShader extends android.graphics.Shader {
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
     ctor public ComposeShader(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.Xfermode);
+    method public void set(android.graphics.Shader, android.graphics.Shader, android.graphics.PorterDuff.Mode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -13018,6 +13040,8 @@
   public class LinearGradient extends android.graphics.Shader {
     ctor public LinearGradient(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public LinearGradient(float, float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public class MaskFilter {
@@ -13536,6 +13560,8 @@
   public class RadialGradient extends android.graphics.Shader {
     ctor public RadialGradient(float, float, float, int[], float[], android.graphics.Shader.TileMode);
     ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int[], float[], android.graphics.Shader.TileMode);
+    method public void set(float, float, float, int, int, android.graphics.Shader.TileMode);
   }
 
   public final class Rect implements android.os.Parcelable {
@@ -13675,7 +13701,7 @@
   }
 
   public class Shader {
-    ctor public Shader();
+    ctor public deprecated Shader();
     method public boolean getLocalMatrix(android.graphics.Matrix);
     method public void setLocalMatrix(android.graphics.Matrix);
   }
@@ -13720,6 +13746,8 @@
   public class SweepGradient extends android.graphics.Shader {
     ctor public SweepGradient(float, float, int[], float[]);
     ctor public SweepGradient(float, float, int, int);
+    method public void set(float, float, int[], float[]);
+    method public void set(float, float, int, int);
   }
 
   public class Typeface {
@@ -13747,9 +13775,12 @@
   public static abstract interface Typeface.FontRequestCallback {
     method public abstract void onTypefaceRequestFailed(int);
     method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
   }
 
   public class Xfermode {
@@ -21087,7 +21118,7 @@
   }
 
   public class AudioManager {
-    method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
+    method public deprecated int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
     method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
@@ -21124,7 +21155,7 @@
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
-    method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public deprecated int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public deprecated void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
@@ -26580,7 +26611,8 @@
   }
 
   public class DiscoverySession {
-    method public java.lang.String createNetworkSpecifier(android.net.wifi.aware.PeerHandle, byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
+    method public java.lang.String createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
     method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
@@ -26668,7 +26700,8 @@
   }
 
   public class WifiAwareSession {
-    method public java.lang.String createNetworkSpecifier(int, byte[], byte[]);
+    method public java.lang.String createNetworkSpecifierOpen(int, byte[]);
+    method public java.lang.String createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
     method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
@@ -34217,7 +34250,7 @@
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static android.content.IntentSender createWebLinkIntent(android.content.ContentResolver, android.net.Uri, android.os.Bundle);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
-    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
+    method public static android.provider.DocumentsContract.Path findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -34333,6 +34366,11 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
     field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
@@ -34860,7 +34898,7 @@
     field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
     field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
     field public static final java.lang.String ANDROID_ID = "android_id";
-    field public static final java.lang.String AUTO_FILL_SERVICE = "auto_fill_service";
+    field public static final java.lang.String AUTOFILL_SERVICE = "autofill_service";
     field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
     field public static final deprecated java.lang.String BLUETOOTH_ON = "bluetooth_on";
     field public static final android.net.Uri CONTENT_URI;
@@ -36832,15 +36870,15 @@
 
 package android.service.autofill {
 
-  public abstract class AutoFillService extends android.app.Service {
-    ctor public AutoFillService();
+  public abstract class AutofillService extends android.app.Service {
+    ctor public AutofillService();
     method public final void disableSelf();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
 
@@ -36854,7 +36892,7 @@
     ctor public Dataset.Builder(android.widget.RemoteViews);
     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 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);
   }
 
   public final class FillCallback {
@@ -36894,7 +36932,7 @@
 
   public static final class SaveInfo.Builder {
     ctor public SaveInfo.Builder(int);
-    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutoFillId...);
+    method public android.service.autofill.SaveInfo.Builder addSavableIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
@@ -39977,7 +40015,7 @@
     method public int getSimState();
     method public int getSimState(int);
     method public java.lang.String getSubscriberId();
-    method public java.lang.String getVisualVoicemailPackageName(android.telecom.PhoneAccountHandle);
+    method public java.lang.String getVisualVoicemailPackageName();
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public int getVoiceNetworkType();
@@ -40117,9 +40155,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
-    field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
-    field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
-    field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
     field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
     field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
     field public final java.lang.String clientPrefix;
@@ -45321,8 +45356,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public void autoFill(android.view.autofill.AutoFillValue);
-    method public void autoFillVirtual(int, android.view.autofill.AutoFillValue);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofillVirtual(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -45376,7 +45411,7 @@
     method public boolean dispatchNestedScroll(int, int, int, int, int[]);
     method public void dispatchPointerCaptureChanged(boolean);
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void dispatchProvideAutoFillStructure(android.view.ViewStructure, int);
+    method public void dispatchProvideAutofillStructure(android.view.ViewStructure, int);
     method public void dispatchProvideStructure(android.view.ViewStructure);
     method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
     method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
@@ -45412,11 +45447,10 @@
     method public float getAlpha();
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
-    method public int getAutoFillHint();
-    method public int getAutoFillMode();
-    method public final deprecated android.view.autofill.AutoFillType getAutoFillType();
-    method public android.view.autofill.AutoFillValue getAutoFillValue();
+    method public int getAutofillHint();
+    method public int getAutofillMode();
     method public int getAutofillType();
+    method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
     method public android.content.res.ColorStateList getBackgroundTintList();
     method public android.graphics.PorterDuff.Mode getBackgroundTintMode();
@@ -45502,7 +45536,7 @@
     method public float getPivotX();
     method public float getPivotY();
     method public android.view.PointerIcon getPointerIcon();
-    method public int getResolvedAutoFillMode();
+    method public int getResolvedAutofillMode();
     method public android.content.res.Resources getResources();
     method public final boolean getRevealOnFocusHint();
     method public final int getRight();
@@ -45662,8 +45696,8 @@
     method protected void onOverScrolled(int, int, boolean, boolean);
     method public void onPointerCaptureChange(boolean);
     method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
-    method public void onProvideAutoFillStructure(android.view.ViewStructure, int);
-    method public void onProvideAutoFillVirtualStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillStructure(android.view.ViewStructure, int);
+    method public void onProvideAutofillVirtualStructure(android.view.ViewStructure, int);
     method public void onProvideStructure(android.view.ViewStructure);
     method public void onProvideVirtualStructure(android.view.ViewStructure);
     method public android.view.PointerIcon onResolvePointerIcon(android.view.MotionEvent, int);
@@ -45737,8 +45771,8 @@
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
-    method public void setAutoFillHint(int);
-    method public void setAutoFillMode(int);
+    method public void setAutofillHint(int);
+    method public void setAutofillMode(int);
     method public void setBackground(android.graphics.drawable.Drawable);
     method public void setBackgroundColor(int);
     method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -45880,28 +45914,28 @@
     field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
     field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
     field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
+    field public static final int AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
+    field public static final int AUTOFILL_HINT_EMAIL_ADDRESS = 1; // 0x1
+    field public static final int AUTOFILL_HINT_NAME = 2; // 0x2
+    field public static final int AUTOFILL_HINT_NONE = 0; // 0x0
+    field public static final int AUTOFILL_HINT_PASSWORD = 8; // 0x8
+    field public static final int AUTOFILL_HINT_PHONE = 16; // 0x10
+    field public static final int AUTOFILL_HINT_POSTAL_ADDRESS = 32; // 0x20
+    field public static final int AUTOFILL_HINT_POSTAL_CODE = 64; // 0x40
+    field public static final int AUTOFILL_HINT_USERNAME = 4; // 0x4
+    field public static final int AUTOFILL_MODE_AUTO = 1; // 0x1
+    field public static final int AUTOFILL_MODE_INHERIT = 0; // 0x0
+    field public static final int AUTOFILL_MODE_MANUAL = 2; // 0x2
     field public static final int AUTOFILL_TYPE_DATE = 4; // 0x4
     field public static final int AUTOFILL_TYPE_LIST = 3; // 0x3
     field public static final int AUTOFILL_TYPE_NONE = 0; // 0x0
     field public static final int AUTOFILL_TYPE_TEXT = 1; // 0x1
     field public static final int AUTOFILL_TYPE_TOGGLE = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 512; // 0x200
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 4096; // 0x1000
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 1024; // 0x400
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 2048; // 0x800
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_NUMBER = 128; // 0x80
-    field public static final int AUTO_FILL_HINT_CREDIT_CARD_SECURITY_CODE = 256; // 0x100
-    field public static final int AUTO_FILL_HINT_EMAIL_ADDRESS = 1; // 0x1
-    field public static final int AUTO_FILL_HINT_NAME = 2; // 0x2
-    field public static final int AUTO_FILL_HINT_NONE = 0; // 0x0
-    field public static final int AUTO_FILL_HINT_PASSWORD = 8; // 0x8
-    field public static final int AUTO_FILL_HINT_PHONE = 16; // 0x10
-    field public static final int AUTO_FILL_HINT_POSTAL_ADDRESS = 32; // 0x20
-    field public static final int AUTO_FILL_HINT_POSTAL_CODE = 64; // 0x40
-    field public static final int AUTO_FILL_HINT_USERNAME = 4; // 0x4
-    field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
-    field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
-    field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
     field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
     field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
     field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
@@ -46467,7 +46501,7 @@
     method public abstract int getLayoutDirection();
     method public abstract android.view.ViewParent getParent();
     method public abstract android.view.ViewParent getParentForAccessibility();
-    method public default int getResolvedAutoFillMode();
+    method public default int getResolvedAutofillMode();
     method public abstract int getTextAlignment();
     method public abstract int getTextDirection();
     method public abstract deprecated void invalidateChild(android.view.View, android.graphics.Rect);
@@ -46546,7 +46580,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
-    method public abstract android.view.ViewStructure asyncNewChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure asyncNewChildForAutofill(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46555,15 +46589,14 @@
     method public abstract int getTextSelectionStart();
     method public abstract boolean hasExtras();
     method public abstract android.view.ViewStructure newChild(int);
-    method public abstract android.view.ViewStructure newChildForAutoFill(int, int, int);
+    method public abstract android.view.ViewStructure newChildForAutofill(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
-    method public abstract void setAutoFillHint(int);
-    method public abstract void setAutoFillOptions(java.lang.String[]);
-    method public abstract deprecated void setAutoFillType(android.view.autofill.AutoFillType);
-    method public abstract void setAutoFillValue(android.view.autofill.AutoFillValue);
+    method public abstract void setAutofillHint(int);
+    method public abstract void setAutofillOptions(java.lang.String[]);
     method public abstract void setAutofillType(int);
+    method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
     method public abstract void setCheckable(boolean);
     method public abstract void setChecked(boolean);
     method public abstract void setChildCount(int);
@@ -46580,6 +46613,7 @@
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
     method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
+    method public abstract void setOpaque(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
     method public abstract void setText(java.lang.CharSequence);
@@ -47298,6 +47332,8 @@
     field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_X = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_X";
+    field public static final java.lang.String ACTION_ARGUMENT_MOVE_WINDOW_Y = "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_Y";
     field public static final java.lang.String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
     field public static final java.lang.String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
@@ -47354,6 +47390,7 @@
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_EXPAND;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_FOCUS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_LONG_CLICK;
+    field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_MOVE_WINDOW;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_HTML_ELEMENT;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PASTE;
@@ -47478,6 +47515,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo getRoot();
     method public java.lang.CharSequence getTitle();
     method public int getType();
+    method public boolean inPictureInPicture();
     method public boolean isAccessibilityFocused();
     method public boolean isActive();
     method public boolean isFocused();
@@ -47814,60 +47852,46 @@
 
 package android.view.autofill {
 
-  public final class AutoFillId implements android.os.Parcelable {
+  public final class AutofillId implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillId> CREATOR;
   }
 
-  public final class AutoFillManager {
-    method public void registerCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+  public final class AutofillManager {
+    method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void reset();
-    method public void startAutoFillRequest(android.view.View);
-    method public void startAutoFillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
-    method public void stopAutoFillRequest(android.view.View);
-    method public void stopAutoFillRequestOnVirtualView(android.view.View, int);
-    method public void unregisterCallback(android.view.autofill.AutoFillManager.AutofillCallback);
+    method public void startAutofillRequest(android.view.View);
+    method public void startAutofillRequestOnVirtualView(android.view.View, int, android.graphics.Rect);
+    method public void stopAutofillRequest(android.view.View);
+    method public void stopAutofillRequestOnVirtualView(android.view.View, int);
+    method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void valueChanged(android.view.View);
-    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutoFillValue);
+    method public void virtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
   }
 
-  public static abstract class AutoFillManager.AutofillCallback {
-    ctor public AutoFillManager.AutofillCallback();
+  public static abstract class AutofillManager.AutofillCallback {
+    ctor public AutofillManager.AutofillCallback();
     method public void onAutofillEvent(android.view.View, int);
     method public void onAutofillEventVirtual(android.view.View, int, int);
     field public static final int EVENT_INPUT_HIDDEN = 2; // 0x2
     field public static final int EVENT_INPUT_SHOWN = 1; // 0x1
   }
 
-  public final class AutoFillType implements android.os.Parcelable {
+  public final class AutofillValue implements android.os.Parcelable {
     method public int describeContents();
-    method public static android.view.autofill.AutoFillType forDate();
-    method public static android.view.autofill.AutoFillType forList();
-    method public static android.view.autofill.AutoFillType forText();
-    method public static android.view.autofill.AutoFillType forToggle();
-    method public boolean isDate();
-    method public boolean isList();
-    method public boolean isText();
-    method public boolean isToggle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillType> CREATOR;
-  }
-
-  public final class AutoFillValue implements android.os.Parcelable {
-    method public int describeContents();
-    method public static android.view.autofill.AutoFillValue forDate(long);
-    method public static android.view.autofill.AutoFillValue forList(int);
-    method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
-    method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public static android.view.autofill.AutofillValue forDate(long);
+    method public static android.view.autofill.AutofillValue forList(int);
+    method public static android.view.autofill.AutofillValue forText(java.lang.CharSequence);
+    method public static android.view.autofill.AutofillValue forToggle(boolean);
     method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillValue> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.view.autofill.AutofillValue> CREATOR;
   }
 
 }
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index b4e119e..64d7d4c 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -1438,7 +1438,7 @@
      */
     public AccessibilityNodeInfo findFocus(int focus) {
         return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
-                AccessibilityNodeInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
+                AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
     }
 
     /**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0193c5f..1969f8b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,9 +16,9 @@
 
 package android.app;
 
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
@@ -690,7 +690,7 @@
         Window.Callback, KeyEvent.Callback,
         OnCreateContextMenuListener, ComponentCallbacks2,
         Window.OnWindowDismissedCallback, WindowControllerCallback,
-        AutoFillManager.AutoFillClient {
+        AutofillManager.AutofillClient {
     private static final String TAG = "Activity";
     private static final boolean DEBUG_LIFECYCLE = false;
 
@@ -1783,7 +1783,7 @@
         mTranslucentCallback = null;
         mCalled = true;
         if (isFinishing() && mAutoFillResetNeeded) {
-            getSystemService(AutoFillManager.class).reset();
+            getSystemService(AutofillManager.class).reset();
         }
     }
 
@@ -7042,7 +7042,7 @@
             }
         } else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
             Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
-            getSystemService(AutoFillManager.class).onAuthenticationResult(resultData);
+            getSystemService(AutofillManager.class).onAuthenticationResult(resultData);
         } else {
             Fragment frag = mFragments.findFragmentByWho(who);
             if (frag != null) {
@@ -7185,22 +7185,22 @@
 
     /** @hide */
     @Override
-    public void autoFill(List<AutoFillId> ids, List<AutoFillValue> values) {
+    public void autofill(List<AutofillId> ids, List<AutofillValue> values) {
         final View root = getWindow().getDecorView();
         final int itemCount = ids.size();
         for (int i = 0; i < itemCount; i++) {
-            final AutoFillId id = ids.get(i);
-            final AutoFillValue value = values.get(i);
+            final AutofillId id = ids.get(i);
+            final AutofillValue value = values.get(i);
             final int viewId = id.getViewId();
             final View view = root.findViewByAccessibilityIdTraversal(viewId);
             if (view == null) {
-                Log.w(TAG, "autoFill(): no View with id " + viewId);
+                Log.w(TAG, "autofill(): no View with id " + viewId);
                 continue;
             }
             if (id.isVirtual()) {
-                view.autoFillVirtual(id.getVirtualChildId(), value);
+                view.autofillVirtual(id.getVirtualChildId(), value);
             } else {
-                view.autoFill(value);
+                view.autofill(value);
             }
         }
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index cae37c6..043e0ab 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -133,7 +133,7 @@
     public final static boolean ENABLE_TASK_SNAPSHOTS;
 
     static {
-        ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", false);
+        ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", true);
     }
 
     static final class UidObserver extends IUidObserver.Stub {
@@ -144,7 +144,7 @@
         }
 
         @Override
-        public void onUidStateChanged(int uid, int procState) {
+        public void onUidStateChanged(int uid, int procState, long procStateSeq) {
             mListener.onUidImportance(uid, RunningAppProcessInfo.procStateToImportance(procState));
         }
 
@@ -502,8 +502,8 @@
     /** @hide requestType for assist context: generate full AssistStructure. */
     public static final int ASSIST_CONTEXT_FULL = 1;
 
-    /** @hide requestType for assist context: generate full AssistStructure for auto-fill. */
-    public static final int ASSIST_CONTEXT_AUTO_FILL = 2;
+    /** @hide requestType for assist context: generate full AssistStructure for autofill. */
+    public static final int ASSIST_CONTEXT_AUTOFILL = 2;
 
     /** @hide Flag for registerUidObserver: report changes in process state. */
     public static final int UID_OBSERVER_PROCSTATE = 1<<0;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ce9d91f..44cc5b4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2913,13 +2913,13 @@
     }
 
     public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
-        // Filling for auto-fill has a few differences:
+        // Filling for autofill has a few differences:
         // - it does not need an AssistContent
         // - it does not call onProvideAssistData()
         // - it needs an IAutoFillCallback
-        boolean forAutoFill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL;
+        boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL;
 
-        // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
+        // TODO(b/33197203): decide if lastSessionId logic applies to autofill sessions
         if (mLastSessionId != cmd.sessionId) {
             // Clear the existing structures
             mLastSessionId = cmd.sessionId;
@@ -2934,25 +2934,26 @@
 
         Bundle data = new Bundle();
         AssistStructure structure = null;
-        AssistContent content = forAutoFill ? null : new AssistContent();
+        AssistContent content = forAutofill ? null : new AssistContent();
+        final long startTime = SystemClock.uptimeMillis();
         ActivityClientRecord r = mActivities.get(cmd.activityToken);
         Uri referrer = null;
         if (r != null) {
-            if (!forAutoFill) {
+            if (!forAutofill) {
                 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
                 r.activity.onProvideAssistData(data);
                 referrer = r.activity.onProvideReferrer();
             }
-            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutoFill) {
-                structure = new AssistStructure(r.activity, forAutoFill);
+            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) {
+                structure = new AssistStructure(r.activity, forAutofill);
                 Intent activityIntent = r.activity.getIntent();
-                // TODO(b/33197203): re-evaluate conditions below for auto-fill. In particular,
+                // TODO(b/33197203): re-evaluate conditions below for autofill. In particular,
                 // FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE)
                 boolean notSecure = r.window == null ||
                         (r.window.getAttributes().flags
                                 & WindowManager.LayoutParams.FLAG_SECURE) == 0;
                 if (activityIntent != null && notSecure) {
-                    if (!forAutoFill) {
+                    if (!forAutofill) {
                         Intent intent = new Intent(activityIntent);
                         intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
@@ -2960,11 +2961,11 @@
                         content.setDefaultIntent(intent);
                     }
                 } else {
-                    if (!forAutoFill) {
+                    if (!forAutofill) {
                         content.setDefaultIntent(new Intent());
                     }
                 }
-                if (!forAutoFill) {
+                if (!forAutofill) {
                     r.activity.onProvideAssistContent(content);
                 }
             }
@@ -2973,7 +2974,11 @@
             structure = new AssistStructure();
         }
 
-        // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
+        // TODO(b/33197203): decide if lastSessionId logic applies to autofill sessions
+
+        structure.setAcquisitionStartTime(startTime);
+        structure.setAcquisitionEndTime(SystemClock.uptimeMillis());
+
         mLastAssistStructures.add(new WeakReference<>(structure));
         IActivityManager mgr = ActivityManager.getService();
         try {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 152d514..081dae2 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -588,7 +588,7 @@
     boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId);
     void unregisterTaskStackListener(ITaskStackListener listener);
     void moveStackToDisplay(int stackId, int displayId);
-    boolean requestAutoFillData(in IResultReceiver receiver, in Bundle receiverExtras,
+    boolean requestAutofillData(in IResultReceiver receiver, in Bundle receiverExtras,
                                 in IBinder activityToken);
     void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback);
     int restartUserInBackground(int userId);
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index 64cb9b1..ae64875 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -20,8 +20,13 @@
 oneway interface IUidObserver {
     /**
      * General report of a state change of an uid.
+     *
+     * @param uid The uid for which the state change is being reported.
+     * @param procState The updated process state for the uid.
+     * @param procStateSeq The sequence no. associated with process state change of the uid,
+     *                     see UidRecord.procStateSeq for details.
      */
-    void onUidStateChanged(int uid, int procState);
+    void onUidStateChanged(int uid, int procState, long procStateSeq);
 
     /**
      * Report that there are no longer any processes running for a uid.
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index f330a4b..4ae0617 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -114,7 +114,7 @@
 import android.os.storage.StorageManager;
 import android.print.IPrintManager;
 import android.print.PrintManager;
-import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutoFillManager;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
@@ -821,13 +821,13 @@
                         IBinder b = ServiceManager.getServiceOrThrow(Context.FONT_SERVICE);
                         return new FontManager(IFontManager.Stub.asInterface(b));
                     }});
-        registerService(Context.AUTO_FILL_MANAGER_SERVICE, AutoFillManager.class,
-                new CachedServiceFetcher<AutoFillManager>() {
+        registerService(Context.AUTOFILL_MANAGER_SERVICE, AutofillManager.class,
+                new CachedServiceFetcher<AutofillManager>() {
             @Override
-            public AutoFillManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                IBinder b = ServiceManager.getServiceOrThrow(Context.AUTO_FILL_MANAGER_SERVICE);
+            public AutofillManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+                IBinder b = ServiceManager.getServiceOrThrow(Context.AUTOFILL_MANAGER_SERVICE);
                 IAutoFillManager service = IAutoFillManager.Stub.asInterface(b);
-                return new AutoFillManager(ctx.getOuterContext(), service);
+                return new AutofillManager(ctx.getOuterContext(), service);
             }});
 
         registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 1d6f42e..18e7599 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -381,7 +381,7 @@
      */
     public AccessibilityNodeInfo findFocus(int focus) {
         return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId,
-                AccessibilityNodeInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
+                AccessibilityWindowInfo.ANY_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID, focus);
     }
 
     /**
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 2e0ca02..1f2ed00 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -24,6 +24,8 @@
 import android.view.autofill.AutoFillId;
 import android.view.autofill.AutoFillType;
 import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -45,6 +47,7 @@
     boolean mHaveData;
 
     ComponentName mActivityComponent;
+    private boolean mIsHomeActivity;
 
     final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
 
@@ -56,10 +59,54 @@
     Rect mTmpRect = new Rect();
 
     boolean mSanitizeOnWrite = false;
+    private long mAcquisitionStartTime;
+    private long mAcquisitionEndTime;
 
     static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
     static final String DESCRIPTOR = "android.app.AssistStructure";
 
+    /** @hide */
+    public void setAcquisitionStartTime(long acquisitionStartTime) {
+        mAcquisitionStartTime = acquisitionStartTime;
+    }
+
+    /** @hide */
+    public void setAcquisitionEndTime(long acquisitionEndTime) {
+        mAcquisitionEndTime = acquisitionEndTime;
+    }
+
+    /**
+     * @hide
+     * Set the home activity flag.
+     */
+    public void setHomeActivity(boolean isHomeActivity) {
+        mIsHomeActivity = isHomeActivity;
+    }
+
+    /**
+     * Returns the time when the activity started generating assist data to build the
+     * AssistStructure. The time is as specified by {@link SystemClock#uptimeMillis()}.
+     *
+     * @see #getAcquisitionEndTime()
+     * @return Returns the acquisition start time of the assist data, in milliseconds.
+     */
+    public long getAcquisitionStartTime() {
+        ensureData();
+        return mAcquisitionStartTime;
+    }
+
+    /**
+     * Returns the time when the activity finished generating assist data to build the
+     * AssistStructure. The time is as specified by {@link SystemClock#uptimeMillis()}.
+     *
+     * @see #getAcquisitionStartTime()
+     * @return Returns the acquisition end time of the assist data, in milliseconds.
+     */
+    public long getAcquisitionEndTime() {
+        ensureData();
+        return mAcquisitionEndTime;
+    }
+
     final static class SendChannel extends Binder {
         volatile AssistStructure mAssistStructure;
 
@@ -123,6 +170,8 @@
             mSanitizeOnWrite = as.mSanitizeOnWrite;
             mWriteStructure = as.waitForReady();
             ComponentName.writeToParcel(as.mActivityComponent, out);
+            out.writeLong(as.mAcquisitionStartTime);
+            out.writeLong(as.mAcquisitionEndTime);
             mNumWindows = as.mWindowNodes.size();
             if (mWriteStructure && mNumWindows > 0) {
                 out.writeInt(mNumWindows);
@@ -275,6 +324,8 @@
         void go() {
             fetchData();
             mActivityComponent = ComponentName.readFromParcel(mCurParcel);
+            mAcquisitionStartTime = mCurParcel.readLong();
+            mAcquisitionEndTime = mCurParcel.readLong();
             final int N = mCurParcel.readInt();
             if (N > 0) {
                 if (DEBUG_PARCEL) Log.d(TAG, "Creating PooledStringReader @ "
@@ -424,7 +475,7 @@
             if ((root.getWindowFlags() & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
                 if (forAutoFill) {
                     // NOTE: flags are currently not supported, hence 0
-                    view.onProvideAutoFillStructure(builder, 0);
+                    view.onProvideAutofillStructure(builder, 0);
                 } else {
                     // This is a secure window, so it doesn't want a screenshot, and that
                     // means we should also not copy out its view hierarchy for Assist
@@ -435,7 +486,7 @@
             }
             if (forAutoFill) {
                 // NOTE: flags are currently not supported, hence 0
-                view.dispatchProvideAutoFillStructure(builder, 0);
+                view.dispatchProvideAutofillStructure(builder, 0);
             } else {
                 view.dispatchProvideStructure(builder);
             }
@@ -537,11 +588,11 @@
 
         // TODO(b/33197203): once we have more flags, it might be better to store the individual
         // fields (viewId and childId) of the field.
-        AutoFillId mAutoFillId;
+        AutofillId mAutofillId;
         @View.AutofillType int mAutofillType;
-        @View.AutoFillHint int mAutoFillHint;
-        AutoFillValue mAutoFillValue;
-        String[] mAutoFillOptions;
+        @View.AutofillHint int mAutofillHint;
+        AutofillValue mAutofillValue;
+        String[] mAutofillOptions;
         boolean mSanitized;
 
         int mX;
@@ -567,12 +618,13 @@
         static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x00001000;
         static final int FLAGS_ACTIVATED = 0x00002000;
         static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
+        static final int FLAGS_OPAQUE = 0x00008000;
 
-        // TODO(b/33197203): auto-fill data is made of many fields and ideally we should verify
+        // TODO(b/33197203): autofill data is made of many fields and ideally we should verify
         // one-by-one to optimize what's sent over, but there isn't enough flag bits for that, we'd
         // need to create a 'flags2' or 'autoFillFlags' field and add these flags there.
         // So, to keep thinkg simpler for now, let's just use on flag for all of them...
-        static final int FLAGS_HAS_AUTO_FILL_DATA = 0x80000000;
+        static final int FLAGS_HAS_AUTOFILL_DATA = 0x80000000;
         static final int FLAGS_HAS_MATRIX = 0x40000000;
         static final int FLAGS_HAS_ALPHA = 0x20000000;
         static final int FLAGS_HAS_ELEVATION = 0x10000000;
@@ -620,13 +672,13 @@
                     }
                 }
             }
-            if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0) {
+            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
                 mSanitized = in.readInt() == 1;
-                mAutoFillId = in.readParcelable(null);
+                mAutofillId = in.readParcelable(null);
                 mAutofillType = in.readInt();
-                mAutoFillHint = in.readInt();
-                mAutoFillValue = in.readParcelable(null);
-                mAutoFillOptions = in.readStringArray();
+                mAutofillHint = in.readInt();
+                mAutofillValue = in.readParcelable(null);
+                mAutofillOptions = in.readStringArray();
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 mX = in.readInt();
@@ -686,15 +738,15 @@
 
         int writeSelfToParcel(Parcel out, PooledStringWriter pwriter, boolean sanitizeOnWrite,
                 float[] tmpMatrix) {
-            // Guard used to skip non-sanitized data when writing for auto-fill.
+            // Guard used to skip non-sanitized data when writing for autofill.
             boolean writeSensitive = true;
 
             int flags = mFlags & ~FLAGS_ALL_CONTROL;
             if (mId != View.NO_ID) {
                 flags |= FLAGS_HAS_ID;
             }
-            if (mAutoFillId != null) {
-                flags |= FLAGS_HAS_AUTO_FILL_DATA;
+            if (mAutofillId != null) {
+                flags |= FLAGS_HAS_AUTOFILL_DATA;
             }
             if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
                     || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
@@ -737,8 +789,8 @@
             pwriter.writeString(mClassName);
 
             int writtenFlags = flags;
-            if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0 && (mSanitized || !sanitizeOnWrite)) {
-                // Remove 'checked' from sanitized auto-fill request.
+            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0 && (mSanitized || !sanitizeOnWrite)) {
+                // Remove 'checked' from sanitized autofill request.
                 writtenFlags = flags & ~FLAGS_CHECKED;
             }
 
@@ -753,15 +805,15 @@
                     }
                 }
             }
-            if ((flags&FLAGS_HAS_AUTO_FILL_DATA) != 0) {
+            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
                 writeSensitive = mSanitized || !sanitizeOnWrite;
                 out.writeInt(mSanitized ? 1 : 0);
-                out.writeParcelable(mAutoFillId, 0);
+                out.writeParcelable(mAutofillId, 0);
                 out.writeInt(mAutofillType);
-                out.writeInt(mAutoFillHint);
-                final AutoFillValue sanitizedValue = writeSensitive ? mAutoFillValue : null;
+                out.writeInt(mAutofillHint);
+                final AutofillValue sanitizedValue = writeSensitive ? mAutofillValue : null;
                 out.writeParcelable(sanitizedValue,  0);
-                out.writeStringArray(mAutoFillOptions);
+                out.writeStringArray(mAutofillOptions);
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 out.writeInt(mX);
@@ -840,17 +892,26 @@
         }
 
         /**
-         * Gets the id that can be used to auto-fill the view contents.
-         *
-         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
-         * for assist.
+         * @hide
+         * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
          */
-        // TODO(b/33197203, b/33802548): add CTS/unit test
+        @Deprecated
         public AutoFillId getAutoFillId() {
-            return mAutoFillId;
+            return AutoFillId.forDaRealId(mAutofillId);
         }
 
         /**
+         * Gets the id that can be used to autofill the view contents.
+         *
+         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
+         * for assist.
+         */
+        public AutofillId getAutofillId() {
+            return mAutofillId;
+        }
+
+        /**
+         * @hide
          * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype()
          */
         @Deprecated
@@ -870,9 +931,9 @@
         }
 
         /**
-         * Gets the the type of value that can be used to auto-fill the view contents.
+         * Gets the the type of value that can be used to autofill the view contents.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
          * for assist.
          */
         public @View.AutofillType int getAutofillType() {
@@ -880,41 +941,48 @@
         }
 
         /**
-         * Describes the content of a view so that a auto-fill service can fill in the appropriate
+         * Describes the content of a view so that a autofill service can fill in the appropriate
          * data.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
          * for assist.</p>
          *
          * @return The hint for this view
          */
-        // TODO(b/35364993): add CTS/unit test
-        @View.AutoFillHint public int getAutoFillHint() {
-            return mAutoFillHint;
+        @View.AutofillHint public int getAutoFillHint() {
+            return mAutofillHint;
+        }
+
+        /**
+         * @hide
+         * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
+         */
+        @Deprecated
+        public AutoFillValue getAutoFillValue() {
+            return AutoFillValue.forDaRealValue(mAutofillValue);
         }
 
         /**
          * Gets the the value of this view.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
          * for assist.
          */
-        // TODO(b/33197203, b/33802548): add CTS/unit test
-        public AutoFillValue getAutoFillValue() {
-            return mAutoFillValue;
+        public AutofillValue getAutofillValue() {
+            return mAutofillValue;
         }
 
         /**
-         * Gets the options that can be used to auto-fill this structure.
+         * Gets the options that can be used to autofill this structure.
          *
-         * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning
-         * of each possible value in the list.
+         * <p>Typically used by nodes whose {@link View#getAutofillType()} is a list to indicate
+         * the meaning of each possible value in the list.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for auto-filling purposes, not
+         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
          * for assist.
          */
-        public String[] getAutoFillOptions() {
-            return mAutoFillOptions;
+        public String[] getAutofillOptions() {
+            return mAutofillOptions;
         }
 
         /**
@@ -932,18 +1000,18 @@
         }
 
         /**
-         * Updates the {@link AutoFillValue} of this structure.
+         * Updates the {@link AutofillValue} of this structure.
          *
          * <p>Should be used just before sending the structure to the
-         * {@link android.service.autofill.AutoFillService} for saving, since it will override the
+         * {@link android.service.autofill.AutofillService} for saving, since it will override the
          * initial value.
          *
          * @hide
          */
-        public void updateAutoFillValue(AutoFillValue value) {
-            mAutoFillValue = value;
+        public void updateAutofillValue(AutofillValue value) {
+            mAutofillValue = value;
             // TODO(b/33197203, b/33802548): decide whether to set text as well (so it would work
-            // with "legacy" views) or just the auto-fill value
+            // with "legacy" views) or just the autofill value
             final CharSequence text = value.getTextValue();
             if (text != null) {
                 mText.mText = text;
@@ -1102,6 +1170,11 @@
         }
 
         /**
+         * Returns true if this node is opaque.
+         */
+        public boolean isOpaque() { return (mFlags&ViewNode.FLAGS_OPAQUE) != 0; }
+
+        /**
          * Returns true if this node is something the user can perform a long click/press on.
          */
         public boolean isLongClickable() {
@@ -1142,8 +1215,8 @@
          * <li>Child nodes that represent hyperlinks (contains the hyperlink URL).
          * </ol>
          *
-         * <strong>WARNING:</strong> a {@link android.service.autofill.AutoFillService} should only
-         * use this URL for auto-fill purposes when it trusts the app generating it (i.e., the app
+         * <strong>WARNING:</strong> a {@link android.service.autofill.AutofillService} should only
+         * use this URL for autofill purposes when it trusts the app generating it (i.e., the app
          * defined by {@link AssistStructure#getActivityComponent()}).
          */
         public String getUrl() {
@@ -1394,6 +1467,12 @@
         }
 
         @Override
+        public void setOpaque(boolean opaque) {
+            mNode.mFlags = (mNode.mFlags & ~ViewNode.FLAGS_OPAQUE)
+                    | (opaque ? ViewNode.FLAGS_OPAQUE : 0);
+        }
+
+        @Override
         public void setClassName(String className) {
             mNode.mClassName = className;
         }
@@ -1504,15 +1583,15 @@
             return mNode.mChildren != null ? mNode.mChildren.length : 0;
         }
 
-        private void setAutoFillId(ViewNode child, boolean forAutoFill, int virtualId) {
+        private void setAutofillId(ViewNode child, boolean forAutoFill, int virtualId) {
             if (forAutoFill) {
-                child.mAutoFillId = new AutoFillId(mNode.mAutoFillId, virtualId);
+                child.mAutofillId = new AutofillId(mNode.mAutofillId, virtualId);
             }
         }
 
         private ViewStructure newChild(int index, boolean forAutoFill, int virtualId, int flags) {
             ViewNode node = new ViewNode();
-            setAutoFillId(node, forAutoFill, virtualId);
+            setAutofillId(node, forAutoFill, virtualId);
             mNode.mChildren[index] = node;
             return new ViewNodeBuilder(mAssist, node, false);
         }
@@ -1520,7 +1599,7 @@
         private ViewStructure asyncNewChild(int index, boolean forAutoFill, int virtualId) {
             synchronized (mAssist) {
                 ViewNode node = new ViewNode();
-                setAutoFillId(node, forAutoFill, virtualId);
+                setAutofillId(node, forAutoFill, virtualId);
                 mNode.mChildren[index] = node;
                 ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true);
                 mAssist.mPendingAsyncChildren.add(builder);
@@ -1535,7 +1614,7 @@
 
         // TODO(b/33197203, b/33802548): add CTS/unit test
         @Override
-        public ViewStructure newChildForAutoFill(int index, int virtualId, int flags) {
+        public ViewStructure newChildForAutofill(int index, int virtualId, int flags) {
             return newChild(index, true, virtualId, flags);
         }
 
@@ -1545,7 +1624,7 @@
         }
 
         @Override
-        public ViewStructure asyncNewChildForAutoFill(int index, int virtualId, int flags) {
+        public ViewStructure asyncNewChildForAutofill(int index, int virtualId, int flags) {
             return asyncNewChild(index, true, virtualId);
         }
 
@@ -1569,28 +1648,13 @@
         }
 
         @Override
-        public void setAutoFillId(int viewId) {
-            mNode.mAutoFillId = new AutoFillId(viewId);
+        public void setAutofillId(int viewId) {
+            mNode.mAutofillId = new AutofillId(viewId);
         }
 
         @Override
-        public AutoFillId getAutoFillId() {
-            return mNode.mAutoFillId;
-        }
-
-        @Override
-        public void setAutoFillType(AutoFillType type) {
-            if (type == null) return;
-
-            if (type.isText()) {
-                mNode.mAutofillType = View.AUTOFILL_TYPE_TEXT;
-            } else if (type.isToggle()) {
-                mNode.mAutofillType = View.AUTOFILL_TYPE_TOGGLE;
-            } else if (type.isList()) {
-                mNode.mAutofillType = View.AUTOFILL_TYPE_LIST;
-            } else if (type.isDate()) {
-                mNode.mAutofillType = View.AUTOFILL_TYPE_DATE;
-            }
+        public AutofillId getAutofillId() {
+            return mNode.mAutofillId;
         }
 
         @Override
@@ -1599,18 +1663,18 @@
         }
 
         @Override
-        public void setAutoFillHint(@View.AutoFillHint int hint) {
-            mNode.mAutoFillHint = hint;
+        public void setAutofillHint(@View.AutofillHint int hint) {
+            mNode.mAutofillHint = hint;
         }
 
         @Override
-        public void setAutoFillValue(AutoFillValue value) {
-            mNode.mAutoFillValue = value;
+        public void setAutofillValue(AutofillValue value) {
+            mNode.mAutofillValue = value;
         }
 
         @Override
-        public void setAutoFillOptions(String[] options) {
-            mNode.mAutoFillOptions = options;
+        public void setAutofillOptions(String[] options) {
+            mNode.mAutofillOptions = options;
         }
 
         @Override
@@ -1648,13 +1712,14 @@
 
     /** @hide */
     public AssistStructure(Parcel in) {
+        mIsHomeActivity = in.readInt() == 1;
         mReceiveChannel = in.readStrongBinder();
     }
 
     /**
      * Helper method used to sanitize the structure before it's written to a parcel.
      *
-     * <p>Used just on auto-fill.
+     * <p>Used just on autofill.
      * @hide
      */
     public void sanitizeForParceling(boolean sanitize) {
@@ -1739,16 +1804,16 @@
         if (node.isAssistBlocked()) {
             Log.i(TAG, prefix + "  BLOCKED");
         }
-        AutoFillId autoFillId = node.getAutoFillId();
-        if (autoFillId == null) {
-            Log.i(TAG, prefix + " NO AUTO-FILL ID");
+        AutofillId autofillId = node.getAutofillId();
+        if (autofillId == null) {
+            Log.i(TAG, prefix + " NO autofill ID");
         } else {
-            Log.i(TAG, prefix + "AutoFill info: id= " + autoFillId
+            Log.i(TAG, prefix + "Autofill info: id= " + autofillId
                     + ", type=" + node.getAutofillType()
-                    + ", options=" + Arrays.toString(node.getAutoFillOptions())
+                    + ", options=" + Arrays.toString(node.getAutofillOptions())
                     + ", inputType=" + node.getInputType()
                     + ", hint=" + Integer.toHexString(node.getAutoFillHint())
-                    + ", value=" + node.getAutoFillValue()
+                    + ", value=" + node.getAutofillValue()
                     + ", sanitized=" + node.isSanitized());
         }
 
@@ -1772,6 +1837,15 @@
     }
 
     /**
+     * Returns whether the activity associated with this AssistStructure was the home activity
+     * at the time the assist data was acquired.
+     * @return Whether the activity was the home activity.
+     */
+    public boolean isHomeActivity() {
+        return mIsHomeActivity;
+    }
+
+    /**
      * Return the number of window contents that have been collected in this assist data.
      */
     public int getWindowNodeCount() {
@@ -1833,6 +1907,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mIsHomeActivity ? 1 : 0);
         if (mHaveData) {
             // This object holds its data.  We want to write a send channel that the
             // other side can use to retrieve that data.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index d36692a..488511b 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1447,9 +1447,9 @@
     }
 
     /**
-     * Return true if LE Periodic Advertising feature is supported.
+     * Return true if LE Extended Advertising feature is supported.
      *
-     * @return true if chipset supports LE Periodic Advertising feature
+     * @return true if chipset supports LE Extended Advertising feature
      */
     public boolean isLeExtendedAdvertisingSupported() {
         if (!getLeAccess()) return false;
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index 03a01e1..453dd70 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -284,7 +284,7 @@
          *
          * @param isAnonymous wether anonymous advertising should be used.
          */
-        public Builder setAnonymouus(boolean isAnonymous) {
+        public Builder setAnonymous(boolean isAnonymous) {
             this.isAnonymous = isAnonymous;
             return this;
         }
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index b89c64a..457096b 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -23,6 +23,8 @@
 import android.os.ParcelUuid;
 import android.os.Parcelable;
 
+import com.android.internal.util.BitUtils;
+
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -345,15 +347,7 @@
 
     // Check if the uuid pattern matches the particular service uuid.
     private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
-        if (mask == null) {
-            return uuid.equals(data);
-        }
-        if ((uuid.getLeastSignificantBits() & mask.getLeastSignificantBits()) !=
-                (data.getLeastSignificantBits() & mask.getLeastSignificantBits())) {
-            return false;
-        }
-        return ((uuid.getMostSignificantBits() & mask.getMostSignificantBits()) ==
-                (data.getMostSignificantBits() & mask.getMostSignificantBits()));
+        return BitUtils.maskedEquals(data, uuid, mask);
     }
 
     // Check whether the data pattern matches the parsed data.
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index 583ddd2..745cd16 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -67,12 +67,12 @@
     public static final int SID_NOT_PRESENT = 0xFF;
 
     /**
-     * Mask for checking wether event type represents legacy advertisement.
+     * Mask for checking whether event type represents legacy advertisement.
      */
     private static final int ET_LEGACY_MASK = 0x10;
 
     /**
-     * Mask for checking wether event type represents connectable advertisement.
+     * Mask for checking whether event type represents connectable advertisement.
      */
     private static final int ET_CONNECTABLE_MASK = 0x01;
 
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index d477f43..56f5d44 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -16,20 +16,21 @@
 
 package android.companion;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.OneTimeUseBuilder;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * A request for the user to select a companion device to associate with.
  *
- * You can optionally set a {@link Builder#setDeviceFilter filter} for which devices to show to the
+ * You can optionally set {@link Builder#addDeviceFilter filters} for which devices to show to the
  * user to select from.
  * The exact type and fields of the filter you can set depend on the
  * medium type. See {@link Builder}'s static factory methods for specific protocols that are
@@ -37,38 +38,22 @@
  *
  * You can also set {@link Builder#setSingleDevice single device} to request a popup with single
  * device to be shown instead of a list to choose from
- *
- * @param <F> Device filter type
  */
-public final class AssociationRequest<F extends DeviceFilter> implements Parcelable {
-
-    /** @hide */
-    public static final int MEDIUM_TYPE_BLUETOOTH = 0;
-    /** @hide */
-    public static final int MEDIUM_TYPE_BLUETOOTH_LE = 1;
-    /** @hide */
-    public static final int MEDIUM_TYPE_WIFI = 2;
-
-    /** @hide */
-    @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediumType {}
+public final class AssociationRequest implements Parcelable {
 
     private final boolean mSingleDevice;
-    private final int mMediumType;
-    private final F mDeviceFilter;
+    private final List<DeviceFilter<?>> mDeviceFilters;
 
-    private AssociationRequest(boolean singleDevice, int mMediumType, F deviceFilter) {
+    private AssociationRequest(
+            boolean singleDevice, @Nullable List<DeviceFilter<?>> deviceFilters) {
         this.mSingleDevice = singleDevice;
-        this.mMediumType = mMediumType;
-        this.mDeviceFilter = deviceFilter;
+        this.mDeviceFilters = ArrayUtils.emptyIfNull(deviceFilters);
     }
 
     private AssociationRequest(Parcel in) {
         this(
             in.readByte() != 0,
-            in.readInt(),
-            in.readParcelable(AssociationRequest.class.getClassLoader()));
+            in.readParcelableList(new ArrayList<>(), AssociationRequest.class.getClassLoader()));
     }
 
     /** @hide */
@@ -77,22 +62,15 @@
     }
 
     /** @hide */
-    @MediumType
-    public int getMediumType() {
-        return mMediumType;
-    }
-
-    /** @hide */
-    @Nullable
-    public F getDeviceFilter() {
-        return mDeviceFilter;
+    @NonNull
+    public List<DeviceFilter<?>> getDeviceFilters() {
+        return mDeviceFilters;
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeByte((byte) (mSingleDevice ? 1 : 0));
-        dest.writeInt(mMediumType);
-        dest.writeParcelable(mDeviceFilter, flags);
+        dest.writeParcelableList(mDeviceFilters, flags);
     }
 
     @Override
@@ -114,45 +92,19 @@
 
     /**
      * A builder for {@link AssociationRequest}
-     *
-     * @param <F> the type of filter for the request.
      */
-    public static final class Builder<F extends DeviceFilter>
-            extends OneTimeUseBuilder<AssociationRequest<F>> {
+    public static final class Builder extends OneTimeUseBuilder<AssociationRequest> {
         private boolean mSingleDevice = false;
-        @MediumType private int mMediumType;
-        @Nullable private F mDeviceFilter = null;
+        @Nullable private ArrayList<DeviceFilter<?>> mDeviceFilters = null;
 
-        private Builder() {}
-
-        /**
-         * Create a new builder for an association request with a Bluetooth LE device
-         */
-        @NonNull
-        public static Builder<BluetoothLEDeviceFilter> createForBluetoothLEDevice() {
-            return new Builder<BluetoothLEDeviceFilter>()
-                    .setMediumType(MEDIUM_TYPE_BLUETOOTH_LE);
-        }
-
-        /**
-         * Create a new builder for an association request with a Bluetooth(non-LE) device
-         */
-        @NonNull
-        public static Builder<BluetoothDeviceFilter> createForBluetoothDevice() {
-            return new Builder<BluetoothDeviceFilter>()
-                    .setMediumType(MEDIUM_TYPE_BLUETOOTH);
-        }
-
-        //TODO implement, once specific filter classes are available
-//        public static Builder<> createForWiFiDevice()
-//        public static Builder<> createForNanDevice()
+        public Builder() {}
 
         /**
          * @param singleDevice if true, scanning for a device will stop as soon as at least one
          *                     fitting device is found
          */
         @NonNull
-        public Builder<F> setSingleDevice(boolean singleDevice) {
+        public Builder setSingleDevice(boolean singleDevice) {
             checkNotUsed();
             this.mSingleDevice = singleDevice;
             return this;
@@ -163,29 +115,20 @@
          *                     user
          */
         @NonNull
-        public Builder<F> setDeviceFilter(@Nullable F deviceFilter) {
+        public Builder addDeviceFilter(@Nullable DeviceFilter<?> deviceFilter) {
             checkNotUsed();
-            this.mDeviceFilter = deviceFilter;
-            return this;
-        }
-
-        /**
-         * @param deviceType A type of medium over which to discover devices
-         *
-         * @see MediumType
-         */
-        @NonNull
-        private Builder<F> setMediumType(@MediumType int deviceType) {
-            mMediumType = deviceType;
+            if (deviceFilter != null) {
+                mDeviceFilters = ArrayUtils.add(mDeviceFilters, deviceFilter);
+            }
             return this;
         }
 
         /** @inheritDoc */
         @NonNull
         @Override
-        public AssociationRequest<F> build() {
+        public AssociationRequest build() {
             markUsed();
-            return new AssociationRequest<>(mSingleDevice, mMediumType, mDeviceFilter);
+            return new AssociationRequest(mSingleDevice, mDeviceFilters);
         }
     }
 }
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
index 5a69955..0f16b7b 100644
--- a/core/java/android/companion/BluetoothDeviceFilter.java
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -16,6 +16,7 @@
 
 package android.companion;
 
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
 import static android.companion.BluetoothDeviceFilterUtils.matchesAddress;
 import static android.companion.BluetoothDeviceFilterUtils.matchesName;
 import static android.companion.BluetoothDeviceFilterUtils.matchesServiceUuids;
@@ -40,8 +41,6 @@
  */
 public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice> {
 
-    private static BluetoothDeviceFilter NO_OP;
-
     private final Pattern mNamePattern;
     private final String mAddress;
     private final List<ParcelUuid> mServiceUuids;
@@ -67,22 +66,7 @@
     }
 
     private static List<ParcelUuid> readUuids(Parcel in) {
-        final ArrayList<ParcelUuid> list = new ArrayList<>();
-        in.readParcelableList(list, ParcelUuid.class.getClassLoader());
-        return list;
-    }
-
-    /** @hide */
-    @NonNull
-    public static BluetoothDeviceFilter nullsafe(@Nullable BluetoothDeviceFilter nullable) {
-        return nullable != null ? nullable : noOp();
-    }
-
-    /** @hide */
-    @NonNull
-    public static BluetoothDeviceFilter noOp() {
-        if (NO_OP == null) NO_OP = new Builder().build();
-        return NO_OP;
+        return in.readParcelableList(new ArrayList<>(), ParcelUuid.class.getClassLoader());
     }
 
     /** @hide */
@@ -94,6 +78,18 @@
     }
 
     /** @hide */
+    @Override
+    public String getDeviceDisplayName(BluetoothDevice device) {
+        return getDeviceDisplayNameInternal(device);
+    }
+
+    /** @hide */
+    @Override
+    public int getMediumType() {
+        return DeviceFilter.MEDIUM_TYPE_BLUETOOTH;
+    }
+
+    /** @hide */
     @Nullable
     public Pattern getNamePattern() {
         return mNamePattern;
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 289f995..8a316f1 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -23,7 +23,9 @@
 import android.annotation.Nullable;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.le.ScanFilter;
+import android.net.wifi.ScanResult;
 import android.os.ParcelUuid;
+import android.os.Parcelable;
 import android.util.Log;
 
 import java.util.Arrays;
@@ -96,12 +98,47 @@
         return result;
     }
 
-    private static void debugLogMatchResult(
-            boolean result, BluetoothDevice device, Object criteria) {
-        Log.i(LOG_TAG, getDeviceDisplayName(device) + (result ? " ~ " : " !~ ") + criteria);
+    static boolean matchesName(@Nullable Pattern namePattern, ScanResult device) {
+        boolean result;
+        if (namePattern == null)  {
+            result = true;
+        } else if (device == null) {
+            result = false;
+        } else {
+            final String name = device.SSID;
+            result = name != null && namePattern.matcher(name).find();
+        }
+        if (DEBUG) debugLogMatchResult(result, device, namePattern);
+        return result;
     }
 
-    public static String getDeviceDisplayName(@NonNull BluetoothDevice device) {
+    private static void debugLogMatchResult(
+            boolean result, BluetoothDevice device, Object criteria) {
+        Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria);
+    }
+
+    private static void debugLogMatchResult(
+            boolean result, ScanResult device, Object criteria) {
+        Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria);
+    }
+
+    public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) {
         return firstNotEmpty(device.getAliasName(), device.getAddress());
     }
+
+    public static String getDeviceDisplayNameInternal(@NonNull ScanResult device) {
+        return firstNotEmpty(device.SSID, device.BSSID);
+    }
+
+    public static String getDeviceMacAddress(@NonNull Parcelable device) {
+        if (device instanceof BluetoothDevice) {
+            return ((BluetoothDevice) device).getAddress();
+        } else if (device instanceof ScanResult) {
+            return ((ScanResult) device).BSSID;
+        } else if (device instanceof android.bluetooth.le.ScanResult) {
+            return getDeviceMacAddress(((android.bluetooth.le.ScanResult) device).getDevice());
+        } else {
+            throw new IllegalArgumentException("Unknown device type: " + device);
+        }
+    }
 }
diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java
index 4a481ca..e057fbc 100644
--- a/core/java/android/companion/BluetoothLEDeviceFilter.java
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.java
@@ -16,18 +16,25 @@
 
 package android.companion;
 
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
 import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
 import static android.companion.BluetoothDeviceFilterUtils.patternToString;
 
+import static com.android.internal.util.Preconditions.checkArgument;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
 import android.os.Parcel;
 import android.provider.OneTimeUseBuilder;
+import android.text.TextUtils;
 
+import com.android.internal.util.BitUtils;
 import com.android.internal.util.ObjectUtils;
+import com.android.internal.util.Preconditions;
 
 import java.util.regex.Pattern;
 
@@ -36,36 +43,33 @@
  *
  * @see ScanFilter
  */
-public final class BluetoothLEDeviceFilter implements DeviceFilter<BluetoothDevice> {
+public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
 
-    private static BluetoothLEDeviceFilter NO_OP;
+    private static final int RENAME_PREFIX_LENGTH_LIMIT = 10;
 
     private final Pattern mNamePattern;
     private final ScanFilter mScanFilter;
+    private final byte[] mRawDataFilter;
+    private final byte[] mRawDataFilterMask;
+    private final String mRenamePrefix;
+    private final String mRenameSuffix;
+    private final int mRenameBytesFrom;
+    private final int mRenameBytesTo;
+    private final boolean mRenameBytesReverseOrder;
 
-    private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter) {
+    private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter,
+            byte[] rawDataFilter, byte[] rawDataFilterMask, String renamePrefix,
+            String renameSuffix, int renameBytesFrom, int renameBytesTo,
+            boolean renameBytesReverseOrder) {
         mNamePattern = namePattern;
         mScanFilter = ObjectUtils.firstNotNull(scanFilter, ScanFilter.EMPTY);
-    }
-
-    @SuppressLint("ParcelClassLoader")
-    private BluetoothLEDeviceFilter(Parcel in) {
-        this(
-            patternFromString(in.readString()),
-            in.readParcelable(null));
-    }
-
-    /** @hide */
-    @NonNull
-    public static BluetoothLEDeviceFilter nullsafe(@Nullable BluetoothLEDeviceFilter nullable) {
-        return nullable != null ? nullable : noOp();
-    }
-
-    /** @hide */
-    @NonNull
-    public static BluetoothLEDeviceFilter noOp() {
-        if (NO_OP == null) NO_OP = new Builder().build();
-        return NO_OP;
+        mRawDataFilter = rawDataFilter;
+        mRawDataFilterMask = rawDataFilterMask;
+        mRenamePrefix = renamePrefix;
+        mRenameSuffix = renameSuffix;
+        mRenameBytesFrom = renameBytesFrom;
+        mRenameBytesTo = renameBytesTo;
+        mRenameBytesReverseOrder = renameBytesReverseOrder;
     }
 
     /** @hide */
@@ -81,12 +85,80 @@
     }
 
     /** @hide */
+    @Nullable
+    public byte[] getRawDataFilter() {
+        return mRawDataFilter;
+    }
+
+    /** @hide */
+    @Nullable
+    public byte[] getRawDataFilterMask() {
+        return mRawDataFilterMask;
+    }
+
+    /** @hide */
+    @Nullable
+    public String getRenamePrefix() {
+        return mRenamePrefix;
+    }
+
+    /** @hide */
+    @Nullable
+    public String getRenameSuffix() {
+        return mRenameSuffix;
+    }
+
+    /** @hide */
+    public int getRenameBytesFrom() {
+        return mRenameBytesFrom;
+    }
+
+    /** @hide */
+    public int getRenameBytesTo() {
+        return mRenameBytesTo;
+    }
+
+    /** @hide */
+    public boolean isRenameBytesReverseOrder() {
+        return mRenameBytesReverseOrder;
+    }
+
+    /** @hide */
     @Override
-    public boolean matches(BluetoothDevice device) {
+    @Nullable
+    public String getDeviceDisplayName(ScanResult sr) {
+        if (mRenameBytesFrom < 0) return getDeviceDisplayNameInternal(sr.getDevice());
+        final byte[] bytes = sr.getScanRecord().getBytes();
+        final StringBuilder sb = new StringBuilder(TextUtils.emptyIfNull(mRenamePrefix));
+        int startInclusive = mRenameBytesFrom;
+        int endInclusive = mRenameBytesTo - 1;
+        int initial = mRenameBytesReverseOrder ? endInclusive : startInclusive;
+        int step = mRenameBytesReverseOrder ? -1 : 1;
+        for (int i = initial; startInclusive <= i && i <= endInclusive; i+=step) {
+            sb.append(Byte.toHexString(bytes[i], true));
+        }
+        return sb.append(TextUtils.emptyIfNull(mRenameSuffix)).toString();
+    }
+
+    /** @hide */
+    @Override
+    public boolean matches(ScanResult device) {
+        return matches(device.getDevice())
+                && BitUtils.maskedEquals(device.getScanRecord().getBytes(),
+                        mRawDataFilter, mRawDataFilterMask);
+    }
+
+    private boolean matches(BluetoothDevice device) {
         return BluetoothDeviceFilterUtils.matches(getScanFilter(), device)
                 && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
     }
 
+    /** @hide */
+    @Override
+    public int getMediumType() {
+        return DeviceFilter.MEDIUM_TYPE_BLUETOOTH_LE;
+    }
+
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(patternToString(getNamePattern()));
@@ -102,7 +174,13 @@
             = new Creator<BluetoothLEDeviceFilter>() {
         @Override
         public BluetoothLEDeviceFilter createFromParcel(Parcel in) {
-            return new BluetoothLEDeviceFilter(in);
+            return new BluetoothLEDeviceFilter.Builder()
+                    .setNamePattern(patternFromString(in.readString()))
+                    .setScanFilter(in.readParcelable(null))
+                    .setRawDataFilter(in.readBlob(), in.readBlob())
+                    .setRename(in.readString(), in.readString(),
+                            in.readInt(), in.readInt(), in.readBoolean())
+                    .build();
         }
 
         @Override
@@ -111,16 +189,28 @@
         }
     };
 
+    public static int getRenamePrefixLengthLimit() {
+        return RENAME_PREFIX_LENGTH_LIMIT;
+    }
+
     /**
      * Builder for {@link BluetoothLEDeviceFilter}
      */
     public static final class Builder extends OneTimeUseBuilder<BluetoothLEDeviceFilter> {
         private ScanFilter mScanFilter;
         private Pattern mNamePattern;
+        private byte[] mRawDataFilter;
+        private byte[] mRawDataFilterMask;
+        private String mRenamePrefix;
+        private String mRenameSuffix;
+        private int mRenameBytesFrom = -1;
+        private int mRenameBytesTo;
+        private boolean mRenameBytesReverseOrder = false;
 
         /**
          * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
          *              given regular expression will be shown
+         * @return self for chaining
          */
         public Builder setNamePattern(@Nullable Pattern regex) {
             checkNotUsed();
@@ -131,6 +221,7 @@
         /**
          * @param scanFilter a {@link ScanFilter} to filter devices by
          *
+         * @return self for chaining
          * @see ScanFilter for specific details on its various fields
          */
         @NonNull
@@ -140,12 +231,66 @@
             return this;
         }
 
+        /**
+         * Filter devices by raw advertisement data, as obtained by {@link ScanRecord#getBytes}
+         *
+         * @param rawDataFilter bit values that have to match against advertized data
+         * @param rawDataFilterMask bits that have to be matched
+         * @return self for chaining
+         */
+        @NonNull
+        public Builder setRawDataFilter(@NonNull byte[] rawDataFilter,
+                @NonNull byte[] rawDataFilterMask) {
+            checkNotUsed();
+            checkArgument(rawDataFilter.length == rawDataFilterMask.length,
+                    "Mask and filter should be the same length");
+            mRawDataFilter = Preconditions.checkNotNull(rawDataFilter);
+            mRawDataFilterMask = Preconditions.checkNotNull(rawDataFilterMask);
+            return this;
+        }
+
+        /**
+         * Rename the devices shown in the list, using specific bytes from the raw advertisement
+         * data ({@link ScanRecord#getBytes}) in hexadecimal format, as well as a custom
+         * prefix/suffix around them
+         *
+         * Note that the prefix length is limited to {@link #getRenamePrefixLengthLimit} characters
+         * to ensure that there's enough space to display the byte data
+         *
+         * The range of bytes to be displayed cannot be empty
+         *
+         * @param prefix to be displayed before the byte data
+         * @param suffix to be displayed after the byte data
+         * @param bytesFrom the start byte index to be displayed (inclusive)
+         * @param bytesTo the end byte index to be displayed (exclusive)
+         * @param bytesReverseOrder if true, the byte order of the provided range will be flipped
+         *                          when displaying
+         * @return self for chaining
+         */
+        @NonNull
+        public Builder setRename(@NonNull String prefix, @NonNull String suffix,
+                int bytesFrom, int bytesTo, boolean bytesReverseOrder) {
+            checkNotUsed();
+            checkArgument(TextUtils.length(prefix) >= getRenamePrefixLengthLimit(),
+                    "Prefix is too short");
+            mRenamePrefix = prefix;
+            mRenameSuffix = suffix;
+            checkArgument(bytesFrom < bytesTo, "Byte range must be non-empty");
+            mRenameBytesFrom = bytesFrom;
+            mRenameBytesTo = bytesTo;
+            mRenameBytesReverseOrder = bytesReverseOrder;
+            return this;
+        }
+
         /** @inheritDoc */
         @Override
         @NonNull
         public BluetoothLEDeviceFilter build() {
             markUsed();
-            return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter);
+            return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter,
+                    mRawDataFilter, mRawDataFilterMask,
+                    mRenamePrefix, mRenameSuffix,
+                    mRenameBytesFrom, mRenameBytesTo, mRenameBytesReverseOrder);
         }
     }
 }
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 6fa32b4..5710ad1 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -117,7 +117,7 @@
      * @see AssociationRequest
      */
     public void associate(
-            @NonNull AssociationRequest<?> request,
+            @NonNull AssociationRequest request,
             @NonNull Callback callback,
             @Nullable Handler handler) {
         final Handler finalHandler = handler != null
diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java
index 8362b2d..9b4fdfd 100644
--- a/core/java/android/companion/DeviceFilter.java
+++ b/core/java/android/companion/DeviceFilter.java
@@ -17,17 +17,28 @@
 
 package android.companion;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A filter for companion devices of type {@code D}
  *
  * @param <D> Type of devices, filtered by this filter,
- *           e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.WifiInfo}
+ *           e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.ScanResult}
  */
 public interface DeviceFilter<D extends Parcelable> extends Parcelable {
 
+    /** @hide */
+    int MEDIUM_TYPE_BLUETOOTH = 0;
+    /** @hide */
+    int MEDIUM_TYPE_BLUETOOTH_LE = 1;
+    /** @hide */
+    int MEDIUM_TYPE_WIFI = 2;
+
     /**
      * @return whether the given device matches this filter
      *
@@ -35,6 +46,12 @@
      */
     boolean matches(D device);
 
+    /** @hide */
+    String getDeviceDisplayName(D device);
+
+    /**  @hide */
+    @MediumType int getMediumType();
+
     /**
      * A nullsafe {@link #matches(Parcelable)}, returning true if the filter is null
      *
@@ -43,4 +60,9 @@
     static <D extends Parcelable> boolean matches(@Nullable DeviceFilter<D> filter, D device) {
         return filter == null || filter.matches(device);
     }
+
+    /** @hide */
+    @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface MediumType {}
 }
diff --git a/core/java/android/companion/WifiDeviceFilter.java b/core/java/android/companion/WifiDeviceFilter.java
new file mode 100644
index 0000000..1ab9ce1
--- /dev/null
+++ b/core/java/android/companion/WifiDeviceFilter.java
@@ -0,0 +1,125 @@
+/*
+ * 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.companion;
+
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
+import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
+import static android.companion.BluetoothDeviceFilterUtils.patternToString;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.net.wifi.ScanResult;
+import android.os.Parcel;
+import android.provider.OneTimeUseBuilder;
+
+import java.util.regex.Pattern;
+
+/**
+ * A filter for Wifi devices
+ *
+ * @see ScanFilter
+ */
+public final class WifiDeviceFilter implements DeviceFilter<ScanResult> {
+
+    private final Pattern mNamePattern;
+
+    private WifiDeviceFilter(Pattern namePattern) {
+        mNamePattern = namePattern;
+    }
+
+    @SuppressLint("ParcelClassLoader")
+    private WifiDeviceFilter(Parcel in) {
+        this(patternFromString(in.readString()));
+    }
+
+    /** @hide */
+    @Nullable
+    public Pattern getNamePattern() {
+        return mNamePattern;
+    }
+
+
+    /** @hide */
+    @Override
+    public boolean matches(ScanResult device) {
+        return BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
+    }
+
+    /** @hide */
+    @Override
+    public String getDeviceDisplayName(ScanResult device) {
+        return getDeviceDisplayNameInternal(device);
+    }
+
+    /** @hide */
+    @Override
+    public int getMediumType() {
+        return MEDIUM_TYPE_WIFI;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(patternToString(getNamePattern()));
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<WifiDeviceFilter> CREATOR
+            = new Creator<WifiDeviceFilter>() {
+        @Override
+        public WifiDeviceFilter createFromParcel(Parcel in) {
+            return new WifiDeviceFilter(in);
+        }
+
+        @Override
+        public WifiDeviceFilter[] newArray(int size) {
+            return new WifiDeviceFilter[size];
+        }
+    };
+
+    /**
+     * Builder for {@link WifiDeviceFilter}
+     */
+    public static final class Builder extends OneTimeUseBuilder<WifiDeviceFilter> {
+        private Pattern mNamePattern;
+
+        /**
+         * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
+         *              given regular expression will be shown
+         * @return self for chaining
+         */
+        public Builder setNamePattern(@Nullable Pattern regex) {
+            checkNotUsed();
+            mNamePattern = regex;
+            return this;
+        }
+
+        /** @inheritDoc */
+        @Override
+        @NonNull
+        public WifiDeviceFilter build() {
+            markUsed();
+            return new WifiDeviceFilter(mNamePattern);
+        }
+    }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index de503c0..3cf96ed 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3401,12 +3401,12 @@
     public static final String VOICE_INTERACTION_MANAGER_SERVICE = "voiceinteraction";
 
     /**
-     * Official published name of the (internal) auto-fill service.
+     * Official published name of the (internal) autofill service.
      *
      * @hide
      * @see #getSystemService
      */
-    public static final String AUTO_FILL_MANAGER_SERVICE = "autofill";
+    public static final String AUTOFILL_MANAGER_SERVICE = "autofill";
 
     /**
      * Use with {@link #getSystemService} to access the
diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java
index 612b135..60b27b4 100644
--- a/core/java/android/metrics/LogMaker.java
+++ b/core/java/android/metrics/LogMaker.java
@@ -46,8 +46,9 @@
 
     private SparseArray<Object> entries = new SparseArray();
 
-    public LogMaker(int mainCategory) {
-        setCategory(mainCategory);
+    /** @param category for the new LogMaker. */
+    public LogMaker(int category) {
+        setCategory(category);
     }
 
     /* Deserialize from the eventlog */
@@ -55,71 +56,133 @@
       deserialize(items);
     }
 
+    /** @param category to replace the existing setting. */
     public LogMaker setCategory(int category) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_CATEGORY, category);
         return this;
     }
 
+    /** Set the category to unknown. */
     public LogMaker clearCategory() {
         entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_CATEGORY);
         return this;
     }
 
+    /** @param type to replace the existing setting. */
     public LogMaker setType(int type) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_TYPE, type);
         return this;
     }
 
+    /** Set the type to unknown. */
     public LogMaker clearType() {
         entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_TYPE);
         return this;
     }
 
+    /** @param subtype to replace the existing setting. */
     public LogMaker setSubtype(int subtype) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE, subtype);
         return this;
     }
 
+    /** Set the subtype to 0. */
     public LogMaker clearSubtype() {
         entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE);
         return this;
     }
 
+    /**
+     * This will be set by the system when the log is persisted.
+     * Client-supplied values will be ignored.
+     *
+     * @param timestamp to replace the existing settings.
+     * @hide
+     */
     public LogMaker setTimestamp(long timestamp) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_TIMESTAMP, timestamp);
         return this;
     }
 
+    /** Remove the timestamp property.
+     * @hide
+     */
     public LogMaker clearTimestamp() {
         entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_TIMESTAMP);
         return this;
     }
 
+    /** @param packageName to replace the existing setting. */
     public LogMaker setPackageName(String packageName) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME, packageName);
         return this;
     }
 
+    /** Remove the package name property. */
     public LogMaker clearPackageName() {
         entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME);
         return this;
     }
 
+    /**
+     * This will be set by the system when the log is persisted.
+     * Client-supplied values will be ignored.
+     *
+     * @param pid to replace the existing setting.
+     * @hide
+     */
+    public LogMaker setProcessId(int pid) {
+        entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_PID, pid);
+        return this;
+    }
+
+    /** Remove the process ID property.
+     * @hide
+     */
+    public LogMaker clearProcessId() {
+        entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_PID);
+        return this;
+    }
+
+    /**
+     * The name of the counter or histogram.
+     * Only useful for counter or histogram category objects.
+     * @param name to replace the existing setting.
+     * @hide
+     */
     public LogMaker setCounterName(String name) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME, name);
         return this;
     }
 
+    /**
+     * The bucket label, expressed as an integer.
+     * Only useful for histogram category objects.
+     * @param bucket to replace the existing setting.
+     * @hide
+     */
     public LogMaker setCounterBucket(int bucket) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET, bucket);
         return this;
     }
 
+    /**
+     * The bucket label, expressed as a long integer.
+     * Only useful for histogram category objects.
+     * @param bucket to replace the existing setting.
+     * @hide
+     */
     public LogMaker setCounterBucket(long bucket) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET, bucket);
         return this;
     }
 
+    /**
+     * The value to increment the counter or bucket by.
+     * Only useful for counter and histogram category objects.
+     * @param value to replace the existing setting.
+     * @hide
+     */
     public LogMaker setCounterValue(int value) {
         entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_VALUE, value);
         return this;
@@ -171,6 +234,7 @@
         return entries.get(tag);
     }
 
+    /** @return the category of the log, or unknown. */
     public int getCategory() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_CATEGORY);
         if (obj instanceof Integer) {
@@ -180,6 +244,7 @@
         }
     }
 
+    /** @return the type of the log, or unknwon. */
     public int getType() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_TYPE);
         if (obj instanceof Integer) {
@@ -189,6 +254,7 @@
         }
     }
 
+    /** @return the subtype of the log, or 0. */
     public int getSubtype() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE);
         if (obj instanceof Integer) {
@@ -198,6 +264,7 @@
         }
     }
 
+    /** @return the timestamp of the log.or 0 */
     public long getTimestamp() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_TIMESTAMP);
         if (obj instanceof Long) {
@@ -207,6 +274,7 @@
         }
     }
 
+    /** @return the package name of the log, or null. */
     public String getPackageName() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME);
         if (obj instanceof String) {
@@ -216,6 +284,17 @@
         }
     }
 
+    /** @return the process ID of the log, or -1. */
+    public int getProcessId() {
+        Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_PID);
+        if (obj instanceof Integer) {
+            return (Integer) obj;
+        } else {
+            return -1;
+        }
+    }
+
+    /** @return the name of the counter, or null. */
     public String getCounterName() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME);
         if (obj instanceof String) {
@@ -225,6 +304,7 @@
         }
     }
 
+    /** @return the bucket label of the histogram\, or 0. */
     public long getCounterBucket() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
         if (obj instanceof Number) {
@@ -234,11 +314,13 @@
         }
     }
 
+    /** @return true if the bucket label was specified as a long integer. */
     public boolean isLongCounterBucket() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
         return obj instanceof Long;
     }
 
+    /** @return the increment value of the counter, or 0. */
     public int getCounterValue() {
         Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_VALUE);
         if (obj instanceof Integer) {
@@ -249,7 +331,7 @@
     }
 
     /**
-     * Assemble logs into structure suitable for EventLog.
+     * @return a representation of the log suitable for EventLog.
      */
     public Object[] serialize() {
         Object[] out = new Object[entries.size() * 2];
diff --git a/core/java/android/metrics/MetricsReader.java b/core/java/android/metrics/MetricsReader.java
index dd8a74d..181e87f 100644
--- a/core/java/android/metrics/MetricsReader.java
+++ b/core/java/android/metrics/MetricsReader.java
@@ -77,7 +77,8 @@
                     objects[0] = data;
                 }
                 mEventQueue.add(new LogMaker(objects)
-                        .setTimestamp(eventTimestampMs));
+                        .setTimestamp(eventTimestampMs)
+                        .setProcessId(event.getProcessId()));
                 mLastEventMs = eventTimestampMs;
             }
         }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f94e89a..7a39d23 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -601,6 +601,11 @@
         nativeWriteString(mNativePtr, val);
     }
 
+    /** @hide */
+    public final void writeBoolean(boolean val) {
+        writeInt(val ? 1 : 0);
+    }
+
     /**
      * Write a CharSequence value into the parcel at the current dataPosition(),
      * growing dataCapacity() if needed.
@@ -1964,6 +1969,11 @@
         return nativeReadString(mNativePtr);
     }
 
+    /** @hide */
+    public final boolean readBoolean() {
+        return readInt() != 0;
+    }
+
     /**
      * Read a CharSequence value from the parcel at the current dataPosition().
      * @hide
@@ -2490,11 +2500,11 @@
      * @see #writeParcelableList(List, int)
      * @hide
      */
-    public final <T extends Parcelable> void readParcelableList(List<T> list, ClassLoader cl) {
+    public final <T extends Parcelable> List<T> readParcelableList(List<T> list, ClassLoader cl) {
         final int N = readInt();
         if (N == -1) {
             list.clear();
-            return;
+            return list;
         }
 
         final int M = list.size();
@@ -2508,6 +2518,7 @@
         for (; i<M; i++) {
             list.remove(N);
         }
+        return list;
     }
 
     /**
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 33b5903..173603d 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -1367,24 +1367,25 @@
     }
 
     /**
-     * Finds the canonical path to the top of the tree. The return value starts
-     * from the top of the tree or the root document to the requested document,
-     * both inclusive.
+     * Finds the canonical path from the top of the document tree.
      *
-     * Document ID should be unique across roots.
+     * The {@link Path#getPath()} of the return value contains the document ID
+     * of all documents along the path from the top the document tree to the
+     * requested document, both inclusive.
+     *
+     * The {@link Path#getRootId()} of the return value returns {@code null}.
      *
      * @param treeUri treeUri of the document which path is requested.
-     * @return a list of documents ID starting from the top of the tree to the
-     *      requested document, or {@code null} if failed.
+     * @return the path of the document, or {@code null} if failed.
      * @see DocumentsProvider#findDocumentPath(String, String)
      */
-    public static List<String> findDocumentPath(ContentResolver resolver, Uri treeUri) {
+    public static Path findDocumentPath(ContentResolver resolver, Uri treeUri) {
         checkArgument(isTreeUri(treeUri), treeUri + " is not a tree uri.");
 
         final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                 treeUri.getAuthority());
         try {
-            return findDocumentPath(client, treeUri).getPath();
+            return findDocumentPath(client, treeUri);
         } catch (Exception e) {
             Log.w(TAG, "Failed to find path", e);
             return null;
@@ -1394,12 +1395,14 @@
     }
 
     /**
-     * Finds the canonical path. If uri is a document uri returns path to a root and
-     * its associated root id. If uri is a tree uri returns the path to the top of
-     * the tree. The {@link Path#getPath()} in the return value starts from the top of
-     * the tree or the root document to the requested document, both inclusive.
+     * Finds the canonical path. If uri is a document uri returns path from a root and
+     * its associated root id. If uri is a tree uri returns the path from the top of
+     * the tree. The {@link Path#getPath()} of the return value contains document ID
+     * starts from the top of the tree or the root document to the requested document,
+     * both inclusive.
      *
-     * Document id should be unique across roots.
+     * Callers can expect the root ID returned from multiple calls to this method is
+     * consistent.
      *
      * @param uri uri of the document which path is requested. It can be either a
      *          plain document uri or a tree uri.
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index f5e558a..89a80f0 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -65,6 +65,7 @@
 import libcore.io.IoUtils;
 
 import java.io.FileNotFoundException;
+import java.util.LinkedList;
 import java.util.Objects;
 
 /**
@@ -352,14 +353,14 @@
      * Different roots should use different document ID to refer to the same
      * document.
      *
-     * @param childDocumentId the document which path is requested.
      * @param parentDocumentId the document from which the path starts if not null,
      *     or null to indicate a path from the root is requested.
+     * @param childDocumentId the document which path is requested.
      * @return the path of the requested document. If parentDocumentId is null
      *     returned root ID must not be null. If parentDocumentId is not null
      *     returned root ID must be null.
      */
-    public Path findDocumentPath(String childDocumentId, @Nullable String parentDocumentId)
+    public Path findDocumentPath(@Nullable String parentDocumentId, String childDocumentId)
             throws FileNotFoundException {
         throw new UnsupportedOperationException("findDocumentPath not supported.");
     }
@@ -1048,13 +1049,19 @@
                     ? DocumentsContract.getTreeDocumentId(documentUri)
                     : null;
 
-            Path path = findDocumentPath(documentId, parentDocumentId);
+            Path path = findDocumentPath(parentDocumentId, documentId);
 
             // Ensure provider doesn't leak information to unprivileged callers.
             if (isTreeUri) {
                 if (!Objects.equals(path.getPath().get(0), parentDocumentId)) {
                     Log.wtf(TAG, "Provider doesn't return path from the tree root. Expected: "
                             + parentDocumentId + " found: " + path.getPath().get(0));
+
+                    LinkedList<String> docs = new LinkedList<>(path.getPath());
+                    while (docs.size() > 1 && !Objects.equals(docs.getFirst(), parentDocumentId)) {
+                        docs.removeFirst();
+                    }
+                    path = new Path(null, docs);
                 }
 
                 if (path.getRootId() != null) {
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 96dd76b..9f5d9d4 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -40,6 +40,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -78,6 +79,37 @@
          * {@link android.graphics.Typeface#BOLD_ITALIC}
          */
         public static final String STYLE = "font_style";
+        /**
+         * Constant used to request data from a font provider. The cursor returned from the query
+         * should have this column populated to indicate the result status of the
+         * query. This will be checked before any other data in the cursor. Possible values are
+         * {@link #RESULT_CODE_OK}, {@link #RESULT_CODE_FONT_NOT_FOUND},
+         * {@link #RESULT_CODE_MALFORMED_QUERY} and {@link #RESULT_CODE_FONT_UNAVAILABLE}. If not
+         * present, {@link #RESULT_CODE_OK} will be assumed.
+         */
+        public static final String RESULT_CODE = "result_code";
+
+        /**
+         * Constant used to represent a result was retrieved successfully. The given fonts will be
+         * attempted to retrieve immediately via
+         * {@link android.content.ContentProvider#openFile(Uri, String)}. See {@link #RESULT_CODE}.
+         */
+        public static final int RESULT_CODE_OK = 0;
+        /**
+         * Constant used to represent a result was not found. See {@link #RESULT_CODE}.
+         */
+        public static final int RESULT_CODE_FONT_NOT_FOUND = 1;
+        /**
+         * Constant used to represent a result was found, but cannot be provided at this moment. Use
+         * this to indicate, for example, that a font needs to be fetched from the network. See
+         * {@link #RESULT_CODE}.
+         */
+        public static final int RESULT_CODE_FONT_UNAVAILABLE = 2;
+        /**
+         * Constant used to represent that the query was not in a supported format by the provider.
+         * See {@link #RESULT_CODE}.
+         */
+        public static final int RESULT_CODE_MALFORMED_QUERY = 3;
     }
 
     /**
@@ -87,12 +119,13 @@
      */
     public static final String PARCEL_FONT_RESULTS = "font_results";
 
+    // Error codes internal to the system, which can not come from a provider. To keep the number
+    // space open for new provider codes, these should all be negative numbers.
     /** @hide */
-    public static final int RESULT_CODE_OK = 0;
+    public static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1;
     /** @hide */
-    public static final int RESULT_CODE_FONT_NOT_FOUND = 1;
-    /** @hide */
-    public static final int RESULT_CODE_PROVIDER_NOT_FOUND = 2;
+    public static final int RESULT_CODE_WRONG_CERTIFICATES = -2;
+    // Note -3 is used by Typeface to indicate the font failed to load.
 
     private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000;
 
@@ -136,9 +169,7 @@
         }
     };
 
-    /**
-     * @hide
-     */
+    /** @hide */
     public void getFont(FontRequest request, ResultReceiver receiver) {
         synchronized (mLock) {
             if (mHandler == null) {
@@ -147,9 +178,8 @@
                 mHandler = new Handler(mThread.getLooper());
             }
             mHandler.post(() -> {
-                ProviderInfo providerInfo = getProvider(request);
+                ProviderInfo providerInfo = getProvider(request, receiver);
                 if (providerInfo == null) {
-                    receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
                     return;
                 }
                 getFontFromProvider(request, receiver, providerInfo.authority);
@@ -161,17 +191,19 @@
 
     /** @hide */
     @VisibleForTesting
-    public ProviderInfo getProvider(FontRequest request) {
+    public ProviderInfo getProvider(FontRequest request, ResultReceiver receiver) {
         String providerAuthority = request.getProviderAuthority();
         ProviderInfo info = mPackageManager.resolveContentProvider(providerAuthority, 0);
         if (info == null) {
             Log.e(TAG, "Can't find content provider " + providerAuthority);
+            receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
             return null;
         }
 
         if (!info.packageName.equals(request.getProviderPackage())) {
             Log.e(TAG, "Found content provider " + providerAuthority + ", but package was not "
                     + request.getProviderPackage());
+            receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
             return null;
         }
         // Trust system apps without signature checks
@@ -186,6 +218,7 @@
             signatures = convertToSet(packageInfo.signatures);
         } catch (PackageManager.NameNotFoundException e) {
             Log.e(TAG, "Can't find content provider " + providerAuthority, e);
+            receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
             return null;
         }
         List<List<byte[]>> requestCertificatesList = request.getCertificates();
@@ -196,6 +229,7 @@
             }
         }
         Log.e(TAG, "Certificates don't match for given provider " + providerAuthority);
+        receiver.send(RESULT_CODE_WRONG_CERTIFICATES, null);
         return null;
     }
 
@@ -222,17 +256,37 @@
                 .authority(authority)
                 .build();
         try (Cursor cursor = mContext.getContentResolver().query(uri, new String[] { Columns._ID,
-                        Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.STYLE },
+                        Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.STYLE,
+                        Columns.RESULT_CODE },
                 "query = ?", new String[] { request.getQuery() }, null);) {
             // TODO: Should we restrict the amount of fonts that can be returned?
             // TODO: Write documentation explaining that all results should be from the same family.
             if (cursor != null && cursor.getCount() > 0) {
+                final int resultCodeColumnIndex = cursor.getColumnIndex(Columns.RESULT_CODE);
+                int resultCode = -1;
                 result = new ArrayList<>();
-                final int idColumnIndex = cursor.getColumnIndex(Columns._ID);
+                final int idColumnIndex = cursor.getColumnIndexOrThrow(Columns._ID);
                 final int ttcIndexColumnIndex = cursor.getColumnIndex(Columns.TTC_INDEX);
                 final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS);
                 final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE);
                 while (cursor.moveToNext()) {
+                    resultCode = resultCodeColumnIndex != -1
+                            ? cursor.getInt(resultCodeColumnIndex) : Columns.RESULT_CODE_OK;
+                    if (resultCode != Columns.RESULT_CODE_OK) {
+                        if (resultCode < 0) {
+                            // Negative values are reserved for the internal errors.
+                            resultCode = Columns.RESULT_CODE_FONT_NOT_FOUND;
+                        }
+                        for (int i = 0; i < result.size(); ++i) {
+                            try {
+                                result.get(i).getFileDescriptor().close();
+                            } catch (IOException e) {
+                                // Ignore, as we are closing fds for cleanup.
+                            }
+                        }
+                        receiver.send(resultCode, null);
+                        return;
+                    }
                     long id = cursor.getLong(idColumnIndex);
                     Uri fileUri = ContentUris.withAppendedId(uri, id);
                     try {
@@ -255,9 +309,9 @@
         if (result != null && !result.isEmpty()) {
             Bundle bundle = new Bundle();
             bundle.putParcelableArrayList(PARCEL_FONT_RESULTS, result);
-            receiver.send(RESULT_CODE_OK, bundle);
+            receiver.send(Columns.RESULT_CODE_OK, bundle);
             return;
         }
-        receiver.send(RESULT_CODE_FONT_NOT_FOUND, null);
+        receiver.send(Columns.RESULT_CODE_FONT_NOT_FOUND, null);
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e3a9d80..52aa1d5 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5128,11 +5128,11 @@
         public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
 
         /**
-         * The currently selected auto-fill service flattened ComponentName.
+         * The currently selected autofill service flattened ComponentName.
          * @hide
          */
         @TestApi
-        public static final String AUTO_FILL_SERVICE = "auto_fill_service";
+        public static final String AUTOFILL_SERVICE = "autofill_service";
 
         /**
          * bluetooth HCI snoop log configuration
@@ -6743,6 +6743,13 @@
         public static final String ASSIST_GESTURE_ENABLED = "assist_gesture_enabled";
 
         /**
+         * Sensitivity control for the assist gesture.
+         *
+         * @hide
+         */
+        public static final String ASSIST_GESTURE_SENSITIVITY = "assist_gesture_sensitivity";
+
+        /**
          * Control whether Night display is currently activated.
          * @hide
          */
@@ -7001,6 +7008,7 @@
             NFC_PAYMENT_DEFAULT_COMPONENT,
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             ASSIST_GESTURE_ENABLED,
+            ASSIST_GESTURE_SENSITIVITY,
             VR_DISPLAY_MODE
         };
 
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index 3c211eb..c26f679 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -15,236 +15,10 @@
  */
 package android.service.autofill;
 
-import android.accessibilityservice.IAccessibilityServiceConnection;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Message;
-import android.os.RemoteException;
-import android.view.accessibility.AccessibilityInteractionClient;
-import com.android.internal.os.HandlerCaller;
-import android.annotation.SdkConstant;
-import android.app.Activity;
-import android.app.Service;
-import android.app.assist.AssistStructure;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.Looper;
-import android.util.Log;
-
-import com.android.internal.os.SomeArgs;
-
-//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
-//life-cycle (and how state could be maintained on server-side) is well documented.
-
 /**
- * Top-level service of the current auto-fill service for a given user.
- *
- * <p>Apps providing auto-fill capabilities must extend this service.
+ * @hide
+ * @deprecated TODO(b/35956626): remove once clients use AutofillService
  */
-public abstract class AutoFillService extends Service {
-    private static final String TAG = "AutoFillService";
-
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * To be supported, the service must also require the
-     * {@link android.Manifest.permission#BIND_AUTO_FILL} permission so
-     * that other applications can not abuse it.
-     */
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
-
-    /**
-     * Name under which a AutoFillService component publishes information about itself.
-     * This meta-data should reference an XML resource containing a
-     * <code>&lt;{@link
-     * android.R.styleable#AutoFillService autofill-service}&gt;</code> tag.
-     * This is a a sample XML file configuring an AutoFillService:
-     * <pre> &lt;autofill-service
-     *     android:settingsActivity="foo.bar.SettingsActivity"
-     *     . . .
-     * /&gt;</pre>
-     */
-    public static final String SERVICE_META_DATA = "android.autofill";
-
-    // Internal extras
-    /** @hide */
-    public static final String EXTRA_ACTIVITY_TOKEN =
-            "android.service.autofill.extra.ACTIVITY_TOKEN";
-
-    // Handler messages.
-    private static final int MSG_CONNECT = 1;
-    private static final int MSG_DISCONNECT = 2;
-    private static final int MSG_ON_FILL_REQUEST = 3;
-    private static final int MSG_ON_SAVE_REQUEST = 4;
-
-    private final IAutoFillService mInterface = new IAutoFillService.Stub() {
-        @Override
-        public void onInit(IAutoFillServiceConnection connection) {
-            if (connection != null) {
-                mHandlerCaller.obtainMessageO(MSG_CONNECT, connection).sendToTarget();
-            } else {
-                mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget();
-            }
-        }
-
-        @Override
-        public void onFillRequest(AssistStructure structure, Bundle extras,
-                IFillCallback callback) {
-            ICancellationSignal transport = CancellationSignal.createTransport();
-            try {
-                callback.onCancellable(transport);
-            } catch (RemoteException e) {
-                e.rethrowFromSystemServer();
-            }
-            mHandlerCaller.obtainMessageOOOO(MSG_ON_FILL_REQUEST, structure,
-                    CancellationSignal.fromTransport(transport), extras, callback)
-                    .sendToTarget();
-        }
-
-        @Override
-        public void onSaveRequest(AssistStructure structure, Bundle extras,
-                ISaveCallback callback) {
-            mHandlerCaller.obtainMessageOOO(MSG_ON_SAVE_REQUEST, structure,
-                    extras, callback).sendToTarget();
-        }
-    };
-
-    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
-        switch (msg.what) {
-            case MSG_CONNECT: {
-                mConnection = (IAutoFillServiceConnection) msg.obj;
-                onConnected();
-                break;
-            } case MSG_ON_FILL_REQUEST: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final AssistStructure structure = (AssistStructure) args.arg1;
-                final CancellationSignal cancellation = (CancellationSignal) args.arg2;
-                final Bundle extras = (Bundle) args.arg3;
-                final IFillCallback callback = (IFillCallback) args.arg4;
-                final FillCallback fillCallback = new FillCallback(callback);
-                args.recycle();
-                onFillRequest(structure, extras, cancellation, fillCallback);
-                break;
-            } case MSG_ON_SAVE_REQUEST: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final AssistStructure structure = (AssistStructure) args.arg1;
-                final Bundle extras = (Bundle) args.arg2;
-                final ISaveCallback callback = (ISaveCallback) args.arg3;
-                final SaveCallback saveCallback = new SaveCallback(callback);
-                args.recycle();
-                onSaveRequest(structure, extras, saveCallback);
-                break;
-            } case MSG_DISCONNECT: {
-                onDisconnected();
-                mConnection = null;
-                break;
-            } default: {
-                Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
-            }
-        }
-    };
-
-    private HandlerCaller mHandlerCaller;
-
-    private IAutoFillServiceConnection mConnection;
-
-    /**
-     * {@inheritDoc}
-     *
-     * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}.
-     */
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
-    }
-
-    @Override
-    public final IBinder onBind(Intent intent) {
-        if (SERVICE_INTERFACE.equals(intent.getAction())) {
-            return mInterface.asBinder();
-        }
-        Log.w(TAG, "Tried to bind to wrong intent: " + intent);
-        return null;
-    }
-
-    /**
-     * Called when the Android system connects to service.
-     *
-     * <p>You should generally do initialization here rather than in {@link #onCreate}.
-     */
-    public void onConnected() {
-        //TODO(b/33197203): is not called anymore, fix it!
-    }
-
-    /**
-     * Called by the Android system do decide if an {@link Activity} can be auto-filled by the
-     * service.
-     *
-     * <p>Service must call one of the {@link FillCallback} methods (like
-     * {@link FillCallback#onSuccess(FillResponse)}
-     * or {@link FillCallback#onFailure(CharSequence)})
-     * to notify the result of the request.
-     *
-     * @param structure {@link Activity}'s view structure.
-     * @param data bundle containing data passed by the service on previous calls to fill.
-     *     This bundle allows your service to keep state between fill and save requests
-     *     as well as when filling different sections of the UI as the system will try to
-     *     aggressively unbind from the service to conserve resources. See {@link
-     *     FillResponse} Javadoc for examples of multiple-sections requests.
-     * @param cancellationSignal signal for observing cancellation requests. The system will use
-     *     this to notify you that the fill result is no longer needed and you should stop
-     *     handling this fill request in order to save resources.
-     * @param callback object used to notify the result of the request.
-     */
-    public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
-            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
-
-    /**
-     * Called when user requests service to save the fields of an {@link Activity}.
-     *
-     * <p>Service must call one of the {@link SaveCallback} methods (like
-     * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
-     * to notify the result of the request.
-     *
-     * @param structure {@link Activity}'s view structure.
-     * @param data bundle containing data passed by the service on previous calls to fill.
-     *     This bundle allows your service to keep state between fill and save requests
-     *     as well as when filling different sections of the UI as the system will try to
-     *     aggressively unbind from the service to conserve resources. See {@link
-     *     FillResponse} Javadoc for examples of multiple-sections requests.
-     * @param callback object used to notify the result of the request.
-     */
-    public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
-            @NonNull SaveCallback callback);
-
-    /**
-     * Called when the Android system disconnects from the service.
-     *
-     * <p> At this point this service may no longer be an active {@link AutoFillService}.
-     */
-    public void onDisconnected() {
-        //TODO(b/33197203): is not called anymore, fix it!
-    }
-
-    /**
-     * Disables the service. After calling this method, the service will
-     * be disabled and settings will show that it is turned off.
-     *
-     * <p>You should call this method only after a call to {@link #onConnected()}
-     * and before the corresponding call to {@link #onDisconnected()}. In other words
-     * you can disable your service only while the system is connected to it.</p>
-     */
-    public final void disableSelf() {
-        if (mConnection != null) {
-            try {
-                mConnection.disableSelf();
-            } catch (RemoteException re) {
-                throw re.rethrowFromSystemServer();
-            }
-        }
-    }
+@Deprecated
+public abstract class AutoFillService extends AutofillService {
 }
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
new file mode 100644
index 0000000..29e2073
--- /dev/null
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -0,0 +1,261 @@
+/*
+ * 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.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import com.android.internal.os.HandlerCaller;
+import android.annotation.SdkConstant;
+import android.app.Activity;
+import android.app.Service;
+import android.app.assist.AssistStructure;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.util.Log;
+
+import com.android.internal.os.SomeArgs;
+
+//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
+//life-cycle (and how state could be maintained on server-side) is well documented.
+
+/**
+ * Top-level service of the current autofill service for a given user.
+ *
+ * <p>Apps providing autofill capabilities must extend this service.
+ */
+public abstract class AutofillService extends Service {
+    private static final String TAG = "AutofillService";
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     * To be supported, the service must also require the
+     * {@link android.Manifest.permission#BIND_AUTO_FILL} permission so
+     * that other applications can not abuse it.
+     *
+     * @hide
+     * @deprecated TODO(b/35956626): remove once clients use AutofillService
+     */
+    @Deprecated
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String OLD_SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     * To be supported, the service must also require the
+     * {@link android.Manifest.permission#BIND_AUTOFILL} permission so
+     * that other applications can not abuse it.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
+
+    /**
+     * Name under which a AutoFillService component publishes information about itself.
+     * This meta-data should reference an XML resource containing a
+     * <code>&lt;{@link
+     * android.R.styleable#AutoFillService autofill-service}&gt;</code> tag.
+     * This is a a sample XML file configuring an AutoFillService:
+     * <pre> &lt;autofill-service
+     *     android:settingsActivity="foo.bar.SettingsActivity"
+     *     . . .
+     * /&gt;</pre>
+     */
+    public static final String SERVICE_META_DATA = "android.autofill";
+
+    // Internal extras
+    /** @hide */
+    public static final String EXTRA_ACTIVITY_TOKEN =
+            "android.service.autofill.extra.ACTIVITY_TOKEN";
+
+    // Handler messages.
+    private static final int MSG_CONNECT = 1;
+    private static final int MSG_DISCONNECT = 2;
+    private static final int MSG_ON_FILL_REQUEST = 3;
+    private static final int MSG_ON_SAVE_REQUEST = 4;
+
+    private final IAutoFillService mInterface = new IAutoFillService.Stub() {
+        @Override
+        public void onInit(IAutoFillServiceConnection connection) {
+            if (connection != null) {
+                mHandlerCaller.obtainMessageO(MSG_CONNECT, connection).sendToTarget();
+            } else {
+                mHandlerCaller.obtainMessage(MSG_DISCONNECT).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onFillRequest(AssistStructure structure, Bundle extras,
+                IFillCallback callback) {
+            ICancellationSignal transport = CancellationSignal.createTransport();
+            try {
+                callback.onCancellable(transport);
+            } catch (RemoteException e) {
+                e.rethrowFromSystemServer();
+            }
+            mHandlerCaller.obtainMessageOOOO(MSG_ON_FILL_REQUEST, structure,
+                    CancellationSignal.fromTransport(transport), extras, callback)
+                    .sendToTarget();
+        }
+
+        @Override
+        public void onSaveRequest(AssistStructure structure, Bundle extras,
+                ISaveCallback callback) {
+            mHandlerCaller.obtainMessageOOO(MSG_ON_SAVE_REQUEST, structure,
+                    extras, callback).sendToTarget();
+        }
+    };
+
+    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+        switch (msg.what) {
+            case MSG_CONNECT: {
+                mConnection = (IAutoFillServiceConnection) msg.obj;
+                onConnected();
+                break;
+            } case MSG_ON_FILL_REQUEST: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final AssistStructure structure = (AssistStructure) args.arg1;
+                final CancellationSignal cancellation = (CancellationSignal) args.arg2;
+                final Bundle extras = (Bundle) args.arg3;
+                final IFillCallback callback = (IFillCallback) args.arg4;
+                final FillCallback fillCallback = new FillCallback(callback);
+                args.recycle();
+                onFillRequest(structure, extras, cancellation, fillCallback);
+                break;
+            } case MSG_ON_SAVE_REQUEST: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final AssistStructure structure = (AssistStructure) args.arg1;
+                final Bundle extras = (Bundle) args.arg2;
+                final ISaveCallback callback = (ISaveCallback) args.arg3;
+                final SaveCallback saveCallback = new SaveCallback(callback);
+                args.recycle();
+                onSaveRequest(structure, extras, saveCallback);
+                break;
+            } case MSG_DISCONNECT: {
+                onDisconnected();
+                mConnection = null;
+                break;
+            } default: {
+                Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
+            }
+        }
+    };
+
+    private HandlerCaller mHandlerCaller;
+
+    private IAutoFillServiceConnection mConnection;
+
+    /**
+     * {@inheritDoc}
+     *
+     * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}.
+     */
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())
+                || OLD_SERVICE_INTERFACE.equals(intent.getAction())) {
+            return mInterface.asBinder();
+        }
+        Log.w(TAG, "Tried to bind to wrong intent: " + intent);
+        return null;
+    }
+
+    /**
+     * Called when the Android system connects to service.
+     *
+     * <p>You should generally do initialization here rather than in {@link #onCreate}.
+     */
+    public void onConnected() {
+        //TODO(b/33197203): is not called anymore, fix it!
+    }
+
+    /**
+     * Called by the Android system do decide if an {@link Activity} can be autofilled by the
+     * service.
+     *
+     * <p>Service must call one of the {@link FillCallback} methods (like
+     * {@link FillCallback#onSuccess(FillResponse)}
+     * or {@link FillCallback#onFailure(CharSequence)})
+     * to notify the result of the request.
+     *
+     * @param structure {@link Activity}'s view structure.
+     * @param data bundle containing data passed by the service on previous calls to fill.
+     *     This bundle allows your service to keep state between fill and save requests
+     *     as well as when filling different sections of the UI as the system will try to
+     *     aggressively unbind from the service to conserve resources. See {@link
+     *     FillResponse} Javadoc for examples of multiple-sections requests.
+     * @param cancellationSignal signal for observing cancellation requests. The system will use
+     *     this to notify you that the fill result is no longer needed and you should stop
+     *     handling this fill request in order to save resources.
+     * @param callback object used to notify the result of the request.
+     */
+    public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
+
+    /**
+     * Called when user requests service to save the fields of an {@link Activity}.
+     *
+     * <p>Service must call one of the {@link SaveCallback} methods (like
+     * {@link SaveCallback#onSuccess()} or {@link SaveCallback#onFailure(CharSequence)})
+     * to notify the result of the request.
+     *
+     * @param structure {@link Activity}'s view structure.
+     * @param data bundle containing data passed by the service on previous calls to fill.
+     *     This bundle allows your service to keep state between fill and save requests
+     *     as well as when filling different sections of the UI as the system will try to
+     *     aggressively unbind from the service to conserve resources. See {@link
+     *     FillResponse} Javadoc for examples of multiple-sections requests.
+     * @param callback object used to notify the result of the request.
+     */
+    public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+            @NonNull SaveCallback callback);
+
+    /**
+     * Called when the Android system disconnects from the service.
+     *
+     * <p> At this point this service may no longer be an active {@link AutofillService}.
+     */
+    public void onDisconnected() {
+        //TODO(b/33197203): is not called anymore, fix it!
+    }
+
+    /**
+     * Disables the service. After calling this method, the service will
+     * be disabled and settings will show that it is turned off.
+     *
+     * <p>You should call this method only after a call to {@link #onConnected()}
+     * and before the corresponding call to {@link #onDisconnected()}. In other words
+     * you can disable your service only while the system is connected to it.</p>
+     */
+    public final void disableSelf() {
+        if (mConnection != null) {
+            try {
+                mConnection.disableSelf();
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+    }
+}
diff --git a/core/java/android/service/autofill/AutoFillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
similarity index 73%
rename from core/java/android/service/autofill/AutoFillServiceInfo.java
rename to core/java/android/service/autofill/AutofillServiceInfo.java
index 985e32f..d220052 100644
--- a/core/java/android/service/autofill/AutoFillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -38,12 +38,12 @@
 
 // TODO(b/33197203 , b/33802548): add CTS tests
 /**
- * {@link ServiceInfo} and meta-data about an {@link AutoFillService}.
+ * {@link ServiceInfo} and meta-data about an {@link AutofillService}.
  *
  * @hide
  */
-public final class AutoFillServiceInfo {
-    private static final String TAG = "AutoFillServiceInfo";
+public final class AutofillServiceInfo {
+    private static final String TAG = "AutofillServiceInfo";
 
     private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
             throws PackageManager.NameNotFoundException {
@@ -66,17 +66,26 @@
     @Nullable
     private final String mSettingsActivity;
 
-    public AutoFillServiceInfo(PackageManager pm, ComponentName comp, int userHandle)
+    public AutofillServiceInfo(PackageManager pm, ComponentName comp, int userHandle)
             throws PackageManager.NameNotFoundException {
         this(pm, getServiceInfoOrThrow(comp, userHandle));
     }
 
-    public AutoFillServiceInfo(PackageManager pm, ServiceInfo si) {
+    public AutofillServiceInfo(PackageManager pm, ServiceInfo si) {
         mServiceInfo = si;
         final TypedArray metaDataArray = getMetaDataArray(pm, si);
         if (metaDataArray != null) {
-            mSettingsActivity =
-                    metaDataArray.getString(R.styleable.AutoFillService_settingsActivity);
+            // TODO(b/35956626): inline newSettingsActivity once clients migrate
+            final String newSettingsActivity =
+                    metaDataArray.getString(R.styleable.AutofillService_settingsActivity);
+            System.out.println(">>> NEW CRAP MAN: " + newSettingsActivity); // TODO(felipeal): tmp
+            if (newSettingsActivity != null) {
+                mSettingsActivity = newSettingsActivity;
+            } else {
+                mSettingsActivity =
+                        metaDataArray.getString(R.styleable.AutoFillService_settingsActivity);
+            }
+            System.out.println(">>> FINAL CRAP MAN: " + mSettingsActivity); // TODO(felipeal): tmp
             metaDataArray.recycle();
         } else {
             mSettingsActivity = null;
@@ -89,13 +98,18 @@
     @Nullable
     private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si) {
         // Check for permissions.
-        if (!Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) {
-            Log.e(TAG, "Service does not require permission " + Manifest.permission.BIND_AUTO_FILL);
+        // TODO(b/35956626): remove check for BIND_AUTO_FILL once clients migrate
+        if (!Manifest.permission.BIND_AUTOFILL.equals(si.permission)
+                && !Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) {
+            Log.e(TAG, "Service does not require permission " + Manifest.permission.BIND_AUTOFILL);
             return null;
         }
 
+        // TODO(b/35956626): remove once clients migrate
+        final boolean oldStyle = !Manifest.permission.BIND_AUTOFILL.equals(si.permission);
+
         // Get the AutoFill metadata, if declared.
-        XmlResourceParser parser = si.loadXmlMetaData(pm, AutoFillService.SERVICE_META_DATA);
+        XmlResourceParser parser = si.loadXmlMetaData(pm, AutofillService.SERVICE_META_DATA);
         if (parser == null) {
             return null;
         }
@@ -129,7 +143,8 @@
                 return null;
             }
 
-            return res.obtainAttributes(attrs, R.styleable.AutoFillService);
+            return oldStyle ? res.obtainAttributes(attrs, R.styleable.AutoFillService)
+                    : res.obtainAttributes(attrs, R.styleable.AutofillService);
         } finally {
             parser.close();
         }
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index d76d444..2461947 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -25,13 +25,15 @@
 import android.os.Parcelable;
 import android.view.autofill.AutoFillId;
 import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.widget.RemoteViews;
 import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 
 /**
- * A set of data that can be used to auto-fill an {@link android.app.Activity}.
+ * A set of data that can be used to autofill an {@link android.app.Activity}.
  *
  * <p>It contains:
  *
@@ -45,8 +47,8 @@
  */
 public final class Dataset implements Parcelable {
 
-    private final ArrayList<AutoFillId> mFieldIds;
-    private final ArrayList<AutoFillValue> mFieldValues;
+    private final ArrayList<AutofillId> mFieldIds;
+    private final ArrayList<AutofillValue> mFieldValues;
     private final RemoteViews mPresentation;
     private final IntentSender mAuthentication;
 
@@ -58,12 +60,12 @@
     }
 
     /** @hide */
-    public @Nullable ArrayList<AutoFillId> getFieldIds() {
+    public @Nullable ArrayList<AutofillId> getFieldIds() {
         return mFieldIds;
     }
 
     /** @hide */
-    public @Nullable ArrayList<AutoFillValue> getFieldValues() {
+    public @Nullable ArrayList<AutofillValue> getFieldValues() {
         return mFieldValues;
     }
 
@@ -99,8 +101,8 @@
      * one value for a field or set an authentication intent.
      */
     public static final class Builder {
-        private ArrayList<AutoFillId> mFieldIds;
-        private ArrayList<AutoFillValue> mFieldValues;
+        private ArrayList<AutofillId> mFieldIds;
+        private ArrayList<AutofillValue> mFieldValues;
         private RemoteViews mPresentation;
         private IntentSender mAuthentication;
         private boolean mDestroyed;
@@ -116,7 +118,7 @@
         }
 
         /**
-         * Requires a dataset authentication before auto-filling the activity with this dataset.
+         * Requires a dataset authentication before autofilling the activity with this dataset.
          *
          * <p>This method is called when you need to provide an authentication
          * UI for the data set. For example, when a data set contains credit card information
@@ -131,13 +133,13 @@
          * the items with these labels is chosen. Note that if you use sensitive data as
          * a label, for example an email address, then it should also be encrypted.</p>
          *
-         * <p>When a user triggers auto-fill, the system launches the provided intent
+         * <p>When a user triggers autofill, the system launches the provided intent
          * whose extras will have the {@link
-         * android.view.autofill.AutoFillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once
+         * android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once
          * you complete your authentication flow you should set the activity result to {@link
          * android.app.Activity#RESULT_OK} and provide the fully populated {@link Dataset
          * dataset} by setting it to the {@link
-         * android.view.autofill.AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example,
+         * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example,
          * if you provided credit card information without the CVV for the data set in the
          * {@link FillResponse response} then the returned data set should contain the
          * CVV entry.</p>
@@ -158,14 +160,22 @@
         }
 
         /**
+         * @hide
+         * @deprecated TODO(b/35956626): remove once clients use other setValue()
+         */
+       @Deprecated
+        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
+            return setValue(id.getDaRealId(), value.getDaRealValue());
+        }
+        /**
          * Sets the value of a field.
          *
          * @param id id returned by {@link
-         *         android.app.assist.AssistStructure.ViewNode#getAutoFillId()}.
+         *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
          * @param value value to be auto filled.
          * @return This builder.
          */
-        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
+        public @NonNull Builder setValue(@NonNull AutofillId id, @NonNull AutofillValue value) {
             throwIfDestroyed();
             Preconditions.checkNotNull(id, "id cannot be null");
             Preconditions.checkNotNull(value, "value cannot be null");
@@ -233,13 +243,13 @@
             // the system obeys the contract of the builder to avoid attacks
             // using specially crafted parcels.
             final Builder builder = new Builder(parcel.readParcelable(null));
-            final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
-            final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
+            final ArrayList<AutofillId> ids = parcel.readTypedArrayList(null);
+            final ArrayList<AutofillValue> values = parcel.readTypedArrayList(null);
             final int idCount = (ids != null) ? ids.size() : 0;
             final int valueCount = (values != null) ? values.size() : 0;
             for (int i = 0; i < idCount; i++) {
-                AutoFillId id = ids.get(i);
-                AutoFillValue value = (valueCount > i) ? values.get(i) : null;
+                final AutofillId id = ids.get(i);
+                final AutofillValue value = (valueCount > i) ? values.get(i) : null;
                 builder.setValue(id, value);
             }
             builder.setAuthentication(parcel.readParcelable(null));
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 69c9904..00b206c 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -22,8 +22,8 @@
 import android.os.RemoteException;
 
 /**
- * Handles auto-fill requests from the {@link AutoFillService} into the {@link Activity} being
- * auto-filled.
+ * Handles autofill requests from the {@link AutofillService} into the {@link Activity} being
+ * autofilled.
  */
 public final class FillCallback {
     private final IFillCallback mCallback;
@@ -36,11 +36,11 @@
 
     /**
      * Notifies the Android System that an
-     * {@link AutoFillService#onFillRequest(android.app.assist.AssistStructure, Bundle,
+     * {@link AutofillService#onFillRequest(android.app.assist.AssistStructure, Bundle,
      * android.os.CancellationSignal, FillCallback)} was successfully fulfilled by the service.
      *
-     * @param response auto-fill information for that activity, or {@code null} when the activity
-     * cannot be auto-filled (for example, if it only contains read-only fields). See
+     * @param response autofill information for that activity, or {@code null} when the activity
+     * cannot be autofilled (for example, if it only contains read-only fields). See
      * {@link FillResponse} for examples.
      */
     public void onSuccess(@Nullable FillResponse response) {
@@ -55,7 +55,7 @@
 
     /**
      * Notifies the Android System that an
-     * {@link AutoFillService#onFillRequest(android.app.assist.AssistStructure,
+     * {@link AutofillService#onFillRequest(android.app.assist.AssistStructure,
      * Bundle, android.os.CancellationSignal, FillCallback)}
      * could not be fulfilled by the service.
      *
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index c457c56..069e83c 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -23,19 +23,18 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutofillManager;
 import android.widget.RemoteViews;
 
 import java.util.ArrayList;
 
 /**
  * Response for a {@link
- * AutoFillService#onFillRequest(android.app.assist.AssistStructure,
+ * AutofillService#onFillRequest(android.app.assist.AssistStructure,
  * Bundle, android.os.CancellationSignal, FillCallback)}.
  *
  * <p>The response typically contains one or more {@link Dataset}s, each representing a set of
- * fields that can be auto-filled together, and the Android system displays a dataset picker UI
+ * fields that can be autofilled together, and the Android system displays a dataset picker UI
  * affordance that the user must use before the {@link android.app.Activity} is filled with
  * the dataset.
  *
@@ -125,7 +124,7 @@
  * </pre>
  *
  * <p>Then after the user picks the second dataset and taps the street field to
- * trigger another auto-fill request, the second response could be:
+ * trigger another autofill request, the second response could be:
  *
  * <pre class="prettyprint">
  *  new FillResponse.Builder()
@@ -141,7 +140,7 @@
  * </pre>
  *
  * <p>The service could require user authentication at the {@link FillResponse} or the
- * {@link Dataset} level, prior to auto-filling an activity - see
+ * {@link Dataset} level, prior to autofilling an activity - see
  * {@link FillResponse.Builder#setAuthentication(IntentSender, RemoteViews)} and
  * {@link Dataset.Builder#setAuthentication(IntentSender)}.
  *
@@ -169,8 +168,6 @@
     private FillResponse(@NonNull Builder builder) {
         mDatasets = builder.mDatasets;
 
-        // TODO(b/33197203, 35727295): this is how mSaveInfo will be set once we don't support
-        // FillResponse.addSavableIds()
         mSaveInfo = builder.mSaveInfo;
         if (mSaveInfo != null) {
             mSaveInfo.addSavableIds(mDatasets);
@@ -223,7 +220,7 @@
         private boolean mDestroyed;
 
         /**
-         * Requires a fill response authentication before auto-filling the activity with
+         * Requires a fill response authentication before autofilling the activity with
          * any data set in this response.
          *
          * <p>This is typically useful when a user interaction is required to unlock their
@@ -236,12 +233,12 @@
          * intent you also need to specify the presentation view to be shown in the fill UI
          * for the user to trigger your authentication flow.</p>
          *
-         * <p>When a user triggers auto-fill, the system launches the provided intent
-         * whose extras will have the {@link AutoFillManager#EXTRA_ASSIST_STRUCTURE screen
+         * <p>When a user triggers autofill, the system launches the provided intent
+         * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
          * content}. Once you complete your authentication flow you should set the activity
          * result to {@link android.app.Activity#RESULT_OK} and provide the fully populated
          * {@link FillResponse response} by setting it to the {@link
-         * AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra.
+         * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
          * For example, if you provided an empty {@link FillResponse resppnse} because the
          * user's data was locked and marked that the response needs an authentication then
          * in the response returned if authentication succeeds you need to provide all
@@ -309,9 +306,9 @@
         /**
          * Sets a {@link Bundle} that will be passed to subsequent APIs that
          * manipulate this response. For example, they are passed to subsequent
-         * calls to {@link AutoFillService#onFillRequest(
+         * calls to {@link AutofillService#onFillRequest(
          * android.app.assist.AssistStructure, Bundle, android.os.CancellationSignal,
-         * FillCallback)} and {@link AutoFillService#onSaveRequest(
+         * FillCallback)} and {@link AutofillService#onSaveRequest(
          * android.app.assist.AssistStructure, Bundle, SaveCallback)}.
          *
          * @param extras The response extras.
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index c6dd1df..2c4ba6c 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -21,8 +21,8 @@
 import android.os.RemoteException;
 
 /**
- * Handles save requests from the {@link AutoFillService} into the {@link Activity} being
- * auto-filled.
+ * Handles save requests from the {@link AutofillService} into the {@link Activity} being
+ * autofilled.
  */
 public final class SaveCallback {
     private final ISaveCallback mCallback;
@@ -35,7 +35,7 @@
 
     /**
      * Notifies the Android System that an
-     * {@link AutoFillService#onSaveRequest (android.app.assist.AssistStructure, Bundle,
+     * {@link AutofillService#onSaveRequest (android.app.assist.AssistStructure, Bundle,
      * SaveCallback)} was successfully fulfilled by the service.
      *
      * @throws RuntimeException if an error occurred while calling the Android System.
@@ -52,7 +52,7 @@
 
     /**
      * Notifies the Android System that an
-     * {@link AutoFillService#onSaveRequest(android.app.assist.AssistStructure, Bundle,
+     * {@link AutofillService#onSaveRequest(android.app.assist.AssistStructure, Bundle,
      * SaveCallback)} could not be fulfilled by the service.
      *
      * @param message error message to be displayed to the user.
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index a8f9aee..a8e3ff8 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -27,6 +27,7 @@
 import android.os.Parcelable;
 import android.util.ArraySet;
 import android.view.autofill.AutoFillId;
+import android.view.autofill.AutofillId;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -39,12 +40,12 @@
  * <p>A {@link SaveInfo} is always associated with a {@link FillResponse}.
  *
  * <p>A {@link SaveInfo} must define the type it represents, and contain at least one
- * {@code savableId}. A {@code savableId} is the {@link AutoFillId} of a view the service is
+ * {@code savableId}. A {@code savableId} is the {@link AutofillId} of a view the service is
  * interested to save in a {@code onSaveRequest()}; the ids of all {@link Dataset} present in the
  * {@link FillResponse} associated with this {@link SaveInfo} are already marked as savable,
- * but additional ids can be added through {@link Builder#addSavableIds(AutoFillId...)}.
+ * but additional ids can be added through {@link Builder#addSavableIds(AutofillId...)}.
  *
- * <p>See {@link AutoFillService#onSaveRequest(android.app.assist.AssistStructure, Bundle,
+ * <p>See {@link AutofillService#onSaveRequest(android.app.assist.AssistStructure, Bundle,
  * SaveCallback)} and {@link FillResponse} for more info.
  */
 public final class SaveInfo implements Parcelable {
@@ -75,7 +76,7 @@
     private final @SaveDataType int mType;
     private CharSequence mNegativeActionTitle;
     private IntentSender mNegativeActionListener;
-    private ArraySet<AutoFillId> mSavableIds;
+    private ArraySet<AutofillId> mSavableIds;
     private final CharSequence mDescription;
 
     /** @hide */
@@ -108,7 +109,7 @@
     }
 
     /** @hide */
-    public @Nullable ArraySet<AutoFillId> getSavableIds() {
+    public @Nullable ArraySet<AutofillId> getSavableIds() {
         return mSavableIds;
     }
 
@@ -126,11 +127,11 @@
     public void addSavableIds(@Nullable ArrayList<Dataset> datasets) {
         if (datasets != null) {
             for (Dataset dataset : datasets) {
-                final ArrayList<AutoFillId> ids = dataset.getFieldIds();
+                final ArrayList<AutofillId> ids = dataset.getFieldIds();
                 if (ids != null) {
                     final int fieldCount = ids.size();
                     for (int i = 0; i < fieldCount; i++) {
-                        final AutoFillId id = ids.get(i);
+                        final AutofillId id = ids.get(i);
                         if (mSavableIds == null) {
                             mSavableIds = new ArraySet<>();
                         }
@@ -149,7 +150,7 @@
         private final @SaveDataType int mType;
         private CharSequence mNegativeActionTitle;
         private IntentSender mNegativeActionListener;
-        private ArraySet<AutoFillId> mSavableIds;
+        private ArraySet<AutofillId> mSavableIds;
         private CharSequence mDescription;
         private boolean mDestroyed;
 
@@ -182,13 +183,13 @@
          *
          * @see FillResponse
          */
-        public @NonNull Builder addSavableIds(@Nullable AutoFillId... ids) {
+        public @NonNull Builder addSavableIds(@Nullable AutofillId... ids) {
             throwIfDestroyed();
 
             if (ids == null) {
                 return this;
             }
-            for (AutoFillId id : ids) {
+            for (AutofillId id : ids) {
                 if (mSavableIds == null) {
                     mSavableIds = new ArraySet<>();
                 }
@@ -302,7 +303,7 @@
             // using specially crafted parcels.
             final Builder builder = new Builder(parcel.readInt());
             builder.setNegativeAction(parcel.readCharSequence(), parcel.readParcelable(null));
-            final ArraySet<AutoFillId> savableIds = parcel.readTypedArraySet(null);
+            final ArraySet<AutofillId> savableIds = parcel.readTypedArraySet(null);
             final int savableIdsCount = (savableIds != null) ? savableIds.size() : 0;
             for (int i = 0; i < savableIdsCount; i++) {
                 builder.addSavableIds(savableIds.valueAt(i));
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index ac9c0d7..ee2b38e 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -474,6 +474,11 @@
         return !isEmpty(a) ? a : Preconditions.checkStringNotEmpty(b);
     }
 
+    /** {@hide} */
+    public static int length(@Nullable String s) {
+        return isEmpty(s) ? 0 : s.length();
+    }
+
     /**
      * Returns the length that the specified CharSequence would have if
      * spaces and ASCII control characters were trimmed from the start and end,
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 77e9f0f..1b74c13 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -161,7 +161,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 root = mViewRootImpl.mView;
             } else {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -217,7 +217,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -283,7 +283,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -291,14 +291,9 @@
             if (root != null && isShown(root)) {
                 AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
                 if (provider != null) {
-                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                        infos = provider.findAccessibilityNodeInfosByText(text,
-                                virtualDescendantId);
-                    } else {
-                        infos = provider.findAccessibilityNodeInfosByText(text,
-                                AccessibilityNodeProvider.HOST_VIEW_ID);
-                    }
-                } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                    infos = provider.findAccessibilityNodeInfosByText(text,
+                            virtualDescendantId);
+                } else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
                     ArrayList<View> foundViews = mTempArrayList;
                     foundViews.clear();
                     root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
@@ -376,7 +371,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -402,7 +397,7 @@
                                 focused = AccessibilityNodeInfo.obtain(
                                         mViewRootImpl.mAccessibilityFocusedVirtualView);
                             }
-                        } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        } else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
                             focused = host.createAccessibilityNodeInfo();
                         }
                     } break;
@@ -471,7 +466,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -531,7 +526,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View target = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
                 target = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 target = mViewRootImpl.mView;
@@ -544,14 +539,9 @@
                 } else {
                     AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                     if (provider != null) {
-                        if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                            succeeded = provider.performAction(virtualDescendantId, action,
-                                    arguments);
-                        } else {
-                            succeeded = provider.performAction(
-                                    AccessibilityNodeProvider.HOST_VIEW_ID, action, arguments);
-                        }
-                    } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        succeeded = provider.performAction(virtualDescendantId, action,
+                                arguments);
+                    } else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
                         succeeded = target.performAccessibilityAction(action, arguments);
                     }
                 }
@@ -711,7 +701,9 @@
             applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
             adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
             callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
-            infos.clear();
+            if (infos != null) {
+                infos.clear();
+            }
         } catch (RemoteException re) {
             /* ignore - the other side will time out */
         } finally {
@@ -761,10 +753,8 @@
         AccessibilityNodeInfo infoWithSpan = null;
         AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
         if (provider != null) {
-            int idForNode = (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
-                    ? AccessibilityNodeProvider.HOST_VIEW_ID : virtualDescendantId;
-            infoWithSpan = provider.createAccessibilityNodeInfo(idForNode);
-        } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            infoWithSpan = provider.createAccessibilityNodeInfo(virtualDescendantId);
+        } else if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
             infoWithSpan = view.createAccessibilityNodeInfo();
         }
         if (infoWithSpan == null) {
@@ -817,13 +807,12 @@
                     }
                 }
             } else {
-                final int idForRoot = (virtualViewId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID)
-                        ? AccessibilityNodeProvider.HOST_VIEW_ID : virtualViewId;
-                final AccessibilityNodeInfo root = provider.createAccessibilityNodeInfo(idForRoot);
+                final AccessibilityNodeInfo root =
+                        provider.createAccessibilityNodeInfo(virtualViewId);
                 if (root != null) {
                     if (extraDataRequested != null) {
                         provider.addExtraDataToAccessibilityNodeInfo(
-                                idForRoot, root, extraDataRequested, arguments);
+                                virtualViewId, root, extraDataRequested, arguments);
                     }
                     outInfos.add(root);
                     if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
@@ -1034,15 +1023,10 @@
                 }
                 final int virtualDescendantId =
                     AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
-                if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
+                if (virtualDescendantId != AccessibilityNodeProvider.HOST_VIEW_ID
                         || accessibilityViewId == providerHost.getAccessibilityViewId()) {
                     final AccessibilityNodeInfo parent;
-                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                        parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
-                    } else {
-                        parent = provider.createAccessibilityNodeInfo(
-                                AccessibilityNodeProvider.HOST_VIEW_ID);
-                    }
+                    parent = provider.createAccessibilityNodeInfo(virtualDescendantId);
                     if (parent == null) {
                         // Going up the parent relation we found a null predecessor,
                         // so remove these disconnected nodes form the result.
@@ -1072,15 +1056,10 @@
                 AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
             final int parentVirtualDescendantId =
                 AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
-            if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
+            if (parentVirtualDescendantId != AccessibilityNodeProvider.HOST_VIEW_ID
                     || parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
-                final AccessibilityNodeInfo parent;
-                if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                    parent = provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
-                } else {
-                    parent = provider.createAccessibilityNodeInfo(
-                            AccessibilityNodeProvider.HOST_VIEW_ID);
-                }
+                final AccessibilityNodeInfo parent =
+                        provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
                 if (parent != null) {
                     final int childCount = parent.getChildCount();
                     for (int i = 0; i < childCount; i++) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ecd5e3b..8bb3fa9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -72,6 +73,7 @@
     private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
     private static native void nativeSetBuffersTransform(long nativeObject, long transform);
     private static native int nativeForceScopedDisconnect(long nativeObject);
+    private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
 
     public static final Parcelable.Creator<Surface> CREATOR =
             new Parcelable.Creator<Surface>() {
@@ -562,6 +564,21 @@
     }
 
     /**
+     * Transfer ownership of buffer and present it on the Surface.
+     * @hide
+     */
+    public void attachAndQueueBuffer(GraphicBuffer buffer) {
+        synchronized (mLock) {
+            checkNotReleasedLocked();
+            int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
+            if (err != 0) {
+                throw new RuntimeException(
+                        "Failed to attach and queue buffer to Surface (bad object?)");
+            }
+        }
+    }
+
+    /**
      * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
      * @hide
      */
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b718696..519c1e2 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -95,6 +95,11 @@
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long nativeObject,
             IBinder handle, long frame);
+    private static native void nativeDeferTransactionUntilSurface(long nativeObject,
+            long surfaceObject, long frame);
+    private static native void nativeReparentChildren(long nativeObject,
+            IBinder handle);
+    private static native void nativeSeverChildren(long nativeObject);
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
@@ -418,7 +423,23 @@
     }
 
     public void deferTransactionUntil(IBinder handle, long frame) {
-        nativeDeferTransactionUntil(mNativeObject, handle, frame);
+        if (frame > 0) {
+            nativeDeferTransactionUntil(mNativeObject, handle, frame);
+        }
+    }
+
+    public void deferTransactionUntil(Surface barrier, long frame) {
+        if (frame > 0) {
+            nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
+        }
+    }
+
+    public void reparentChildren(IBinder newParentHandle) {
+        nativeReparentChildren(mNativeObject, newParentHandle);
+    }
+
+    public void detachChildren() {
+        nativeSeverChildren(mNativeObject);
     }
 
     public void setOverrideScalingMode(int scalingMode) {
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index 3cf5af4..b5912bc 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -27,6 +27,7 @@
     private long mNativeClient; // SurfaceComposerClient*
 
     private static native long nativeCreate();
+    private static native long nativeCreateScoped(long surfacePtr);
     private static native void nativeDestroy(long ptr);
     private static native void nativeKill(long ptr);
 
@@ -35,6 +36,10 @@
         mNativeClient = nativeCreate();
     }
 
+    public SurfaceSession(Surface root) {
+        mNativeClient = nativeCreateScoped(root.mNativeObject);
+    }
+
     /* no user serviceable parts here ... */
     @Override
     protected void finalize() throws Throwable {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index d2577d4..61b1247 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,6 +16,10 @@
 
 package android.view;
 
+import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
+import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
+
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
 import android.content.res.Configuration;
@@ -26,16 +30,12 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
 
-import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.SurfaceCallbackHelper;
 
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -92,8 +92,8 @@
  * positioned asynchronously.</p>
  */
 public class SurfaceView extends View {
-    static private final String TAG = "SurfaceView";
-    static private final boolean DEBUG = false;
+    private static final String TAG = "SurfaceView";
+    private static final boolean DEBUG = false;
 
     final ArrayList<SurfaceHolder.Callback> mCallbacks
             = new ArrayList<SurfaceHolder.Callback>();
@@ -102,28 +102,23 @@
 
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     final Surface mSurface = new Surface();       // Current surface in use
-    final Surface mNewSurface = new Surface();    // New surface we are switching to
     boolean mDrawingStopped = true;
+    // We use this to track if the application has produced a frame
+    // in to the Surface. Up until that point, we should be careful not to punch
+    // holes.
+    boolean mDrawFinished = false;
 
-    final WindowManager.LayoutParams mLayout
-            = new WindowManager.LayoutParams();
-    IWindowSession mSession;
-    MyWindow mWindow;
-    final Rect mVisibleInsets = new Rect();
-    final Rect mWinFrame = new Rect();
-    final Rect mOverscanInsets = new Rect();
-    final Rect mContentInsets = new Rect();
-    final Rect mStableInsets = new Rect();
-    final Rect mOutsets = new Rect();
-    final Rect mBackdropFrame = new Rect();
+    final Rect mScreenRect = new Rect();
+    SurfaceSession mSurfaceSession;
+
+    SurfaceControl mSurfaceControl;
     final Rect mTmpRect = new Rect();
     final Configuration mConfiguration = new Configuration();
 
     static final int KEEP_SCREEN_ON_MSG = 1;
-    static final int GET_NEW_SURFACE_MSG = 2;
-    static final int UPDATE_WINDOW_MSG = 3;
+    static final int DRAW_FINISHED_MSG = 2;
 
-    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+    int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
 
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
@@ -135,11 +130,9 @@
                 case KEEP_SCREEN_ON_MSG: {
                     setKeepScreenOn(msg.arg1 != 0);
                 } break;
-                case GET_NEW_SURFACE_MSG: {
-                    handleGetNewSurface();
-                } break;
-                case UPDATE_WINDOW_MSG: {
-                    updateWindow();
+                case DRAW_FINISHED_MSG: {
+                    mDrawFinished = true;
+                    invalidate();
                 } break;
             }
         }
@@ -149,7 +142,7 @@
             = new ViewTreeObserver.OnScrollChangedListener() {
                     @Override
                     public void onScrollChanged() {
-                        updateWindow();
+                        updateSurface();
                     }
             };
 
@@ -159,13 +152,14 @@
                 public boolean onPreDraw() {
                     // reposition ourselves where the surface is
                     mHaveFrame = getWidth() > 0 && getHeight() > 0;
-                    updateWindow();
+                    updateSurface();
                     return true;
                 }
             };
 
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
+    boolean mLastWindowVisibility = false;
     boolean mViewVisibility = false;
     int mRequestedWidth = -1;
     int mRequestedHeight = -1;
@@ -181,19 +175,17 @@
     boolean mVisible = false;
     int mWindowSpaceLeft = -1;
     int mWindowSpaceTop = -1;
-    int mWindowSpaceWidth = -1;
-    int mWindowSpaceHeight = -1;
+    int mSurfaceWidth = -1;
+    int mSurfaceHeight = -1;
     int mFormat = -1;
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
-    boolean mUpdateWindowNeeded;
-    boolean mReportDrawNeeded;
     private Translator mTranslator;
-    private int mWindowInsetLeft;
-    private int mWindowInsetTop;
 
     private boolean mGlobalListenersAdded;
 
+    private int mSurfaceFlags = SurfaceControl.HIDDEN;
+
     public SurfaceView(Context context) {
         this(context, null);
     }
@@ -227,11 +219,8 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mParent.requestTransparentRegion(this);
-        mSession = getWindowSession();
-        mLayout.token = getWindowToken();
-        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
-        mLayout.packageName = mContext.getOpPackageName();
         mViewVisibility = getVisibility() == VISIBLE;
+        mRequestedVisible = mViewVisibility && mWindowVisibility;
 
         if (!mGlobalListenersAdded) {
             ViewTreeObserver observer = getViewTreeObserver();
@@ -246,7 +235,7 @@
         super.onWindowVisibilityChanged(visibility);
         mWindowVisibility = visibility == VISIBLE;
         mRequestedVisible = mWindowVisibility && mViewVisibility;
-        updateWindow();
+        updateSurface();
     }
 
     @Override
@@ -264,7 +253,7 @@
             requestLayout();
         }
         mRequestedVisible = newRequestedVisible;
-        updateWindow();
+        updateSurface();
     }
 
     @Override
@@ -277,19 +266,14 @@
         }
 
         mRequestedVisible = false;
-        updateWindow();
-        mHaveFrame = false;
-        if (mWindow != null) {
-            try {
-                mSession.remove(mWindow);
-            } catch (RemoteException ex) {
-                // Not much we can do here...
-            }
-            mWindow = null;
-        }
-        mSession = null;
-        mLayout.token = null;
 
+        updateSurface();
+        if (mSurfaceControl != null) {
+            mSurfaceControl.destroy();
+        }
+        mSurfaceControl = null;
+
+        mHaveFrame = false;
         super.onDetachedFromWindow();
     }
 
@@ -308,13 +292,13 @@
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
         boolean result = super.setFrame(left, top, right, bottom);
-        updateWindow();
+        updateSurface();
         return result;
     }
 
     @Override
     public boolean gatherTransparentRegion(Region region) {
-        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+        if (isAboveParent()) {
             return super.gatherTransparentRegion(region);
         }
 
@@ -341,7 +325,7 @@
 
     @Override
     public void draw(Canvas canvas) {
-        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+        if (mDrawFinished && !isAboveParent()) {
             // draw() is not called when SKIP_DRAW is set
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
                 // punch a whole in the view-hierarchy below us
@@ -353,8 +337,8 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
-            // if SKIP_DRAW is cleared, draw() has already punched a hole
+        if (mDrawFinished && !isAboveParent()) {
+            // draw() is not called when SKIP_DRAW is set
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                 // punch a whole in the view-hierarchy below us
                 canvas.drawColor(0, PorterDuff.Mode.CLEAR);
@@ -375,9 +359,8 @@
      * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
      */
     public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-        mWindowType = isMediaOverlay
-                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
-                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+        mSubLayer = isMediaOverlay
+            ? APPLICATION_MEDIA_OVERLAY_SUBLAYER : APPLICATION_MEDIA_SUBLAYER;
     }
 
     /**
@@ -395,12 +378,9 @@
      */
     public void setZOrderOnTop(boolean onTop) {
         if (onTop) {
-            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-            // ensures the surface is placed below the IME
-            mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            mSubLayer = APPLICATION_PANEL_SUBLAYER;
         } else {
-            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            mSubLayer = APPLICATION_MEDIA_SUBLAYER;
         }
     }
 
@@ -418,31 +398,32 @@
      */
     public void setSecure(boolean isSecure) {
         if (isSecure) {
-            mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE;
+            mSurfaceFlags |= SurfaceControl.SECURE;
         } else {
-            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE;
+            mSurfaceFlags &= ~SurfaceControl.SECURE;
         }
     }
 
-    /**
-     * Hack to allow special layering of windows.  The type is one of the
-     * types in WindowManager.LayoutParams.  This is a hack so:
-     * @hide
-     */
-    public void setWindowType(int type) {
-        mWindowType = type;
+    private Rect getParentSurfaceInsets() {
+        final ViewRootImpl root = getViewRootImpl();
+        if (root == null) {
+            return null;
+        } else {
+            return root.mWindowAttributes.surfaceInsets;
+        }
     }
 
     /** @hide */
-    protected void updateWindow() {
+    protected void updateSurface() {
         if (!mHaveFrame) {
             return;
         }
         ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot != null) {
-            mTranslator = viewRoot.mTranslator;
+        if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+            return;
         }
 
+        mTranslator = viewRoot.mTranslator;
         if (mTranslator != null) {
             mSurface.setCompatibilityTranslator(mTranslator);
         }
@@ -452,17 +433,15 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
-        final boolean creating = mWindow == null;
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
+        final boolean creating = (mSurfaceControl == null || formatChanged)
+                && mRequestedVisible;
+        final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
         final boolean visibleChanged = mVisible != mRequestedVisible;
-        final boolean layoutSizeChanged = getWidth() != mLayout.width
-                || getHeight() != mLayout.height;
-
+        final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged
-            || mUpdateWindowNeeded || mReportDrawNeeded) {
+        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
             getLocationInWindow(mLocation);
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -476,93 +455,77 @@
                 final boolean visible = mVisible = mRequestedVisible;
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                mWindowSpaceWidth = myWidth;
-                mWindowSpaceHeight = myHeight;
+                mSurfaceWidth = myWidth;
+                mSurfaceHeight = myHeight;
                 mFormat = mRequestedFormat;
+                mLastWindowVisibility = mWindowVisibility;
 
-                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
-
-                // Places the window relative
-                mLayout.x = mWindowSpaceLeft;
-                mLayout.y = mWindowSpaceTop;
-                mLayout.width = getWidth();
-                mLayout.height = getHeight();
+                mScreenRect.left = mWindowSpaceLeft;
+                mScreenRect.top = mWindowSpaceTop;
+                mScreenRect.right = mWindowSpaceLeft + getWidth();
+                mScreenRect.bottom = mWindowSpaceTop + getHeight();
                 if (mTranslator != null) {
-                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
+                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
-                mLayout.format = mRequestedFormat;
-                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                              | WindowManager.LayoutParams.FLAG_SCALED
-                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              ;
-                if (!creating && !sizeChanged) {
-                    mLayout.privateFlags |=
-                            WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
-                } else {
-                    mLayout.privateFlags &=
-                            ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
+                final Rect surfaceInsets = getParentSurfaceInsets();
+                mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
+
+                if (creating) {
+                    mSurfaceSession = new SurfaceSession(viewRoot.mSurface);
+                    mSurfaceControl = new SurfaceControl(mSurfaceSession,
+                            "SurfaceView - " + viewRoot.getTitle().toString(),
+                            mSurfaceWidth, mSurfaceHeight, mFormat,
+                            mSurfaceFlags);
                 }
 
-                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
-                    mLayout.privateFlags |=
-                            WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-                }
-                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
-                    | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
-
-                if (mWindow == null) {
-                    Display display = getDisplay();
-                    mWindow = new MyWindow(this);
-                    mLayout.type = mWindowType;
-                    mLayout.gravity = Gravity.START|Gravity.TOP;
-                    mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
-                            mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets,
-                            mStableInsets);
-                }
-
-                boolean realSizeChanged;
-                boolean reportDrawNeeded;
-
-                int relayoutResult;
+                boolean realSizeChanged = false;
 
                 mSurfaceLock.lock();
                 try {
-                    mUpdateWindowNeeded = false;
-                    reportDrawNeeded = mReportDrawNeeded;
-                    mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
 
                     if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                             + "Cur surface: " + mSurface);
 
-                    relayoutResult = mSession.relayout(
-                        mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight,
-                            visible ? VISIBLE : GONE,
-                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
-                            mWinFrame, mOverscanInsets, mContentInsets,
-                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
-                            mConfiguration, mNewSurface);
-                    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
-                        reportDrawNeeded = true;
+                    SurfaceControl.openTransaction();
+                    try {
+                        mSurfaceControl.setLayer(mSubLayer);
+                        if (mViewVisibility) {
+                            mSurfaceControl.show();
+                        } else {
+                            mSurfaceControl.hide();
+                        }
+
+                        // While creating the surface, we will set it's initial
+                        // geometry. Outside of that though, we should generally
+                        // leave it to the RenderThread.
+                        if (creating || !mRtHandlingPositionUpdates) {
+                            mSurfaceControl.setPosition(mScreenRect.left, mScreenRect.top);
+                            mSurfaceControl.setMatrix(mScreenRect.width() / (float) mSurfaceWidth,
+                                    0.0f, 0.0f,
+                                    mScreenRect.height() / (float) mSurfaceHeight);
+                        }
+                        if (sizeChanged) {
+                            mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight);
+                        }
+                    } finally {
+                        SurfaceControl.closeTransaction();
                     }
 
-                    if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
-                            + "New surface: " + mNewSurface
-                            + ", vis=" + visible + ", frame=" + mWinFrame);
+                    if (sizeChanged || creating) {
+                        redrawNeeded = true;
+                    }
 
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
                     if (mTranslator == null) {
-                        mSurfaceFrame.right = mWinFrame.width();
-                        mSurfaceFrame.bottom = mWinFrame.height();
+                        mSurfaceFrame.right = mSurfaceWidth;
+                        mSurfaceFrame.bottom = mSurfaceHeight;
                     } else {
                         float appInvertedScale = mTranslator.applicationInvertedScale;
-                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
-                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
+                        mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
+                        mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
                     }
 
                     final int surfaceWidth = mSurfaceFrame.right;
@@ -576,12 +539,11 @@
                 }
 
                 try {
-                    redrawNeeded |= creating | reportDrawNeeded;
+                    redrawNeeded |= visible && !mDrawFinished;
 
                     SurfaceHolder.Callback callbacks[] = null;
 
-                    final boolean surfaceChanged = (relayoutResult
-                            & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0;
+                    final boolean surfaceChanged = creating;
                     if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
                         mSurfaceCreated = false;
                         if (mSurface.isValid()) {
@@ -608,7 +570,10 @@
                         }
                     }
 
-                    mSurface.transferFrom(mNewSurface);
+                    if (creating) {
+                        mSurface.copyFrom(mSurfaceControl);
+                    }
+
                     if (visible && mSurface.isValid()) {
                         if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
                             mSurfaceCreated = true;
@@ -641,53 +606,55 @@
                                 callbacks = getSurfaceCallbacks();
                             }
                             SurfaceCallbackHelper sch =
-                                    new SurfaceCallbackHelper(mSession, mWindow);
+                                    new SurfaceCallbackHelper(this::onDrawFinished);
                             sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                         }
                     }
                 } finally {
                     mIsCreating = false;
-                    mSession.performDeferredDestroy(mWindow);
+                    if (mSurfaceControl != null && !mSurfaceCreated) {
+                        mSurfaceControl.destroy();
+                        mSurfaceControl = null;
+                    }
                 }
-            } catch (RemoteException ex) {
+            } catch (Exception ex) {
                 Log.e(TAG, "Exception from relayout", ex);
             }
             if (DEBUG) Log.v(
-                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
-                " w=" + mLayout.width + " h=" + mLayout.height +
-                ", frame=" + mSurfaceFrame);
+                TAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top
+                + " w=" + mScreenRect.width() + " h=" + mScreenRect.height()
+                + ", frame=" + mSurfaceFrame);
         } else {
             // Calculate the window position in case RT loses the window
             // and we need to fallback to a UI-thread driven position update
-            getLocationInWindow(mLocation);
+            getLocationInSurface(mLocation);
             final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
                     || mWindowSpaceTop != mLocation[1];
+            final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
+                    || getHeight() != mScreenRect.height();
             if (positionChanged || layoutSizeChanged) { // Only the position has changed
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                // For our size changed check, we keep mLayout.width and mLayout.height
+                // For our size changed check, we keep mScreenRect.width() and mScreenRect.height()
                 // in view local space.
-                mLocation[0] = mLayout.width = getWidth();
-                mLocation[1] = mLayout.height = getHeight();
+                mLocation[0] = getWidth();
+                mLocation[1] = getHeight();
 
-                transformFromViewToWindowSpace(mLocation);
-
-                mTmpRect.set(mWindowSpaceLeft, mWindowSpaceTop,
+                mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
                         mLocation[0], mLocation[1]);
 
                 if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mTmpRect);
+                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
-                        if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " +
+                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
                                 "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                                mTmpRect.left, mTmpRect.top,
-                                mTmpRect.right, mTmpRect.bottom));
-                        mSession.repositionChild(mWindow, mTmpRect.left, mTmpRect.top,
-                                mTmpRect.right, mTmpRect.bottom, -1, mTmpRect);
-                    } catch (RemoteException ex) {
+                                mScreenRect.left, mScreenRect.top,
+                                mScreenRect.right, mScreenRect.bottom));
+                        setParentSpaceRectangle(mScreenRect, -1);
+                    } catch (Exception ex) {
                         Log.e(TAG, "Exception from relayout", ex);
                     }
                 }
@@ -695,20 +662,43 @@
         }
     }
 
+    private void onDrawFinished() {
+        if (DEBUG) {
+            Log.i(TAG, System.identityHashCode(this) + " "
+                    + "finishedDrawing");
+        }
+        mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
+    }
+
+    private void setParentSpaceRectangle(Rect position, long frameNumber) {
+        ViewRootImpl viewRoot = getViewRootImpl();
+
+        SurfaceControl.openTransaction();
+        try {
+            if (frameNumber > 0) {
+                mSurfaceControl.deferTransactionUntil(viewRoot.mSurface, frameNumber);
+            }
+            mSurfaceControl.setPosition(position.left, position.top);
+            mSurfaceControl.setMatrix(position.width() / (float) mSurfaceWidth,
+                    0.0f, 0.0f,
+                    position.height() / (float) mSurfaceHeight);
+        } finally {
+            SurfaceControl.closeTransaction();
+        }
+    }
+
     private Rect mRTLastReportedPosition = new Rect();
 
     /**
      * Called by native by a Rendering Worker thread to update the window position
      * @hide
      */
-    public final void updateWindowPosition_renderWorker(long frameNumber,
+    public final void updateSurfacePosition_renderWorker(long frameNumber,
             int left, int top, int right, int bottom) {
-        IWindowSession session = mSession;
-        MyWindow window = mWindow;
-        if (session == null || window == null) {
-            // Guess we got detached, that sucks
+        if (mSurfaceControl == null) {
             return;
         }
+
         // TODO: This is teensy bit racey in that a brand new SurfaceView moving on
         // its 2nd frame if RenderThread is running slowly could potentially see
         // this as false, enter the branch, get pre-empted, then this comes along
@@ -726,35 +716,29 @@
         }
         try {
             if (DEBUG) {
-                Log.d(TAG, String.format("%d updateWindowPosition RenderWorker, frameNr = %d, " +
+                Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " +
                         "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
                         frameNumber, left, top, right, bottom));
             }
-            // Just using mRTLastReportedPosition as a dummy rect here
-            session.repositionChild(window, left, top, right, bottom,
-                    frameNumber,
-                    mRTLastReportedPosition);
-            // Now overwrite mRTLastReportedPosition with our values
             mRTLastReportedPosition.set(left, top, right, bottom);
-        } catch (RemoteException ex) {
+            setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
+            // Now overwrite mRTLastReportedPosition with our values
+        } catch (Exception ex) {
             Log.e(TAG, "Exception from repositionChild", ex);
         }
     }
 
     /**
-     * Called by native on RenderThread to notify that the window is no longer in the
+     * Called by native on RenderThread to notify that the view is no longer in the
      * draw tree. UI thread is blocked at this point.
      * @hide
      */
-    public final void windowPositionLost_uiRtSync(long frameNumber) {
+    public final void surfacePositionLost_uiRtSync(long frameNumber) {
         if (DEBUG) {
             Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
                     System.identityHashCode(this), frameNumber));
         }
-        IWindowSession session = mSession;
-        MyWindow window = mWindow;
-        if (session == null || window == null) {
-            // We got detached prior to receiving this, abort
+        if (mSurfaceControl == null) {
             return;
         }
         if (mRtHandlingPositionUpdates) {
@@ -763,19 +747,14 @@
             // safely access other member variables at this time.
             // So do what the UI thread would have done if RT wasn't handling position
             // updates.
-            mTmpRect.set(mLayout.x, mLayout.y,
-                    mLayout.x + mLayout.width,
-                    mLayout.y + mLayout.height);
-
-            if (!mTmpRect.isEmpty() && !mTmpRect.equals(mRTLastReportedPosition)) {
+            if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
                 try {
-                    if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " +
+                    if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " +
                             "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                            mTmpRect.left, mTmpRect.top,
-                            mTmpRect.right, mTmpRect.bottom));
-                    session.repositionChild(window, mTmpRect.left, mTmpRect.top,
-                            mTmpRect.right, mTmpRect.bottom, frameNumber, mWinFrame);
-                } catch (RemoteException ex) {
+                            mScreenRect.left, mScreenRect.top,
+                            mScreenRect.right, mScreenRect.bottom));
+                    setParentSpaceRectangle(mScreenRect, frameNumber);
+                } catch (Exception ex) {
                     Log.e(TAG, "Exception from relayout", ex);
                 }
             }
@@ -792,10 +771,6 @@
         return callbacks;
     }
 
-    void handleGetNewSurface() {
-        updateWindow();
-    }
-
     /**
      * Check to see if the surface has fixed size dimensions or if the surface's
      * dimensions are dimensions are dependent on its current layout.
@@ -807,65 +782,8 @@
         return (mRequestedWidth != -1 || mRequestedHeight != -1);
     }
 
-    private static class MyWindow extends BaseIWindow {
-        private final WeakReference<SurfaceView> mSurfaceView;
-
-        public MyWindow(SurfaceView surfaceView) {
-            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
-        }
-
-        @Override
-        public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
-                Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                Configuration newConfig, Rect backDropRect, boolean forceLayout,
-                boolean alwaysConsumeNavBar, int displayId) {
-            SurfaceView surfaceView = mSurfaceView.get();
-            if (surfaceView != null) {
-                if (DEBUG) Log.v(TAG, surfaceView + " got resized: w=" + frame.width()
-                        + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight);
-                surfaceView.mSurfaceLock.lock();
-                try {
-                    if (reportDraw) {
-                        surfaceView.mUpdateWindowNeeded = true;
-                        surfaceView.mReportDrawNeeded = true;
-                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
-                    } else if (surfaceView.mWinFrame.width() != frame.width()
-                            || surfaceView.mWinFrame.height() != frame.height()
-                            || forceLayout) {
-                        surfaceView.mUpdateWindowNeeded = true;
-                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
-                    }
-                } finally {
-                    surfaceView.mSurfaceLock.unlock();
-                }
-            }
-        }
-
-        @Override
-        public void dispatchAppVisibility(boolean visible) {
-            // The point of SurfaceView is to let the app control the surface.
-        }
-
-        @Override
-        public void dispatchGetNewSurface() {
-            SurfaceView surfaceView = mSurfaceView.get();
-            if (surfaceView != null) {
-                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
-                surfaceView.mHandler.sendMessage(msg);
-            }
-        }
-
-        @Override
-        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
-            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
-        }
-
-        @Override
-        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
-        }
-
-        int mCurWidth = -1;
-        int mCurHeight = -1;
+    private boolean isAboveParent() {
+        return mSubLayer >= 0;
     }
 
     private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
@@ -913,15 +831,14 @@
 
         @Override
         public void setFormat(int format) {
-
             // for backward compatibility reason, OPAQUE always
             // means 565 for SurfaceView
             if (format == PixelFormat.OPAQUE)
                 format = PixelFormat.RGB_565;
 
             mRequestedFormat = format;
-            if (mWindow != null) {
-                updateWindow();
+            if (mSurfaceControl != null) {
+                updateSurface();
             }
         }
 
@@ -982,10 +899,10 @@
             mSurfaceLock.lock();
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped="
-                    + mDrawingStopped + ", win=" + mWindow);
+                    + mDrawingStopped + ", surfaceControl=" + mSurfaceControl);
 
             Canvas c = null;
-            if (!mDrawingStopped && mWindow != null) {
+            if (!mDrawingStopped && mSurfaceControl != null) {
                 try {
                     if (hardware) {
                         c = mSurface.lockHardwareCanvas();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8cfd6a7..aa1cbf2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -94,12 +94,12 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillType;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -945,175 +945,175 @@
 
     /** @hide */
     @IntDef({
-            AUTO_FILL_MODE_INHERIT,
-            AUTO_FILL_MODE_AUTO,
-            AUTO_FILL_MODE_MANUAL
+            AUTOFILL_MODE_INHERIT,
+            AUTOFILL_MODE_AUTO,
+            AUTOFILL_MODE_MANUAL
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface AutoFillMode {}
+    public @interface AutofillMode {}
 
     /**
-     * This view inherits the auto-fill state from it's parent. If there is no parent it is
-     * {@link #AUTO_FILL_MODE_AUTO}.
-     * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">
-     * {@code android:autoFillMode}.
+     * This view inherits the autofill state from it's parent. If there is no parent it is
+     * {@link #AUTOFILL_MODE_AUTO}.
+     * Use with {@link #setAutofillMode(int)} and <a href="#attr_android:autofillMode">
+     * {@code android:autofillMode}.
      */
-    public static final int AUTO_FILL_MODE_INHERIT = 0;
+    public static final int AUTOFILL_MODE_INHERIT = 0;
 
     /**
-     * Allows this view to automatically trigger an auto-fill request when it get focus.
-     * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">
-     * {@code android:autoFillMode}.
+     * Allows this view to automatically trigger an autofill request when it get focus.
+     * Use with {@link #setAutofillMode(int)} and <a href="#attr_android:autofillMode">
+     * {@code android:autofillMode}.
      */
-    public static final int AUTO_FILL_MODE_AUTO = 1;
+    public static final int AUTOFILL_MODE_AUTO = 1;
 
     /**
-     * Do not trigger an auto-fill request if this view is focused. The user can still force
-     * an auto-fill request.
-     * <p>This does not prevent this field from being auto-filled if an auto-fill operation is
+     * Do not trigger an autofill request if this view is focused. The user can still force
+     * an autofill request.
+     * <p>This does not prevent this field from being autofilled if an autofill operation is
      * triggered from a different view.</p>
      *
-     * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">{@code
-     * android:autoFillMode}.
+     * Use with {@link #setAutofillMode(int)} and <a href="#attr_android:autofillMode">{@code
+     * android:autofillMode}.
      */
-    public static final int AUTO_FILL_MODE_MANUAL = 2;
+    public static final int AUTOFILL_MODE_MANUAL = 2;
 
     /** @hide */
     @IntDef({
-            AUTO_FILL_HINT_NONE,
-            AUTO_FILL_HINT_EMAIL_ADDRESS,
-            AUTO_FILL_HINT_NAME,
-            AUTO_FILL_HINT_POSTAL_ADDRESS,
-            AUTO_FILL_HINT_PASSWORD,
-            AUTO_FILL_HINT_PHONE,
-            AUTO_FILL_HINT_USERNAME,
-            AUTO_FILL_HINT_POSTAL_CODE,
-            AUTO_FILL_HINT_CREDIT_CARD_NUMBER,
-            AUTO_FILL_HINT_CREDIT_CARD_SECURITY_CODE,
-            AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
-            AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
-            AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
-            AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DAY,
+            AUTOFILL_HINT_NONE,
+            AUTOFILL_HINT_EMAIL_ADDRESS,
+            AUTOFILL_HINT_NAME,
+            AUTOFILL_HINT_POSTAL_ADDRESS,
+            AUTOFILL_HINT_PASSWORD,
+            AUTOFILL_HINT_PHONE,
+            AUTOFILL_HINT_USERNAME,
+            AUTOFILL_HINT_POSTAL_CODE,
+            AUTOFILL_HINT_CREDIT_CARD_NUMBER,
+            AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE,
+            AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE,
+            AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH,
+            AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR,
+            AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY,
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface AutoFillHint {}
+    public @interface AutofillHint {}
 
     /**
-     * No auto-fill hint is set.
+     * No autofill hint is set.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_NONE = 0;
+    public static final int AUTOFILL_HINT_NONE = 0;
 
     /**
      * This view contains an email address.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_EMAIL_ADDRESS = 0x1;
+    public static final int AUTOFILL_HINT_EMAIL_ADDRESS = 0x1;
 
     /**
      * The view contains a real name.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_NAME = 0x2;
+    public static final int AUTOFILL_HINT_NAME = 0x2;
 
     /**
      * The view contains a user name.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_USERNAME = 0x4;
+    public static final int AUTOFILL_HINT_USERNAME = 0x4;
 
     /**
      * The view contains a password.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_PASSWORD = 0x8;
+    public static final int AUTOFILL_HINT_PASSWORD = 0x8;
 
     /**
      * The view contains a phone number.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_PHONE = 0x10;
+    public static final int AUTOFILL_HINT_PHONE = 0x10;
 
     /**
      * The view contains a postal address.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_POSTAL_ADDRESS = 0x20;
+    public static final int AUTOFILL_HINT_POSTAL_ADDRESS = 0x20;
 
     /**
      * The view contains a postal code.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_POSTAL_CODE = 0x40;
+    public static final int AUTOFILL_HINT_POSTAL_CODE = 0x40;
 
     /**
      * The view contains a credit card number.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_NUMBER = 0x80;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_NUMBER = 0x80;
 
     /**
      * The view contains a credit card security code.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_SECURITY_CODE = 0x100;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_SECURITY_CODE = 0x100;
 
     /**
      * The view contains a credit card expiration date.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 0x200;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE = 0x200;
 
     /**
      * The view contains the month a credit card expires.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 0x400;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_MONTH = 0x400;
 
     /**
      * The view contains the year a credit card expires.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 0x800;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR = 0x800;
 
     /**
      * The view contains the day a credit card expires.
      *
-     * Use with {@link #setAutoFillHint(int)} and <a href="#attr_android:autoFillHint">
-     * {@code android:autoFillHint}.
+     * Use with {@link #setAutofillHint(int)} and <a href="#attr_android:autofillHint">
+     * {@code android:autofillHint}.
      */
-    public static final int AUTO_FILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 0x1000;
+    public static final int AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = 0x1000;
 
     /**
-     * Hint for the auto-fill services that describes the content of the view.
+     * Hint for the autofill services that describes the content of the view.
      */
-    @AutoFillHint private int mAutoFillHint;
+    @AutofillHint private int mAutofillHint;
 
     /** @hide */
     @IntDef({
@@ -1134,18 +1134,18 @@
     /**
      * Autofill type for a text field, which is filled by a {@link CharSequence}.
      *
-     * <p>{@link AutoFillValue} instances for autofilling a {@link View} can be obtained through
-     * {@link AutoFillValue#forText(CharSequence)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getTextValue()}.
+     * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
+     * {@link AutofillValue#forText(CharSequence)}, and the value passed to autofill a
+     * {@link View} can be fetched through {@link AutofillValue#getTextValue()}.
      */
     public static final int AUTOFILL_TYPE_TEXT = 1;
 
     /**
      * Autofill type for a togglable field, which is filled by a {@code boolean}.
      *
-     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forToggle(boolean)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getToggleValue()}.
+     * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
+     * {@link AutofillValue#forToggle(boolean)}, and the value passed to autofill a
+     * {@link View} can be fetched through {@link AutofillValue#getToggleValue()}.
      */
     public static final int AUTOFILL_TYPE_TOGGLE = 2;
 
@@ -1153,12 +1153,12 @@
      * Autofill type for a selection list field, which is filled by an {@code int}
      * representing the element index inside the list (starting at {@code 0}).
      *
-     * <p>{@link AutoFillValue} instances for autofilling a {@link View} can be obtained through
-     * {@link AutoFillValue#forList(int)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getListValue()}.
+     * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
+     * {@link AutofillValue#forList(int)}, and the value passed to autofill a
+     * {@link View} can be fetched through {@link AutofillValue#getListValue()}.
      *
      * <p>The available options in the selection list are typically provided by
-     * {@link android.app.assist.AssistStructure.ViewNode#getAutoFillOptions()}.
+     * {@link android.app.assist.AssistStructure.ViewNode#getAutofillOptions()}.
      */
     public static final int AUTOFILL_TYPE_LIST = 3;
 
@@ -1168,9 +1168,9 @@
      * the number of milliseconds since the standard base time known as "the epoch", namely
      * January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()}.
      *
-     * <p>{@link AutoFillValue} instances for autofilling a {@link View} can be obtained through
-     * {@link AutoFillValue#forDate(long)}, and the values passed to
-     * auto-fill a {@link View} can be fetched through {@link AutoFillValue#getDateValue()}.
+     * <p>{@link AutofillValue} instances for autofilling a {@link View} can be obtained through
+     * {@link AutofillValue#forDate(long)}, and the values passed to
+     * autofill a {@link View} can be fetched through {@link AutofillValue#getDateValue()}.
      */
     public static final int AUTOFILL_TYPE_DATE = 4;
 
@@ -2768,8 +2768,13 @@
      *                 x                 * NO LONGER NEEDED, SHOULD BE REUSED *
      *                1                  PFLAG3_FINGER_DOWN
      *               1                   PFLAG3_FOCUSED_BY_DEFAULT
+<<<<<<< HEAD
      *             11                    PFLAG3_AUTO_FILL_MODE_MASK
      *           11                      PFLAG3_IMPORTANT_FOR_AUTOFILL
+=======
+     *             11                    PFLAG3_AUTOFILL_MODE_MASK
+     *           xx                      * NO LONGER NEEDED, SHOULD BE REUSED *
+>>>>>>> Replaced auto-fill by autofill to keep it consistent with API style.
      *          1                        PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE
      *         1                         PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED
      *        1                          PFLAG3_TEMPORARY_DETACH
@@ -2990,21 +2995,21 @@
     private static final int PFLAG3_FOCUSED_BY_DEFAULT = 0x40000;
 
     /**
-     * Shift for the place where the auto-fill mode is stored in the pflags
+     * Shift for the place where the autofill mode is stored in the pflags
      *
-     * @see #getAutoFillMode()
-     * @see #setAutoFillMode(int)
+     * @see #getAutofillMode()
+     * @see #setAutofillMode(int)
      */
-    private static final int PFLAG3_AUTO_FILL_MODE_SHIFT = 19;
+    private static final int PFLAG3_AUTOFILL_MODE_SHIFT = 19;
 
     /**
-     * Mask for auto-fill modes
+     * Mask for autofill modes
      *
-     * @see #getAutoFillMode()
-     * @see #setAutoFillMode(int)
+     * @see #getAutofillMode()
+     * @see #setAutofillMode(int)
      */
-    private static final int PFLAG3_AUTO_FILL_MODE_MASK = (AUTO_FILL_MODE_INHERIT
-            | AUTO_FILL_MODE_AUTO | AUTO_FILL_MODE_MANUAL) << PFLAG3_AUTO_FILL_MODE_SHIFT;
+    private static final int PFLAG3_AUTOFILL_MODE_MASK = (AUTOFILL_MODE_INHERIT
+            | AUTOFILL_MODE_AUTO | AUTOFILL_MODE_MANUAL) << PFLAG3_AUTOFILL_MODE_SHIFT;
 
     /**
      * Shift for the bits in {@link #mPrivateFlags3} related to the
@@ -5037,14 +5042,14 @@
                         setFocusedByDefault(a.getBoolean(attr, true));
                     }
                     break;
-                case R.styleable.View_autoFillMode:
+                case R.styleable.View_autofillMode:
                     if (a.peekValue(attr) != null) {
-                        setAutoFillMode(a.getInt(attr, AUTO_FILL_MODE_INHERIT));
+                        setAutofillMode(a.getInt(attr, AUTOFILL_MODE_INHERIT));
                     }
                     break;
-                case R.styleable.View_autoFillHint:
+                case R.styleable.View_autofillHint:
                     if (a.peekValue(attr) != null) {
-                        setAutoFillHint(a.getInt(attr, AUTO_FILL_HINT_NONE));
+                        setAutofillHint(a.getInt(attr, AUTOFILL_HINT_NONE));
                     }
                     break;
                 case R.styleable.View_importantForAutofill:
@@ -6786,14 +6791,14 @@
             mAttachInfo.mKeyDispatchState.reset(this);
         }
 
-        if (isAutoFillable() && isAttachedToWindow()
-                && getResolvedAutoFillMode() == AUTO_FILL_MODE_AUTO) {
-            AutoFillManager afm = getAutoFillManager();
+        if (isAutofillable() && isAttachedToWindow()
+                && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
+            AutofillManager afm = getAutofillManager();
             if (afm != null) {
                 if (gainFocus) {
-                    afm.startAutoFillRequest(this);
+                    afm.startAutofillRequest(this);
                 } else {
-                    afm.stopAutoFillRequest(this);
+                    afm.stopAutofillRequest(this);
                 }
             }
         }
@@ -7238,18 +7243,18 @@
      * fills in all data that can be inferred from the view itself.
      */
     public void onProvideStructure(ViewStructure structure) {
-        onProvideStructureForAssistOrAutoFill(structure, false);
+        onProvideStructureForAssistOrAutofill(structure, false);
     }
 
     /**
-     * Called when assist structure is being retrieved from a view as part of an auto-fill request.
+     * Called when assist structure is being retrieved from a view as part of an autofill request.
      *
-     * <p>This method already provides most of what's needed for auto-fill, but should be overridden
+     * <p>This method already provides most of what's needed for autofill, but should be overridden
      * <ol>
      * <li>The view contents does not include PII (Personally Identifiable Information), so it
      * can call {@link ViewStructure#setSanitized(boolean)} passing {@code true}.
      * <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
-     * {@link ViewStructure#setAutoFillOptions(String[])}, or {@link ViewStructure#setUrl(String)}.
+     * {@link ViewStructure#setAutofillOptions(String[])}, or {@link ViewStructure#setUrl(String)}.
      * </ol>
      *
      * @param structure Fill in with structured view data. The default implementation
@@ -7257,12 +7262,12 @@
      * @param flags optional flags (currently {@code 0}).
      */
     @CallSuper
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        onProvideStructureForAssistOrAutoFill(structure, true);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        onProvideStructureForAssistOrAutofill(structure, true);
     }
 
-    private void onProvideStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutoFill) {
+    private void onProvideStructureForAssistOrAutofill(ViewStructure structure,
+            boolean forAutofill) {
         final int id = mID;
         if (id != NO_ID && !isViewIdGenerated(id)) {
             String pkg, type, entry;
@@ -7279,17 +7284,17 @@
             structure.setId(id, null, null, null);
         }
 
-        if (forAutoFill) {
+        if (forAutofill) {
             final @AutofillType int autofillType = getAutofillType();
-            // Don't need to fill auto-fill info if view does not support it.
-            // For example, only TextViews that are editable support auto-fill
+            // Don't need to fill autofill info if view does not support it.
+            // For example, only TextViews that are editable support autofill
             if (autofillType != AUTOFILL_TYPE_NONE) {
-                // The auto-fill id needs to be unique, but its value doesn't matter, so it's better
+                // The autofill id needs to be unique, but its value doesn't matter, so it's better
                 // to reuse the accessibility id to save space.
-                structure.setAutoFillId(getAccessibilityViewId());
+                structure.setAutofillId(getAccessibilityViewId());
                 structure.setAutofillType(autofillType);
-                structure.setAutoFillHint(getAutoFillHint());
-                structure.setAutoFillValue(getAutoFillValue());
+                structure.setAutofillHint(getAutofillHint());
+                structure.setAutofillValue(getAutofillValue());
             }
         }
 
@@ -7327,6 +7332,9 @@
                 structure.setChecked(true);
             }
         }
+        if (isOpaque()) {
+            structure.setOpaque(true);
+        }
         if (isContextClickable()) {
             structure.setContextClickable(true);
         }
@@ -7343,11 +7351,11 @@
      * optimal implementation providing this data.
      */
     public void onProvideVirtualStructure(ViewStructure structure) {
-        onProvideVirtualStructureForAssistOrAutoFill(structure, false);
+        onProvideVirtualStructureForAssistOrAutofill(structure, false);
     }
 
     /**
-     * Called when assist structure is being retrieved from a view as part of an auto-fill request
+     * Called when assist structure is being retrieved from a view as part of an autofill request
      * to generate additional virtual structure under this view.
      *
      * <p>The default implementation uses {@link #getAccessibilityNodeProvider()} to try to
@@ -7357,27 +7365,27 @@
      * <p>When implementing this method, subclasses must follow the rules below:
      *
      * <ol>
-     * <li>Also implement {@link #autoFillVirtual(int, AutoFillValue)} to auto-fill the virtual
+     * <li>Also implement {@link #autofillVirtual(int, AutofillValue)} to autofill the virtual
      * children.
      * <li>Call
-     * {@link android.view.autofill.AutoFillManager#startAutoFillRequestOnVirtualView} and
-     * {@link android.view.autofill.AutoFillManager#stopAutoFillRequestOnVirtualView(View, int)}
+     * {@link android.view.autofill.AutofillManager#startAutofillRequestOnVirtualView} and
+     * {@link android.view.autofill.AutofillManager#stopAutofillRequestOnVirtualView(View, int)}
      * when the focus inside the view changed.
-     * <li>Call {@link android.view.autofill.AutoFillManager#virtualValueChanged(View, int,
-     * AutoFillValue)} when the value of a child changed.
-     * <li>Call {@link android.view.autofill.AutoFillManager#reset()} when the auto-fill context
+     * <li>Call {@link android.view.autofill.AutofillManager#virtualValueChanged(View, int,
+     * AutofillValue)} when the value of a child changed.
+     * <li>Call {@link android.view.autofill.AutofillManager#reset()} when the autofill context
      * of the view structure changed.
      * </ol>
      *
      * @param structure Fill in with structured view data.
      * @param flags optional flags (currently {@code 0}).
      */
-    public void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags) {
-        onProvideVirtualStructureForAssistOrAutoFill(structure, true);
+    public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
+        onProvideVirtualStructureForAssistOrAutofill(structure, true);
     }
 
-    private void onProvideVirtualStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutoFill) {
+    private void onProvideVirtualStructureForAssistOrAutofill(ViewStructure structure,
+            boolean forAutofill) {
         // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
         // this method should take a boolean with the type of request.
         AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
@@ -7385,7 +7393,7 @@
             AccessibilityNodeInfo info = createAccessibilityNodeInfo();
             structure.setChildCount(1);
             ViewStructure root = structure.newChild(0);
-            populateVirtualStructure(root, provider, info, forAutoFill);
+            populateVirtualStructure(root, provider, info, forAutofill);
             info.recycle();
         }
     }
@@ -7394,13 +7402,13 @@
      * Automatically fills the content of this view with the {@code value}.
      *
      * <p>By default does nothing, but views should override it (and {@link #getAutofillType()},
-     * {@link #getAutoFillValue()}, and {@link #onProvideAutoFillStructure(ViewStructure, int)}
-     * to support the AutoFill Framework.
+     * {@link #getAutofillValue()}, and {@link #onProvideAutofillStructure(ViewStructure, int)}
+     * to support the Autofill Framework.
      *
      * <p>Typically, it is implemented by:
      *
      * <ol>
-     * <li>Calling the proper getter method on {@link AutoFillValue} to fetch the actual value.
+     * <li>Calling the proper getter method on {@link AutofillValue} to fetch the actual value.
      * <li>Passing the actual value to the equivalent setter in the view.
      * <ol>
      *
@@ -7413,76 +7421,56 @@
      * }
      * </pre>
      *
-     * @param value value to be auto-filled.
+     * @param value value to be autofilled.
      */
-    public void autoFill(@SuppressWarnings("unused") AutoFillValue value) {
+    public void autofill(@SuppressWarnings("unused") AutofillValue value) {
     }
 
     /**
      * Automatically fills the content of a virtual view with the {@code value}
      *
-     * <p>See {@link #autoFill(AutoFillValue)} and
-     * {@link #onProvideAutoFillVirtualStructure(ViewStructure, int)} for more info.
+     * <p>See {@link #autofill(AutofillValue)} and
+     * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
      *
-     * @param value value to be auto-filled.
+     * @param value value to be autofilled.
      * @param virtualId id identifying the virtual child inside the custom view.
      */
-    public void autoFillVirtual(@SuppressWarnings("unused") int virtualId,
-            @SuppressWarnings("unused") AutoFillValue value) {
+    public void autofillVirtual(@SuppressWarnings("unused") int virtualId,
+            @SuppressWarnings("unused") AutofillValue value) {
     }
 
     /**
-     * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
-     */
-    @Deprecated
-    @Nullable
-    public final AutoFillType getAutoFillType() {
-        switch (getAutofillType()) {
-            case AUTOFILL_TYPE_TEXT:
-                return AutoFillType.forText();
-            case AUTOFILL_TYPE_TOGGLE:
-                return AutoFillType.forToggle();
-            case AUTOFILL_TYPE_LIST:
-                return AutoFillType.forList();
-            case AUTOFILL_TYPE_DATE:
-                return AutoFillType.forDate();
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Describes the auto-fill type that should be used on calls to
-     * {@link #autoFill(AutoFillValue)} and {@link #autoFillVirtual(int, AutoFillValue)}.
+     * Describes the autofill type that should be used on calls to
+     * {@link #autofill(AutofillValue)} and {@link #autofillVirtual(int, AutofillValue)}.
      *
      * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it (and
-     * {@link #autoFill(AutoFillValue)} to support the AutoFill Framework.
+     * {@link #autofill(AutofillValue)} to support the Autofill Framework.
      */
     public @AutofillType int getAutofillType() {
         return AUTOFILL_TYPE_NONE;
     }
 
     /**
-     * Describes the content of a view so that a auto-fill service can fill in the appropriate data.
+     * Describes the content of a view so that a autofill service can fill in the appropriate data.
      *
      * @return The hint set via the attribute
      *
-     * @attr ref android.R.styleable#View_autoFillHint
+     * @attr ref android.R.styleable#View_autofillHint
      */
     @ViewDebug.ExportedProperty()
-    @AutoFillHint public int getAutoFillHint() {
-        return mAutoFillHint;
+    @AutofillHint public int getAutofillHint() {
+        return mAutofillHint;
     }
 
     /**
-     * Gets the {@link View}'s current auto-fill value.
+     * Gets the {@link View}'s current autofill value.
      *
      * <p>By default returns {@code null}, but views should override it (and
-     * {@link #autoFill(AutoFillValue)}, and {@link #getAutofillType()} to support the AutoFill
+     * {@link #autofill(AutofillValue)}, and {@link #getAutofillType()} to support the Autofill
      * Framework.
      */
     @Nullable
-    public AutoFillValue getAutoFillValue() {
+    public AutofillValue getAutofillValue() {
         return null;
     }
 
@@ -7528,16 +7516,16 @@
      *
      * <p>Generally speaking, a view is important for autofill if:
      * <ol>
-     * <li>The view can-be autofilled by an {@link android.service.autofill.AutoFillService}.
-     * <li>The view contents can help an {@link android.service.autofill.AutoFillService} to
+     * <li>The view can-be autofilled by an {@link android.service.autofill.AutofillService}.
+     * <li>The view contents can help an {@link android.service.autofill.AutofillService} to
      * autofill other views.
      * <ol>
      *
      * <p>For example, view containers should typically return {@code false} for performance reasons
      * (since the important info is provided by their children), but if the container is actually
      * whose children are part of a compound view, it should return {@code true} (and then override
-     * {@link #dispatchProvideAutoFillStructure(ViewStructure, int)} to simply call
-     * {@link #onProvideAutoFillStructure(ViewStructure, int)} so its children are not included in
+     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
+     * {@link #onProvideAutofillStructure(ViewStructure, int)} so its children are not included in
      * the structure). On the other hand, views representing labels or editable fields should
      * typically return {@code true}, but in some cases they could return {@code false} (for
      * example, if they're part of a "Captcha" mechanism).
@@ -7554,9 +7542,9 @@
      *
      * <p>This decision applies just for the view, not its children - if the view children are not
      * important for autofill, the view should override
-     * {@link #dispatchProvideAutoFillStructure(ViewStructure, int)} to simply call
-     * {@link #onProvideAutoFillStructure(ViewStructure, int)} (instead of calling
-     * {@link #dispatchProvideAutoFillStructure(ViewStructure, int)} for each child).
+     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} to simply call
+     * {@link #onProvideAutofillStructure(ViewStructure, int)} (instead of calling
+     * {@link #dispatchProvideAutofillStructure(ViewStructure, int)} for each child).
      *
      * @return whether the view is considered important for autofill.
      *
@@ -7599,16 +7587,16 @@
     }
 
     @Nullable
-    private AutoFillManager getAutoFillManager() {
-        return mContext.getSystemService(AutoFillManager.class);
+    private AutofillManager getAutofillManager() {
+        return mContext.getSystemService(AutofillManager.class);
     }
 
-    private boolean isAutoFillable() {
-        return getAutofillType() != AUTOFILL_TYPE_NONE && !isAutoFillBlocked();
+    private boolean isAutofillable() {
+        return getAutofillType() != AUTOFILL_TYPE_NONE && !isAutofillBlocked();
     }
 
     private void populateVirtualStructure(ViewStructure structure,
-            AccessibilityNodeProvider provider, AccessibilityNodeInfo info, boolean forAutoFill) {
+            AccessibilityNodeProvider provider, AccessibilityNodeInfo info, boolean forAutofill) {
         structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
                 null, null, null);
         Rect rect = structure.getTempRect();
@@ -7646,7 +7634,7 @@
         CharSequence cname = info.getClassName();
         structure.setClassName(cname != null ? cname.toString() : null);
         structure.setContentDescription(info.getContentDescription());
-        if (!forAutoFill && (info.getText() != null || info.getError() != null)) {
+        if (!forAutofill && (info.getText() != null || info.getError() != null)) {
             // TODO(b/33197203) (b/33269702): when sanitized, try to use the Accessibility API to
             // just set sanitized values (like text coming from resource files), rather than not
             // setting it at all.
@@ -7660,7 +7648,7 @@
                 AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
                         AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
                 ViewStructure child = structure.newChild(i);
-                populateVirtualStructure(child, provider, cinfo, forAutoFill);
+                populateVirtualStructure(child, provider, cinfo, forAutofill);
                 cinfo.recycle();
             }
         }
@@ -7672,7 +7660,7 @@
      * {@link #onProvideVirtualStructure}.
      */
     public void dispatchProvideStructure(ViewStructure structure) {
-        dispatchProvideStructureForAssistOrAutoFill(structure, false);
+        dispatchProvideStructureForAssistOrAutofill(structure, false);
     }
 
     /**
@@ -7681,27 +7669,27 @@
      * <p>The structure must be filled according to the request type, which is set in the
      * {@code flags} parameter - see the documentation on each flag for more details.
      *
-     * <p>The default implementation calls {@link #onProvideAutoFillStructure(ViewStructure, int)}
-     * and {@link #onProvideAutoFillVirtualStructure(ViewStructure, int)}.
+     * <p>The default implementation calls {@link #onProvideAutofillStructure(ViewStructure, int)}
+     * and {@link #onProvideAutofillVirtualStructure(ViewStructure, int)}.
      *
      * @param structure Fill in with structured view data.
      * @param flags optional flags (currently {@code 0}).
      */
-    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
-        dispatchProvideStructureForAssistOrAutoFill(structure, true);
+    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
+        dispatchProvideStructureForAssistOrAutofill(structure, true);
     }
 
-    private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutoFill) {
-        boolean blocked = forAutoFill ? isAutoFillBlocked() : isAssistBlocked();
+    private void dispatchProvideStructureForAssistOrAutofill(ViewStructure structure,
+            boolean forAutofill) {
+        boolean blocked = forAutofill ? isAutofillBlocked() : isAssistBlocked();
         if (!blocked) {
-            if (forAutoFill) {
-                // The auto-fill id needs to be unique, but its value doesn't matter,
+            if (forAutofill) {
+                // The autofill id needs to be unique, but its value doesn't matter,
                 // so it's better to reuse the accessibility id to save space.
-                structure.setAutoFillId(getAccessibilityViewId());
+                structure.setAutofillId(getAccessibilityViewId());
                 // NOTE: flags are not currently supported, hence 0
-                onProvideAutoFillStructure(structure, 0);
-                onProvideAutoFillVirtualStructure(structure, 0);
+                onProvideAutofillStructure(structure, 0);
+                onProvideAutofillVirtualStructure(structure, 0);
             } else {
                 onProvideStructure(structure);
                 onProvideVirtualStructure(structure);
@@ -8115,7 +8103,7 @@
      */
     public int getAccessibilityWindowId() {
         return mAttachInfo != null ? mAttachInfo.mAccessibilityWindowId
-                : AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+                : AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
     }
 
     /**
@@ -9082,29 +9070,29 @@
     }
 
     /**
-     * Set auto-fill mode for the view.
+     * Set autofill mode for the view.
      *
-     * @param autoFillMode One of {@link #AUTO_FILL_MODE_INHERIT}, {@link #AUTO_FILL_MODE_AUTO},
-     *                     or {@link #AUTO_FILL_MODE_MANUAL}.
-     * @attr ref android.R.styleable#View_autoFillMode
+     * @param autofillMode One of {@link #AUTOFILL_MODE_INHERIT}, {@link #AUTOFILL_MODE_AUTO},
+     *                     or {@link #AUTOFILL_MODE_MANUAL}.
+     * @attr ref android.R.styleable#View_autofillMode
      */
-    public void setAutoFillMode(@AutoFillMode int autoFillMode) {
-        Preconditions.checkArgumentInRange(autoFillMode, AUTO_FILL_MODE_INHERIT,
-                AUTO_FILL_MODE_MANUAL, "autoFillMode");
+    public void setAutofillMode(@AutofillMode int autofillMode) {
+        Preconditions.checkArgumentInRange(autofillMode, AUTOFILL_MODE_INHERIT,
+                AUTOFILL_MODE_MANUAL, "autofillMode");
 
-        mPrivateFlags3 &= ~PFLAG3_AUTO_FILL_MODE_MASK;
-        mPrivateFlags3 |= autoFillMode << PFLAG3_AUTO_FILL_MODE_SHIFT;
+        mPrivateFlags3 &= ~PFLAG3_AUTOFILL_MODE_MASK;
+        mPrivateFlags3 |= autofillMode << PFLAG3_AUTOFILL_MODE_SHIFT;
     }
 
     /**
-     * Sets the a hint that helps the auto-fill service to select the appropriate data to fill the
+     * Sets the a hint that helps the autofill service to select the appropriate data to fill the
      * view.
      *
-     * @param autoFillHint The auto-fill hint to set
-     * @attr ref android.R.styleable#View_autoFillHint
+     * @param autofillHint The autofill hint to set
+     * @attr ref android.R.styleable#View_autofillHint
      */
-    public void setAutoFillHint(@AutoFillHint int autoFillHint) {
-        mAutoFillHint = autoFillHint;
+    public void setAutofillHint(@AutofillHint int autofillHint) {
+        mAutofillHint = autofillHint;
     }
 
     /**
@@ -9537,19 +9525,19 @@
     /**
      * @hide
      * Indicates whether this view will participate in data collection through
-     * {@link ViewStructure} for auto-fill purposes.
+     * {@link ViewStructure} for autofill purposes.
      *
      * <p>If {@code true}, it will not provide any data for itself or its children.
      * <p>If {@code false}, the normal data collection will be allowed.
      *
-     * @return Returns {@code false} if assist data collection for auto-fill is not blocked,
+     * @return Returns {@code false} if assist data collection for autofill is not blocked,
      * else {@code true}.
      *
      * TODO(b/33197203): update / remove javadoc tags below
      * @see #setAssistBlocked(boolean)
      * @attr ref android.R.styleable#View_assistBlocked
      */
-    public boolean isAutoFillBlocked() {
+    public boolean isAutofillBlocked() {
         return false; // TODO(b/33197203): properly implement it
     }
 
@@ -9711,44 +9699,44 @@
     }
 
     /**
-     * Returns the auto-fill mode for this view.
+     * Returns the autofill mode for this view.
      *
-     * @return One of {@link #AUTO_FILL_MODE_INHERIT}, {@link #AUTO_FILL_MODE_AUTO}, or
-     * {@link #AUTO_FILL_MODE_MANUAL}.
-     * @attr ref android.R.styleable#View_autoFillMode
+     * @return One of {@link #AUTOFILL_MODE_INHERIT}, {@link #AUTOFILL_MODE_AUTO}, or
+     * {@link #AUTOFILL_MODE_MANUAL}.
+     * @attr ref android.R.styleable#View_autofillMode
      */
     @ViewDebug.ExportedProperty(mapping = {
-            @ViewDebug.IntToString(from = AUTO_FILL_MODE_INHERIT, to = "AUTO_FILL_MODE_INHERIT"),
-            @ViewDebug.IntToString(from = AUTO_FILL_MODE_AUTO, to = "AUTO_FILL_MODE_AUTO"),
-            @ViewDebug.IntToString(from = AUTO_FILL_MODE_MANUAL, to = "AUTO_FILL_MODE_MANUAL")
+            @ViewDebug.IntToString(from = AUTOFILL_MODE_INHERIT, to = "AUTOFILL_MODE_INHERIT"),
+            @ViewDebug.IntToString(from = AUTOFILL_MODE_AUTO, to = "AUTOFILL_MODE_AUTO"),
+            @ViewDebug.IntToString(from = AUTOFILL_MODE_MANUAL, to = "AUTOFILL_MODE_MANUAL")
             })
-    @AutoFillMode
-    public int getAutoFillMode() {
-        return (mPrivateFlags3 & PFLAG3_AUTO_FILL_MODE_MASK) >> PFLAG3_AUTO_FILL_MODE_SHIFT;
+    @AutofillMode
+    public int getAutofillMode() {
+        return (mPrivateFlags3 & PFLAG3_AUTOFILL_MODE_MASK) >> PFLAG3_AUTOFILL_MODE_SHIFT;
     }
 
     /**
-     * Returns the resolved auto-fill mode for this view.
+     * Returns the resolved autofill mode for this view.
      *
-     * This is the same as {@link #getAutoFillMode()} but if the mode is
-     * {@link #AUTO_FILL_MODE_INHERIT} the parents auto-fill mode will be returned.
+     * This is the same as {@link #getAutofillMode()} but if the mode is
+     * {@link #AUTOFILL_MODE_INHERIT} the parents autofill mode will be returned.
      *
-     * @return One of {@link #AUTO_FILL_MODE_AUTO}, or {@link #AUTO_FILL_MODE_MANUAL}. If the auto-
-     *         fill mode can not be resolved e.g. {@link #getAutoFillMode()} is
-     *         {@link #AUTO_FILL_MODE_INHERIT} and the {@link View} is detached
-     *         {@link #AUTO_FILL_MODE_AUTO} is returned.
+     * @return One of {@link #AUTOFILL_MODE_AUTO}, or {@link #AUTOFILL_MODE_MANUAL}. If the auto-
+     *         fill mode can not be resolved e.g. {@link #getAutofillMode()} is
+     *         {@link #AUTOFILL_MODE_INHERIT} and the {@link View} is detached
+     *         {@link #AUTOFILL_MODE_AUTO} is returned.
      */
-    public @AutoFillMode int getResolvedAutoFillMode() {
-        @AutoFillMode int autoFillMode = getAutoFillMode();
+    public @AutofillMode int getResolvedAutofillMode() {
+        @AutofillMode int autofillMode = getAutofillMode();
 
-        if (autoFillMode == AUTO_FILL_MODE_INHERIT) {
+        if (autofillMode == AUTOFILL_MODE_INHERIT) {
             if (mParent == null) {
-                return AUTO_FILL_MODE_AUTO;
+                return AUTOFILL_MODE_AUTO;
             } else {
-                return mParent.getResolvedAutoFillMode();
+                return mParent.getResolvedAutofillMode();
             }
         } else {
-            return autoFillMode;
+            return autofillMode;
         }
     }
 
@@ -11904,7 +11892,9 @@
                 if (!mHasPerformedLongPress) {
                     // This is a tap, so remove the longpress check
                     removeLongPressCallback();
-                    return performClick();
+                    if (!event.isCanceled()) {
+                        return performClick();
+                    }
                 }
             }
         }
@@ -16889,10 +16879,10 @@
         }
         needGlobalAttributesUpdate(false);
 
-        if (isAutoFillable() && isFocused() && getResolvedAutoFillMode() == AUTO_FILL_MODE_AUTO) {
-            AutoFillManager afm = getAutoFillManager();
+        if (isAutofillable() && isFocused() && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
+            AutofillManager afm = getAutofillManager();
             if (afm != null) {
-                afm.startAutoFillRequest(this);
+                afm.startAutofillRequest(this);
             }
         }
     }
@@ -16942,10 +16932,10 @@
             mOverlay.getOverlayView().dispatchDetachedFromWindow();
         }
 
-        if (isAutoFillable() && isFocused() && getResolvedAutoFillMode() == AUTO_FILL_MODE_AUTO) {
-            AutoFillManager afm = getAutoFillManager();
+        if (isAutofillable() && isFocused() && getResolvedAutofillMode() == AUTOFILL_MODE_AUTO) {
+            AutofillManager afm = getAutofillManager();
             if (afm != null) {
-                afm.stopAutoFillRequest(this);
+                afm.stopAutofillRequest(this);
             }
         }
     }
@@ -24668,7 +24658,7 @@
         /**
          * The id of the window for accessibility purposes.
          */
-        int mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+        int mAccessibilityWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
 
         /**
          * Flags related to accessibility processing.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 214249f..9fa9985e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3337,8 +3337,8 @@
      * default {@link View} implementation.
      */
     @Override
-    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.dispatchProvideAutoFillStructure(structure, flags);
+    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.dispatchProvideAutofillStructure(structure, flags);
         dispatchProvideStructureForAssistOrAutoFill(structure, true);
     }
 
@@ -3363,8 +3363,8 @@
     }
 
     private void dispatchProvideStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutoFill) {
-        boolean blocked = forAutoFill ? isAutoFillBlocked() : isAssistBlocked();
+            boolean forAutofill) {
+        boolean blocked = forAutofill ? isAutofillBlocked() : isAssistBlocked();
         if (blocked || structure.getChildCount() != 0) {
             return;
         }
@@ -3372,7 +3372,7 @@
         final ArrayList<View> childrenList;
         final int childrenCount;
 
-        if (forAutoFill) {
+        if (forAutofill) {
             childrenArray = null;
             // TODO(b/33197203): the current algorithm allocates a new list for each children that
             // is a view group; ideally, we should use mAttachInfo.mTempArrayList instead, but that
@@ -3432,7 +3432,7 @@
                             preorderedList = new ArrayList<>(childrenCount);
                             for (int j = 0; j < childrenCount; j++) {
                                 final int index = permutation[j];
-                                final View child = forAutoFill
+                                final View child = forAutofill
                                         ? childrenList.get(index)
                                         : childrenArray[index];
                                 preorderedList.add(child);
@@ -3443,15 +3443,15 @@
                     }
                 }
 
-                final View child = forAutoFill
+                final View child = forAutofill
                         ? getAndVerifyPreorderedView(preorderedList, childrenList, childIndex)
                         : getAndVerifyPreorderedView(preorderedList, childrenArray, childIndex);
                 final ViewStructure cstructure = structure.newChild(i);
 
                 // Must explicitly check which recursive method to call.
-                if (forAutoFill) {
+                if (forAutofill) {
                     // NOTE: flags are not currently supported, hence 0
-                    child.dispatchProvideAutoFillStructure(cstructure, 0);
+                    child.dispatchProvideAutofillStructure(cstructure, 0);
                 } else {
                     child.dispatchProvideStructure(cstructure);
                 }
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 1467b69..d5aab48 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -661,15 +661,15 @@
     public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments);
 
     /**
-     * Return the resolved auto-fill mode.
+     * Return the resolved autofill mode.
      *
-     * @return One of {@link View#AUTO_FILL_MODE_AUTO}, {@link View#AUTO_FILL_MODE_MANUAL} if the
-     *         auto-fill mode can be resolved. If the auto-fill mode cannot be resolved
-     *         {@link View#AUTO_FILL_MODE_AUTO}.
+     * @return One of {@link View#AUTOFILL_MODE_AUTO}, {@link View#AUTOFILL_MODE_MANUAL} if the
+     *         autofill mode can be resolved. If the autofill mode cannot be resolved
+     *         {@link View#AUTOFILL_MODE_AUTO}.
      *
-     * @see View#getResolvedAutoFillMode()
+     * @see View#getResolvedAutofillMode()
      */
-    default @View.AutoFillMode int getResolvedAutoFillMode() {
-        return View.AUTO_FILL_MODE_AUTO;
+    default @View.AutofillMode int getResolvedAutofillMode() {
+        return View.AUTOFILL_MODE_AUTO;
     }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 20d960f..580888c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -82,6 +82,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import android.view.animation.AccelerateDecelerateInterpolator;
@@ -2632,6 +2633,14 @@
         }
     }
 
+    private void onDrawFinished() {
+        try {
+            mWindowSession.finishDrawing(mWindow);
+        } catch (RemoteException e) {
+            // Have fun!
+        }
+    }
+
     private void performDraw() {
         if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
             return;
@@ -2682,7 +2691,7 @@
             }
 
             if (mSurfaceHolder != null && mSurface.isValid()) {
-                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(mWindowSession, mWindow);
+                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished);
                 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
 
                 sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
@@ -6872,12 +6881,7 @@
                         final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
                                 sourceNodeId);
                         final AccessibilityNodeInfo node;
-                        if (virtualNodeId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-                            node = provider.createAccessibilityNodeInfo(
-                                    AccessibilityNodeProvider.HOST_VIEW_ID);
-                        } else {
-                            node = provider.createAccessibilityNodeInfo(virtualNodeId);
-                        }
+                        node = provider.createAccessibilityNodeInfo(virtualNodeId);
                         setAccessibilityFocus(source, node);
                     }
                 }
@@ -6963,10 +6967,6 @@
 
         final long focusedSourceNodeId = mAccessibilityFocusedVirtualView.getSourceNodeId();
         int focusedChildId = AccessibilityNodeInfo.getVirtualDescendantId(focusedSourceNodeId);
-        if (focusedChildId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
-            // TODO: Should we clear the focused virtual view?
-            focusedChildId = AccessibilityNodeProvider.HOST_VIEW_ID;
-        }
 
         // Refresh the node for the focused virtual view.
         final Rect oldBounds = mTempRect;
@@ -7487,8 +7487,8 @@
         }
 
         public void ensureConnection() {
-            final boolean registered =
-                    mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+            final boolean registered = mAttachInfo.mAccessibilityWindowId
+                    != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
             if (!registered) {
                 mAttachInfo.mAccessibilityWindowId =
                         mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
@@ -7497,10 +7497,10 @@
         }
 
         public void ensureNoConnection() {
-            final boolean registered =
-                mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+            final boolean registered = mAttachInfo.mAccessibilityWindowId
+                    != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
             if (registered) {
-                mAttachInfo.mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
+                mAttachInfo.mAccessibilityWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
                 mAccessibilityManager.removeAccessibilityInteractionConnection(mWindow);
             }
         }
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index c7c2bb8..bccaca2 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -19,14 +19,13 @@
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillType;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 /**
  * Container for storing additional per-view data generated by {@link View#onProvideStructure
- * View.onProvideStructure} and {@link View#onProvideAutoFillStructure
- * View.onProvideAutoFillStructure}.
+ * View.onProvideStructure} and {@link View#onProvideAutofillStructure
+ * View.onProvideAutofillStructure}.
  */
 public abstract class ViewStructure {
 
@@ -147,6 +146,11 @@
     public abstract void setActivated(boolean state);
 
     /**
+     * Set the opaque state of this view, as per {@link View#isOpaque View.isOpaque()}.
+     */
+    public abstract void setOpaque(boolean opaque);
+
+    /**
      * Set the class name of the view, as per
      * {@link View#getAccessibilityClassName View.getAccessibilityClassName()}.
      */
@@ -264,19 +268,19 @@
     public abstract ViewStructure newChild(int index);
 
     /**
-     * Create a new child {@link ViewStructure} in this view for auto-fill purposes.
+     * Create a new child {@link ViewStructure} in this view for autofill purposes.
      *
      * @param index the index (in the list of children) to put the new child at (see
      *            {@link #addChildCount(int)} and {@link #setChildCount(int)}.
      * @param virtualId an opaque ID to the Android System (although it could be meaningful to the
      *            {@link View} creating the {@link ViewStructure}), but it's the same id used on
-     *            {@link View#autoFillVirtual(int, AutoFillValue)}.
+     *            {@link View#autofillVirtual(int, AutofillValue)}.
      * @param flags currently {@code 0}.
      *
      * @return Returns an fresh {@link ViewStructure} ready to be filled in.
      */
     // TODO(b/33197203, b/33802548): add CTS/unit test
-    public abstract ViewStructure newChildForAutoFill(int index, int virtualId, int flags);
+    public abstract ViewStructure newChildForAutofill(int index, int virtualId, int flags);
 
     /**
      * Like {@link #newChild}, but allows the caller to asynchronously populate the returned
@@ -289,7 +293,7 @@
     public abstract ViewStructure asyncNewChild(int index);
 
     /**
-     * Like {@link #newChildForAutoFill(int, int, int)}, but allows the caller to asynchronously
+     * Like {@link #newChildForAutofill(int, int, int)}, but allows the caller to asynchronously
      * populate the returned child.
      *
      * <p>It can transfer the returned {@link ViewStructure} to another thread for it to build its
@@ -302,19 +306,13 @@
      *            {@link #addChildCount(int)} and {@link #setChildCount(int)}.
      * @param virtualId an opaque ID to the Android System (although it could be meaningful to the
      *            {@link View} creating the {@link ViewStructure}), but it's the same id used on
-     *            {@link View#autoFillVirtual(int, AutoFillValue)}.
+     *            {@link View#autofillVirtual(int, AutofillValue)}.
      * @param flags currently {@code 0}.
      *
      * @return Returns an fresh {@link ViewStructure} ready to be filled in.
      */
     // TODO(b/33197203, b/33802548): add CTS/unit test
-    public abstract ViewStructure asyncNewChildForAutoFill(int index, int virtualId, int flags);
-
-    /**
-     * @deprecated TODO(b/35956626): remove once clients use setAutoFilltype()
-     */
-    @Deprecated
-    public abstract void setAutoFillType(AutoFillType info);
+    public abstract ViewStructure asyncNewChildForAutofill(int index, int virtualId, int flags);
 
     /**
      * Sets the {@link View#getAutofillType()} that can be used to autofill this node.
@@ -322,26 +320,23 @@
     public abstract void setAutofillType(@View.AutofillType int type);
 
     /**
-     * Sets the a hint that helps the auto-fill service to select the appropriate data to fill the
+     * Sets the a hint that helps the autofill service to select the appropriate data to fill the
      * view.
      */
-    // TODO(b/35364993): add CTS/unit test
-    public abstract void setAutoFillHint(@View.AutoFillHint int hint);
+    public abstract void setAutofillHint(@View.AutofillHint int hint);
 
     /**
-     * Sets the {@link AutoFillValue} representing the current value of this node.
+     * Sets the {@link AutofillValue} representing the current value of this node.
      */
-    // TODO(b/33197203, b/33802548): add CTS/unit test
-    public abstract void setAutoFillValue(AutoFillValue value);
+    public abstract void setAutofillValue(AutofillValue value);
 
     /**
-     * Sets the options that can be used to auto-fill this node.
+     * Sets the options that can be used to autofill this node.
      *
-     * <p>Typically used by nodes whose {@link AutoFillType} is a list to indicate the meaning of
-     * each possible value in the list.
+     * <p>Typically used by nodes whose {@link View#getAutofillType()} is a list to indicate the
+     * meaning of each possible value in the list.
      */
-    // TODO(b/33197203, b/33802548): add CTS/unit test
-    public abstract void setAutoFillOptions(String[] options);
+    public abstract void setAutofillOptions(String[] options);
 
     /**
      * Sets the {@link android.text.InputType} bits of this node.
@@ -352,7 +347,7 @@
 
     /**
      * Marks this node as sanitized so its content are sent on {@link
-     * android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
+     * android.service.autofill.AutofillService#onFillRequest(android.app.assist.AssistStructure,
      * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)}.
      *
      * <p>Only nodes that does not have PII (Personally Identifiable Information - sensitive data
@@ -360,7 +355,7 @@
      * as sanitized; a good rule of thumb is to mark as sanitized nodes whose value were statically
      * set from resources.
      *
-     * <p>Should only be set when the node is used for AutoFill purposes - it will be ignored
+     * <p>Should only be set when the node is used for autofill purposes - it will be ignored
      * when used for Assist.
      */
     public abstract void setSanitized(boolean sanitized);
@@ -375,10 +370,10 @@
     public abstract Rect getTempRect();
 
     /** @hide */
-    public abstract void setAutoFillId(int viewId);
+    public abstract void setAutofillId(int viewId);
 
     /** @hide */
-    public abstract AutoFillId getAutoFillId();
+    public abstract AutofillId getAutofillId();
 
     /**
      * Sets the URL represented by this node.
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 737e4607..95a6394 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -46,6 +46,7 @@
     public List<IBinder> childTokens;
     public CharSequence title;
     public int accessibilityIdOfAnchor = View.NO_ID;
+    public boolean inPictureInPicture;
 
     private WindowInfo() {
         /* do nothing - hide constructor */
@@ -69,6 +70,7 @@
         window.boundsInScreen.set(other.boundsInScreen);
         window.title = other.title;
         window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
+        window.inPictureInPicture = other.inPictureInPicture;
 
         if (other.childTokens != null && !other.childTokens.isEmpty()) {
             if (window.childTokens == null) {
@@ -101,6 +103,7 @@
         boundsInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(title);
         parcel.writeInt(accessibilityIdOfAnchor);
+        parcel.writeInt(inPictureInPicture ? 1 : 0);
 
         if (childTokens != null && !childTokens.isEmpty()) {
             parcel.writeInt(1);
@@ -136,6 +139,7 @@
         boundsInScreen.readFromParcel(parcel);
         title = parcel.readCharSequence();
         accessibilityIdOfAnchor = parcel.readInt();
+        inPictureInPicture = (parcel.readInt() == 1);
 
         final boolean hasChildren = (parcel.readInt() == 1);
         if (hasChildren) {
@@ -156,6 +160,7 @@
         if (childTokens != null) {
             childTokens.clear();
         }
+        inPictureInPicture = false;
     }
 
     public static final Parcelable.Creator<WindowInfo> CREATOR =
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 828583c..19213ca 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -158,7 +158,7 @@
      */
     public AccessibilityNodeInfo getRootInActiveWindow(int connectionId) {
         return findAccessibilityNodeInfoByAccessibilityId(connectionId,
-                AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
+                AccessibilityWindowInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
                 false, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS, null);
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 45302b6..fe888ec 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -21,6 +21,7 @@
 import android.Manifest;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -822,6 +823,31 @@
         }
     }
 
+    /**
+     * Set an IAccessibilityInteractionConnection to replace the actions of a picture-in-picture
+     * window. Intended for use by the System UI only.
+     *
+     * @param connection The connection to handle the actions. Set to {@code null} to avoid
+     * affecting the actions.
+     *
+     * @hide
+     */
+    public void setPictureInPictureActionReplacingConnection(
+            @Nullable IAccessibilityInteractionConnection connection) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+        }
+        try {
+            service.setPictureInPictureActionReplacingConnection(connection);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error setting picture in picture action replacement", re);
+        }
+    }
+
     private IAccessibilityManager getServiceLocked() {
         if (mService == null) {
             tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 8094fa6..50f17e0 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -85,17 +85,19 @@
     /** @hide */
     public static final int UNDEFINED_SELECTION_INDEX = -1;
 
+    /* Special IDs for node source IDs */
     /** @hide */
     public static final int UNDEFINED_ITEM_ID = Integer.MAX_VALUE;
 
     /** @hide */
-    public static final long ROOT_NODE_ID = makeNodeId(UNDEFINED_ITEM_ID, UNDEFINED_ITEM_ID);
+    public static final int ROOT_ITEM_ID = Integer.MAX_VALUE - 1;
 
     /** @hide */
-    public static final int ACTIVE_WINDOW_ID = UNDEFINED_ITEM_ID;
+    public static final long UNDEFINED_NODE_ID = makeNodeId(UNDEFINED_ITEM_ID, UNDEFINED_ITEM_ID);
 
     /** @hide */
-    public static final int ANY_WINDOW_ID = -2;
+    public static final long ROOT_NODE_ID = makeNodeId(ROOT_ITEM_ID,
+            AccessibilityNodeProvider.HOST_VIEW_ID);
 
     /** @hide */
     public static final int FLAG_PREFETCH_PREDECESSORS = 0x00000001;
@@ -474,6 +476,34 @@
             "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
 
     /**
+     * Argument for specifying the x coordinate to which to move a window.
+     * <p>
+     * <strong>Type:</strong> int<br>
+     * <strong>Actions:</strong>
+     * <ul>
+     *     <li>{@link AccessibilityAction#ACTION_MOVE_WINDOW}</li>
+     * </ul>
+     *
+     * @see AccessibilityAction#ACTION_MOVE_WINDOW
+     */
+    public static final String ACTION_ARGUMENT_MOVE_WINDOW_X =
+            "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_X";
+
+    /**
+     * Argument for specifying the y coordinate to which to move a window.
+     * <p>
+     * <strong>Type:</strong> int<br>
+     * <strong>Actions:</strong>
+     * <ul>
+     *     <li>{@link AccessibilityAction#ACTION_MOVE_WINDOW}</li>
+     * </ul>
+     *
+     * @see AccessibilityAction#ACTION_MOVE_WINDOW
+     */
+    public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y =
+            "android.view.accessibility.action.ARGUMENT_MOVE_WINDOW_Y";
+
+    /**
      * Argument to pass the {@link AccessibilityClickableSpan}.
      * For use with R.id.accessibilityActionClickOnClickableSpan
      * @hide
@@ -654,13 +684,6 @@
      * @hide
      */
     public static long makeNodeId(int accessibilityViewId, int virtualDescendantId) {
-        // We changed the value for undefined node to positive due to wrong
-        // global id composition (two 32-bin ints into one 64-bit long) but
-        // the value used for the host node provider view has id -1 so we
-        // remap it here.
-        if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
-            virtualDescendantId = UNDEFINED_ITEM_ID;
-        }
         return (((long) virtualDescendantId) << VIRTUAL_DESCENDANT_ID_SHIFT) | accessibilityViewId;
     }
 
@@ -673,12 +696,12 @@
 
     // Data.
     private int mWindowId = UNDEFINED_ITEM_ID;
-    private long mSourceNodeId = ROOT_NODE_ID;
-    private long mParentNodeId = ROOT_NODE_ID;
-    private long mLabelForId = ROOT_NODE_ID;
-    private long mLabeledById = ROOT_NODE_ID;
-    private long mTraversalBefore = ROOT_NODE_ID;
-    private long mTraversalAfter = ROOT_NODE_ID;
+    private long mSourceNodeId = UNDEFINED_NODE_ID;
+    private long mParentNodeId = UNDEFINED_NODE_ID;
+    private long mLabelForId = UNDEFINED_NODE_ID;
+    private long mLabeledById = UNDEFINED_NODE_ID;
+    private long mTraversalBefore = UNDEFINED_NODE_ID;
+    private long mTraversalAfter = UNDEFINED_NODE_ID;
 
     private int mBooleanProperties;
     private final Rect mBoundsInParent = new Rect();
@@ -733,7 +756,7 @@
      * @param source The info source.
      */
     public void setSource(View source) {
-        setSource(source, UNDEFINED_ITEM_ID);
+        setSource(source, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -950,7 +973,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void addChild(View child) {
-        addChildInternal(child, UNDEFINED_ITEM_ID, true);
+        addChildInternal(child, AccessibilityNodeProvider.HOST_VIEW_ID, true);
     }
 
     /**
@@ -960,7 +983,7 @@
      * @hide
      */
     public void addChildUnchecked(View child) {
-        addChildInternal(child, UNDEFINED_ITEM_ID, false);
+        addChildInternal(child, AccessibilityNodeProvider.HOST_VIEW_ID, false);
     }
 
     /**
@@ -978,7 +1001,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public boolean removeChild(View child) {
-        return removeChild(child, UNDEFINED_ITEM_ID);
+        return removeChild(child, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -1205,6 +1228,17 @@
     }
 
     /**
+     * Removes all actions.
+     *
+     * @hide
+     */
+    public void removeAllActions() {
+        if (mActions != null) {
+            mActions.clear();
+        }
+    }
+
+    /**
      * Gets the node before which this one is visited during traversal. A screen-reader
      * must visit the content of this node before the content of the one it precedes.
      *
@@ -1233,7 +1267,7 @@
      * @see #getTraversalBefore()
      */
     public void setTraversalBefore(View view) {
-        setTraversalBefore(view, UNDEFINED_ITEM_ID);
+        setTraversalBefore(view, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -1294,7 +1328,7 @@
      * @see #getTraversalAfter()
      */
     public void setTraversalAfter(View view) {
-        setTraversalAfter(view, UNDEFINED_ITEM_ID);
+        setTraversalAfter(view, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -1572,7 +1606,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setParent(View parent) {
-        setParent(parent, UNDEFINED_ITEM_ID);
+        setParent(parent, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -2533,7 +2567,7 @@
      * @param labeled The view for which this info serves as a label.
      */
     public void setLabelFor(View labeled) {
-        setLabelFor(labeled, UNDEFINED_ITEM_ID);
+        setLabelFor(labeled, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -2585,7 +2619,7 @@
      * @param label The view that labels this node's source.
      */
     public void setLabeledBy(View label) {
-        setLabeledBy(label, UNDEFINED_ITEM_ID);
+        setLabeledBy(label, AccessibilityNodeProvider.HOST_VIEW_ID);
     }
 
     /**
@@ -2815,6 +2849,20 @@
     }
 
     /**
+     * Sets the id of the source node.
+     *
+     * @param sourceId The id.
+     * @param windowId The window id.
+     *
+     * @hide
+     */
+    public void setSourceNodeId(long sourceId, int windowId) {
+        enforceNotSealed();
+        mSourceNodeId = sourceId;
+        mWindowId = windowId;
+    }
+
+    /**
      * Gets the id of the source node.
      *
      * @return The id.
@@ -3299,12 +3347,12 @@
      */
     private void clear() {
         mSealed = false;
-        mSourceNodeId = ROOT_NODE_ID;
-        mParentNodeId = ROOT_NODE_ID;
-        mLabelForId = ROOT_NODE_ID;
-        mLabeledById = ROOT_NODE_ID;
-        mTraversalBefore = ROOT_NODE_ID;
-        mTraversalAfter = ROOT_NODE_ID;
+        mSourceNodeId = UNDEFINED_NODE_ID;
+        mParentNodeId = UNDEFINED_NODE_ID;
+        mLabelForId = UNDEFINED_NODE_ID;
+        mLabeledById = UNDEFINED_NODE_ID;
+        mTraversalBefore = UNDEFINED_NODE_ID;
+        mTraversalAfter = UNDEFINED_NODE_ID;
         mWindowId = UNDEFINED_ITEM_ID;
         mConnectionId = UNDEFINED_CONNECTION_ID;
         mMaxTextLength = -1;
@@ -3324,9 +3372,7 @@
         mError = null;
         mContentDescription = null;
         mViewIdResourceName = null;
-        if (mActions != null) {
-            mActions.clear();
-        }
+        removeAllActions();
         mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
         mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
         mInputType = InputType.TYPE_NULL;
@@ -3975,6 +4021,16 @@
         public static final AccessibilityAction ACTION_SET_PROGRESS =
                 new AccessibilityAction(R.id.accessibilityActionSetProgress, null);
 
+        /**
+         * Action to move a window to a new location.
+         * <p>
+         * <strong>Arguments:</strong>
+         * {@link AccessibilityNodeInfo#ACTION_ARGUMENT_MOVE_WINDOW_X}
+         * {@link AccessibilityNodeInfo#ACTION_ARGUMENT_MOVE_WINDOW_Y}
+         */
+        public static final AccessibilityAction ACTION_MOVE_WINDOW =
+                new AccessibilityAction(R.id.accessibilityActionMoveWindow, null);
+
         private static final ArraySet<AccessibilityAction> sStandardActions = new ArraySet<>();
         static {
             sStandardActions.add(ACTION_FOCUS);
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index f2979bb..3f1fece 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -91,7 +91,7 @@
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
     AccessibilityNodeInfo mSourceNode;
-    int mSourceWindowId = UNDEFINED;
+    int mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
 
     CharSequence mClassName;
     CharSequence mContentDescription;
@@ -136,11 +136,12 @@
     public void setSource(View root, int virtualDescendantId) {
         enforceNotSealed();
         boolean important = true;
-        mSourceWindowId = UNDEFINED;
+        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
         clearSourceNode();
         if (root != null) {
-            if (virtualDescendantId == UNDEFINED ||
-                    virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+            if (virtualDescendantId == View.NO_ID
+                    || virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID
+                    || virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
                 important = root.isImportantForAccessibility();
                 mSourceNode = root.createAccessibilityNodeInfo();
             } else {
@@ -156,6 +157,25 @@
     }
 
     /**
+     * Set the source directly to an AccessibilityNodeInfo rather than indirectly via a View
+     *
+     * @param info The source
+     *
+     * @hide
+     */
+    public void setSource(AccessibilityNodeInfo info) {
+        enforceNotSealed();
+        clearSourceNode();
+        mSourceWindowId = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
+        if (info != null) {
+            mSourceNode = AccessibilityNodeInfo.obtain(info);
+            setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY,
+                    mSourceNode.isImportantForAccessibility());
+            mSourceWindowId = info.getWindowId();
+        }
+    }
+
+    /**
      * Gets the {@link AccessibilityNodeInfo} of the event source.
      * <p>
      *   <strong>Note:</strong> It is a client responsibility to recycle the received info
@@ -833,6 +853,7 @@
             mSourceNode.recycle();
             mSourceNode = null;
         }
+
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index c390406..2a7537b 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -74,7 +74,15 @@
      */
     public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5;
 
-    private static final int UNDEFINED = -1;
+    /* Special values for window IDs */
+    /** @hide */
+    public static final int ACTIVE_WINDOW_ID = Integer.MAX_VALUE;
+    /** @hide */
+    public static final int UNDEFINED_WINDOW_ID = -1;
+    /** @hide */
+    public static final int ANY_WINDOW_ID = -2;
+    /** @hide */
+    public static final int PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID = -3;
 
     private static final int BOOLEAN_PROPERTY_ACTIVE = 1 << 0;
     private static final int BOOLEAN_PROPERTY_FOCUSED = 1 << 1;
@@ -87,17 +95,18 @@
     private static AtomicInteger sNumInstancesInUse;
 
     // Data.
-    private int mType = UNDEFINED;
-    private int mLayer = UNDEFINED;
+    private int mType = UNDEFINED_WINDOW_ID;
+    private int mLayer = UNDEFINED_WINDOW_ID;
     private int mBooleanProperties;
-    private int mId = UNDEFINED;
-    private int mParentId = UNDEFINED;
+    private int mId = UNDEFINED_WINDOW_ID;
+    private int mParentId = UNDEFINED_WINDOW_ID;
     private final Rect mBoundsInScreen = new Rect();
     private LongArray mChildIds;
     private CharSequence mTitle;
-    private int mAnchorId = UNDEFINED;
+    private int mAnchorId = UNDEFINED_WINDOW_ID;
+    private boolean mInPictureInPicture;
 
-    private int mConnectionId = UNDEFINED;
+    private int mConnectionId = UNDEFINED_WINDOW_ID;
 
     private AccessibilityWindowInfo() {
         /* do nothing - hide constructor */
@@ -177,7 +186,7 @@
      * @return The root node.
      */
     public AccessibilityNodeInfo getRoot() {
-        if (mConnectionId == UNDEFINED) {
+        if (mConnectionId == UNDEFINED_WINDOW_ID) {
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -203,7 +212,8 @@
      * @return The anchor node, or {@code null} if none exists.
      */
     public AccessibilityNodeInfo getAnchor() {
-        if ((mConnectionId == UNDEFINED) || (mAnchorId == UNDEFINED) || (mParentId == UNDEFINED)) {
+        if ((mConnectionId == UNDEFINED_WINDOW_ID) || (mAnchorId == UNDEFINED_WINDOW_ID)
+                || (mParentId == UNDEFINED_WINDOW_ID)) {
             return null;
         }
 
@@ -212,13 +222,27 @@
                 mParentId, mAnchorId, true, 0, null);
     }
 
+    /** @hide */
+    public void setPictureInPicture(boolean pictureInPicture) {
+        mInPictureInPicture = pictureInPicture;
+    }
+
+    /**
+     * Check if the window is in picture-in-picture mode.
+     *
+     * @return {@code true} if the window is in picture-in-picture mode, {@code false} otherwise.
+     */
+    public boolean inPictureInPicture() {
+        return mInPictureInPicture;
+    }
+
     /**
      * Gets the parent window.
      *
      * @return The parent window, or {@code null} if none exists.
      */
     public AccessibilityWindowInfo getParent() {
-        if (mConnectionId == UNDEFINED || mParentId == UNDEFINED) {
+        if (mConnectionId == UNDEFINED_WINDOW_ID || mParentId == UNDEFINED_WINDOW_ID) {
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -371,7 +395,7 @@
         if (mChildIds == null) {
             throw new IndexOutOfBoundsException();
         }
-        if (mConnectionId == UNDEFINED) {
+        if (mConnectionId == UNDEFINED_WINDOW_ID) {
             return null;
         }
         final int childId = (int) mChildIds.get(index);
@@ -429,6 +453,7 @@
         infoClone.mBoundsInScreen.set(info.mBoundsInScreen);
         infoClone.mTitle = info.mTitle;
         infoClone.mAnchorId = info.mAnchorId;
+        infoClone.mInPictureInPicture = info.mInPictureInPicture;
 
         if (info.mChildIds != null && info.mChildIds.size() > 0) {
             if (infoClone.mChildIds == null) {
@@ -486,6 +511,7 @@
         mBoundsInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(mTitle);
         parcel.writeInt(mAnchorId);
+        parcel.writeInt(mInPictureInPicture ? 1 : 0);
 
         final LongArray childIds = mChildIds;
         if (childIds == null) {
@@ -510,6 +536,7 @@
         mBoundsInScreen.readFromParcel(parcel);
         mTitle = parcel.readCharSequence();
         mAnchorId = parcel.readInt();
+        mInPictureInPicture = parcel.readInt() == 1;
 
         final int childCount = parcel.readInt();
         if (childCount > 0) {
@@ -556,6 +583,7 @@
         builder.append(", bounds=").append(mBoundsInScreen);
         builder.append(", focused=").append(isFocused());
         builder.append(", active=").append(isActive());
+        builder.append(", pictureInPicture=").append(inPictureInPicture());
         if (DEBUG) {
             builder.append(", parent=").append(mParentId);
             builder.append(", children=[");
@@ -572,8 +600,8 @@
             }
             builder.append(']');
         } else {
-            builder.append(", hasParent=").append(mParentId != UNDEFINED);
-            builder.append(", isAnchored=").append(mAnchorId != UNDEFINED);
+            builder.append(", hasParent=").append(mParentId != UNDEFINED_WINDOW_ID);
+            builder.append(", isAnchored=").append(mAnchorId != UNDEFINED_WINDOW_ID);
             builder.append(", hasChildren=").append(mChildIds != null
                     && mChildIds.size() > 0);
         }
@@ -585,17 +613,18 @@
      * Clears the internal state.
      */
     private void clear() {
-        mType = UNDEFINED;
-        mLayer = UNDEFINED;
+        mType = UNDEFINED_WINDOW_ID;
+        mLayer = UNDEFINED_WINDOW_ID;
         mBooleanProperties = 0;
-        mId = UNDEFINED;
-        mParentId = UNDEFINED;
+        mId = UNDEFINED_WINDOW_ID;
+        mParentId = UNDEFINED_WINDOW_ID;
         mBoundsInScreen.setEmpty();
         if (mChildIds != null) {
             mChildIds.clear();
         }
-        mConnectionId = UNDEFINED;
-        mAnchorId = UNDEFINED;
+        mConnectionId = UNDEFINED_WINDOW_ID;
+        mAnchorId = UNDEFINED_WINDOW_ID;
+        mInPictureInPicture = false;
         mTitle = null;
     }
 
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 8fde47a..157980f 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -45,10 +45,13 @@
     List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId);
 
     int addAccessibilityInteractionConnection(IWindow windowToken,
-        in IAccessibilityInteractionConnection connection, int userId);
+            in IAccessibilityInteractionConnection connection, int userId);
 
     void removeAccessibilityInteractionConnection(IWindow windowToken);
 
+    void setPictureInPictureActionReplacingConnection(
+            in IAccessibilityInteractionConnection connection);
+
     void registerUiTestAutomationService(IBinder owner, IAccessibilityServiceClient client,
         in AccessibilityServiceInfo info, int flags);
 
diff --git a/core/java/android/view/autofill/AutoFillId.aidl b/core/java/android/view/autofill/AutoFillId.aidl
index 56f0338..fc57ce7 100644
--- a/core/java/android/view/autofill/AutoFillId.aidl
+++ b/core/java/android/view/autofill/AutoFillId.aidl
@@ -16,4 +16,5 @@
 
 package android.view.autofill;
 
+//  @deprecated TODO(b/35956626): remove once clients use AutofillId
 parcelable AutoFillId;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/AutoFillId.java b/core/java/android/view/autofill/AutoFillId.java
index 38dc404..081fb02 100644
--- a/core/java/android/view/autofill/AutoFillId.java
+++ b/core/java/android/view/autofill/AutoFillId.java
@@ -15,67 +15,26 @@
  */
 package android.view.autofill;
 
-import static android.view.autofill.Helper.DEBUG;
-
 import android.os.Parcel;
 import android.os.Parcelable;
 
 /**
- * A unique identifier for an auto-fill node inside an {@link android.app.Activity}.
+ * @hide
+ * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
  */
+@Deprecated
 public final class AutoFillId implements Parcelable {
 
-    private int mViewId;
-    private boolean mVirtual;
-    private int mVirtualId;
-
-    // TODO(b/33197203): use factory and cache values, since they're immutable
-    /** @hide */
-    public AutoFillId(int id) {
-        mVirtual = false;
-        mViewId = id;
-    }
+    private final AutofillId mRealId;
 
     /** @hide */
-    public AutoFillId(AutoFillId parent, int virtualChildId) {
-        mVirtual = true;
-        mViewId = parent.mViewId;
-        mVirtualId = virtualChildId;
+    public AutoFillId(AutofillId daRealId) {
+        this.mRealId = daRealId;
     }
 
-    /** @hide */
-    public AutoFillId(int parentId, int virtualChildId) {
-        mVirtual = true;
-        mViewId = parentId;
-        mVirtualId = virtualChildId;
-    }
-
-    /** @hide */
-    public int getViewId() {
-        return mViewId;
-    }
-
-    /** @hide */
-    public int getVirtualChildId() {
-        return mVirtualId;
-    }
-
-    /** @hide */
-    public boolean isVirtual() {
-        return mVirtual;
-    }
-
-    /////////////////////////////////
-    //  Object "contract" methods. //
-    /////////////////////////////////
-
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mViewId;
-        result = prime * result + mVirtualId;
-        return result;
+        return mRealId.hashCode();
     }
 
     @Override
@@ -84,20 +43,7 @@
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         final AutoFillId other = (AutoFillId) obj;
-        if (mViewId != other.mViewId) return false;
-        if (mVirtualId != other.mVirtualId) return false;
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        final StringBuilder builder = new StringBuilder().append(mViewId);
-        if (mVirtual) {
-            builder.append(":").append(mVirtualId);
-        }
-        return builder.toString();
+        return mRealId.equals(other.mRealId);
     }
 
     @Override
@@ -107,15 +53,21 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(mViewId);
-        parcel.writeInt(mVirtual ? 1 : 0);
-        parcel.writeInt(mVirtualId);
+        parcel.writeParcelable(mRealId, 0);
     }
 
     private AutoFillId(Parcel parcel) {
-        mViewId = parcel.readInt();
-        mVirtual = parcel.readInt() == 1;
-        mVirtualId = parcel.readInt();
+        mRealId = parcel.readParcelable(null);
+    }
+
+    /** @hide */
+    public AutofillId getDaRealId() {
+        return mRealId;
+    }
+
+    /** @hide */
+    public static AutoFillId forDaRealId(AutofillId id) {
+        return id == null ? null : new AutoFillId(id);
     }
 
     public static final Parcelable.Creator<AutoFillId> CREATOR =
diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java
index 37966b2..c508ba4 100644
--- a/core/java/android/view/autofill/AutoFillType.java
+++ b/core/java/android/view/autofill/AutoFillType.java
@@ -23,16 +23,18 @@
 import android.view.View;
 
 /**
- * Defines the type of a object that can be used to auto-fill a {@link View} so the
- * {@link android.service.autofill.AutoFillService} can use the proper {@link AutoFillValue} to
+ * Defines the type of a object that can be used to autofill a {@link View} so the
+ * {@link android.service.autofill.AutofillService} can use the proper {@link AutofillValue} to
  * fill it.
  *
- * TODO(b/35956626): remove once clients use getAutoFilltype
+ * @hide
+ * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
  */
+@Deprecated
 public final class AutoFillType implements Parcelable {
 
     // Cached instance for types that don't have subtype; it uses the "lazy initialization holder
-    // class idiom" (Effective Java, Item 71) to avoid memory utilization when auto-fill is not
+    // class idiom" (Effective Java, Item 71) to avoid memory utilization when autofill is not
     // enabled.
     private static class DefaultTypesHolder {
         static final AutoFillType TEXT = new AutoFillType(TYPE_TEXT);
@@ -54,10 +56,6 @@
 
     /**
      * Checks if this is a type for a text field, which is filled by a {@link CharSequence}.
-     *
-     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forText(CharSequence)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getTextValue()}.
      */
     public boolean isText() {
         return mType == TYPE_TEXT;
@@ -65,10 +63,6 @@
 
     /**
      * Checks if this is a a type for a togglable field, which is filled by a {@code boolean}.
-     *
-     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forToggle(boolean)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getToggleValue()}.
      */
     public boolean isToggle() {
         return mType == TYPE_TOGGLE;
@@ -77,14 +71,7 @@
     /**
      * Checks if this is a type for a selection list field, which is filled by a {@code integer}
      * representing the element index inside the list (starting at {@code 0}.
-     *
-     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forList(int)}, and the value passed to auto-fill a
-     * {@link View} can be fetched through {@link AutoFillValue#getListValue()}.
-     *
-     * <p>The available options in the selection list are typically provided by
-     * {@link android.app.assist.AssistStructure.ViewNode#getAutoFillOptions()}.
-     */
+      */
     public boolean isList() {
         return mType == TYPE_LIST;
     }
@@ -93,10 +80,6 @@
      * Checks if this is a type for a date and time, which is represented by a long representing
      * the number of milliseconds since the standard base time known as "the epoch", namely
      * January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()}.
-     *
-     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forDate(long)}, and the values passed to
-     * auto-fill a {@link View} can be fetched through {@link AutoFillValue#getDateValue()}.
      */
     public boolean isDate() {
         return mType == TYPE_DATE;
diff --git a/core/java/android/view/autofill/AutoFillValue.aidl b/core/java/android/view/autofill/AutoFillValue.aidl
index 3b284b9..05b7562 100644
--- a/core/java/android/view/autofill/AutoFillValue.aidl
+++ b/core/java/android/view/autofill/AutoFillValue.aidl
@@ -16,4 +16,5 @@
 
 package android.view.autofill;
 
+//  @deprecated TODO(b/35956626): remove once clients use AutofillValue
 parcelable AutoFillValue;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/AutoFillValue.java b/core/java/android/view/autofill/AutoFillValue.java
index 11fab68..5dd17f1 100644
--- a/core/java/android/view/autofill/AutoFillValue.java
+++ b/core/java/android/view/autofill/AutoFillValue.java
@@ -24,24 +24,15 @@
 import android.view.View;
 
 /**
- * Abstracts how a {@link View} can be auto-filled by an
- * {@link android.service.autofill.AutoFillService}.
- *
- * <p>Each {@link AutoFillValue} has a {@code type} and optionally a {@code sub-type}: the
- * {@code type} defines the view's UI control category (like a text field), while the optional
- * {@code sub-type} define its semantics (like a postal address).
+ * @hide
+ * @deprecated TODO(b/35956626): remove once clients use AutofillValue
  */
+@Deprecated
 public final class AutoFillValue implements Parcelable {
-    private final String mText;
-    private final int mListIndex;
-    private final boolean mToggle;
-    private final long mDate;
+    private final AutofillValue mRealValue;
 
-    private AutoFillValue(CharSequence text, int listIndex, boolean toggle, long date) {
-        mText = (text == null) ? null : text.toString();
-        mListIndex = listIndex;
-        mToggle = toggle;
-        mDate = date;
+    private AutoFillValue(AutofillValue daRealValue) {
+        this.mRealValue = daRealValue;
     }
 
     /**
@@ -50,7 +41,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
      */
     public CharSequence getTextValue() {
-        return mText;
+        return mRealValue.getTextValue();
     }
 
     /**
@@ -59,7 +50,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
      */
     public boolean getToggleValue() {
-        return mToggle;
+        return mRealValue.getToggleValue();
     }
 
     /**
@@ -68,7 +59,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
      */
     public int getListValue() {
-        return mListIndex;
+        return mRealValue.getListValue();
     }
 
     /**
@@ -77,7 +68,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
      */
     public long getDateValue() {
-        return mDate;
+        return mRealValue.getDateValue();
     }
 
     /////////////////////////////////////
@@ -86,13 +77,7 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((mText == null) ? 0 : mText.hashCode());
-        result = prime * result + mListIndex;
-        result = prime * result + (mToggle ? 1231 : 1237);
-        result = prime * result + (int) (mDate ^ (mDate >>> 32));
-        return result;
+        return mRealValue.hashCode();
     }
 
     @Override
@@ -101,32 +86,19 @@
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         final AutoFillValue other = (AutoFillValue) obj;
-        if (mText == null) {
-            if (other.mText != null) return false;
-        } else {
-            if (!mText.equals(other.mText)) return false;
-        }
-        if (mListIndex != other.mListIndex) return false;
-        if (mToggle != other.mToggle) return false;
-        if (mDate != other.mDate) return false;
-        return true;
+        return mRealValue.equals(other.mRealValue);
     }
 
     /** @hide */
     public String coerceToString() {
-        // TODO(b/33197203): How can we filter on toggles or list values?
-        return mText;
+        return mRealValue.coerceToString();
     }
 
     @Override
     public String toString() {
         if (!DEBUG) return super.toString();
 
-        if (mText != null) {
-            return mText.length() + "_chars";
-        }
-
-        return "[l=" + mListIndex + ", t=" + mToggle + ", d=" + mDate + "]";
+        return mRealValue.toString();
     }
 
     /////////////////////////////////////
@@ -140,17 +112,11 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(mText);
-        parcel.writeInt(mListIndex);
-        parcel.writeInt(mToggle ? 1 : 0);
-        parcel.writeLong(mDate);
+        parcel.writeParcelable(mRealValue, 0);
     }
 
     private AutoFillValue(Parcel parcel) {
-        mText = parcel.readString();
-        mListIndex = parcel.readInt();
-        mToggle = parcel.readInt() == 1;
-        mDate = parcel.readLong();
+        mRealValue = parcel.readParcelable(null);
     }
 
     public static final Parcelable.Creator<AutoFillValue> CREATOR =
@@ -169,17 +135,14 @@
     ////////////////////
     // Factory methods //
     ////////////////////
-
-    // TODO(b/33197203): add unit tests for each supported type (new / get should return same value)
     /**
      * Creates a new {@link AutoFillValue} to autofill a {@link View} representing a text field.
      *
      * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
      */
-    // TODO(b/33197203): use cache
     @Nullable
     public static AutoFillValue forText(@Nullable CharSequence value) {
-        return value == null ? null : new AutoFillValue(value, 0, false, 0);
+        return value == null ? null : new AutoFillValue(AutofillValue.forText(value));
     }
 
     /**
@@ -189,7 +152,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
      */
     public static AutoFillValue forToggle(boolean value) {
-        return new AutoFillValue(null, 0, value, 0);
+        return new AutoFillValue(AutofillValue.forToggle(value));
     }
 
     /**
@@ -199,7 +162,7 @@
      * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
      */
     public static AutoFillValue forList(int value) {
-        return new AutoFillValue(null, value, false, 0);
+        return new AutoFillValue(AutofillValue.forList(value));
     }
 
     /**
@@ -208,6 +171,16 @@
      * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
      */
     public static AutoFillValue forDate(long date) {
-        return new AutoFillValue(null, 0, false, date);
+        return new AutoFillValue(AutofillValue.forDate(date));
+    }
+
+    /** @hide */
+    public static AutoFillValue forDaRealValue(AutofillValue daRealValue) {
+        return new AutoFillValue(daRealValue);
+    }
+
+    /** @hide */
+    public AutofillValue getDaRealValue() {
+        return mRealValue;
     }
 }
diff --git a/core/java/android/view/autofill/AutofillId.aidl b/core/java/android/view/autofill/AutofillId.aidl
new file mode 100644
index 0000000..7ac3d5b
--- /dev/null
+++ b/core/java/android/view/autofill/AutofillId.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.view.autofill;
+
+parcelable AutofillId;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/AutofillId.java b/core/java/android/view/autofill/AutofillId.java
new file mode 100644
index 0000000..d678015
--- /dev/null
+++ b/core/java/android/view/autofill/AutofillId.java
@@ -0,0 +1,135 @@
+/*
+ * 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.view.autofill;
+
+import static android.view.autofill.Helper.DEBUG;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.View;
+
+/**
+ * A unique identifier for an autofill node inside an {@link android.app.Activity}.
+ */
+public final class AutofillId implements Parcelable {
+
+    private final int mViewId;
+    private final boolean mVirtual;
+    private final int mVirtualId;
+
+    // TODO(b/33197203): use factory and cache values, since they're immutable
+    /** @hide */
+    public AutofillId(int id) {
+        mVirtual = false;
+        mViewId = id;
+        mVirtualId = View.NO_ID;
+    }
+
+    /** @hide */
+    public AutofillId(AutofillId parent, int virtualChildId) {
+        mVirtual = true;
+        mViewId = parent.mViewId;
+        mVirtualId = virtualChildId;
+    }
+
+    /** @hide */
+    public AutofillId(int parentId, int virtualChildId) {
+        mVirtual = true;
+        mViewId = parentId;
+        mVirtualId = virtualChildId;
+    }
+
+    /** @hide */
+    public int getViewId() {
+        return mViewId;
+    }
+
+    /** @hide */
+    public int getVirtualChildId() {
+        return mVirtualId;
+    }
+
+    /** @hide */
+    public boolean isVirtual() {
+        return mVirtual;
+    }
+
+    /////////////////////////////////
+    //  Object "contract" methods. //
+    /////////////////////////////////
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mViewId;
+        result = prime * result + mVirtualId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final AutofillId other = (AutofillId) obj;
+        if (mViewId != other.mViewId) return false;
+        if (mVirtualId != other.mVirtualId) return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        if (!DEBUG) return super.toString();
+
+        final StringBuilder builder = new StringBuilder().append(mViewId);
+        if (mVirtual) {
+            builder.append(":").append(mVirtualId);
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mViewId);
+        parcel.writeInt(mVirtual ? 1 : 0);
+        parcel.writeInt(mVirtualId);
+    }
+
+    private AutofillId(Parcel parcel) {
+        mViewId = parcel.readInt();
+        mVirtual = parcel.readInt() == 1;
+        mVirtualId = parcel.readInt();
+    }
+
+    public static final Parcelable.Creator<AutofillId> CREATOR =
+            new Parcelable.Creator<AutofillId>() {
+        @Override
+        public AutofillId createFromParcel(Parcel source) {
+            return new AutofillId(source);
+        }
+
+        @Override
+        public AutofillId[] newArray(int size) {
+            return new AutofillId[size];
+        }
+    };
+}
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutofillManager.java
similarity index 75%
rename from core/java/android/view/autofill/AutoFillManager.java
rename to core/java/android/view/autofill/AutofillManager.java
index 8beaf4e..2a12e4b 100644
--- a/core/java/android/view/autofill/AutoFillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -44,9 +44,9 @@
  */
 // TODO(b/33197203): improve this javadoc
 //TODO(b/33197203): restrict manager calls to activity
-public final class AutoFillManager {
+public final class AutofillManager {
 
-    private static final String TAG = "AutoFillManager";
+    private static final String TAG = "AutofillManager";
 
     /**
      * Intent extra: The assist structure which captures the filled screen.
@@ -89,14 +89,14 @@
     private boolean mEnabled;
 
     /** @hide */
-    public interface AutoFillClient {
+    public interface AutofillClient {
         /**
-         * Asks the client to perform an auto-fill.
+         * Asks the client to perform an autofill.
          *
-         * @param ids The values to auto-fill
-         * @param values The values to auto-fill
+         * @param ids The values to autofill
+         * @param values The values to autofill
          */
-        void autoFill(List<AutoFillId> ids, List<AutoFillValue> values);
+        void autofill(List<AutofillId> ids, List<AutofillValue> values);
 
         /**
          * Asks the client to start an authentication flow.
@@ -115,17 +115,17 @@
     /**
      * @hide
      */
-    public AutoFillManager(Context context, IAutoFillManager service) {
+    public AutofillManager(Context context, IAutoFillManager service) {
         mContext = context;
         mService = service;
     }
 
     /**
-     * Called when an auto-fill operation on a {@link View} should start.
+     * Called when an autofill operation on a {@link View} should start.
      *
-     * @param view {@link View} that triggered the auto-fill request.
+     * @param view {@link View} that triggered the autofill request.
      */
-    public void startAutoFillRequest(@NonNull View view) {
+    public void startAutofillRequest(@NonNull View view) {
         ensureServiceClientAddedIfNeeded();
 
         if (!mEnabled) {
@@ -134,8 +134,8 @@
 
         final Rect bounds = mTempRect;
         view.getBoundsOnScreen(bounds);
-        final AutoFillId id = getAutoFillId(view);
-        final AutoFillValue value = view.getAutoFillValue();
+        final AutofillId id = getAutofillId(view);
+        final AutofillValue value = view.getAutofillValue();
 
         if (!mHasSession) {
             // Starts new session.
@@ -147,16 +147,16 @@
     }
 
     /**
-     * Called when an auto-fill operation on a {@link View} should stop.
+     * Called when an autofill operation on a {@link View} should stop.
      *
-     * @param view {@link View} that triggered the auto-fill request in
-     *             {@link #startAutoFillRequest(View)}.
+     * @param view {@link View} that triggered the autofill request in
+     *             {@link #startAutofillRequest(View)}.
      */
-    public void stopAutoFillRequest(@NonNull View view) {
+    public void stopAutofillRequest(@NonNull View view) {
         ensureServiceClientAddedIfNeeded();
 
         if (mEnabled && mHasSession) {
-            final AutoFillId id = getAutoFillId(view);
+            final AutofillId id = getAutofillId(view);
 
             // Update focus on existing session.
             updateSession(id, null, null, FLAG_FOCUS_LOST);
@@ -164,13 +164,13 @@
     }
 
     /**
-     * Called when an auto-fill operation on a virtual {@link View} should start.
+     * Called when an autofill operation on a virtual {@link View} should start.
      *
-     * @param parent parent of the {@link View} that triggered the auto-fill request.
+     * @param parent parent of the {@link View} that triggered the autofill request.
      * @param childId id identifying the virtual child inside the parent view.
      * @param bounds child boundaries, relative to the top window.
      */
-    public void startAutoFillRequestOnVirtualView(@NonNull View parent, int childId,
+    public void startAutofillRequestOnVirtualView(@NonNull View parent, int childId,
             @NonNull Rect bounds) {
         ensureServiceClientAddedIfNeeded();
 
@@ -178,7 +178,7 @@
             return;
         }
 
-        final AutoFillId id = getAutoFillId(parent, childId);
+        final AutofillId id = getAutofillId(parent, childId);
 
         if (!mHasSession) {
             // Starts new session.
@@ -190,17 +190,17 @@
     }
 
     /**
-     * Called when an auto-fill operation on a virtual {@link View} should stop.
+     * Called when an autofill operation on a virtual {@link View} should stop.
      *
-     * @param parent parent of the {@link View} that triggered the auto-fill request in
-     *               {@link #startAutoFillRequestOnVirtualView(View, int, Rect)}.
+     * @param parent parent of the {@link View} that triggered the autofill request in
+     *               {@link #startAutofillRequestOnVirtualView(View, int, Rect)}.
      * @param childId id identifying the virtual child inside the parent view.
      */
-    public void stopAutoFillRequestOnVirtualView(@NonNull View parent, int childId) {
+    public void stopAutofillRequestOnVirtualView(@NonNull View parent, int childId) {
         ensureServiceClientAddedIfNeeded();
 
         if (mEnabled && mHasSession) {
-            final AutoFillId id = getAutoFillId(parent, childId);
+            final AutofillId id = getAutofillId(parent, childId);
 
             // Update focus on existing session.
             updateSession(id, null, null, FLAG_FOCUS_LOST);
@@ -208,7 +208,7 @@
     }
 
     /**
-     * Called to indicate the value of an auto-fillable {@link View} changed.
+     * Called to indicate the value of an autofillable {@link View} changed.
      *
      * @param view view whose value changed.
      */
@@ -217,30 +217,30 @@
             return;
         }
 
-        final AutoFillId id = getAutoFillId(view);
-        final AutoFillValue value = view.getAutoFillValue();
+        final AutofillId id = getAutofillId(view);
+        final AutofillValue value = view.getAutofillValue();
         updateSession(id, null, value, FLAG_VALUE_CHANGED);
     }
 
 
     /**
-     * Called to indicate the value of an auto-fillable virtual {@link View} changed.
+     * Called to indicate the value of an autofillable virtual {@link View} changed.
      *
      * @param parent parent view whose value changed.
      * @param childId id identifying the virtual child inside the parent view.
      * @param value new value of the child.
      */
-    public void virtualValueChanged(View parent, int childId, AutoFillValue value) {
+    public void virtualValueChanged(View parent, int childId, AutofillValue value) {
         if (!mEnabled || !mHasSession) {
             return;
         }
 
-        final AutoFillId id = getAutoFillId(parent, childId);
+        final AutofillId id = getAutofillId(parent, childId);
         updateSession(id, null, value, FLAG_VALUE_CHANGED);
     }
 
     /**
-     * Called to indicate the current auto-fill context should be reset.
+     * Called to indicate the current autofill context should be reset.
      *
      * <p>For example, when a virtual view is rendering an {@code HTML} page with a form, it should
      * call this method after the form is submitted and another page is rendered.
@@ -253,9 +253,9 @@
         finishSession();
     }
 
-    private AutoFillClient getClient() {
-        if (mContext instanceof AutoFillClient) {
-            return (AutoFillClient) mContext;
+    private AutofillClient getClient() {
+        if (mContext instanceof AutofillClient) {
+            return (AutofillClient) mContext;
         }
         return null;
     }
@@ -283,16 +283,17 @@
         }
     }
 
-    private static AutoFillId getAutoFillId(View view) {
-        return new AutoFillId(view.getAccessibilityViewId());
+
+    private static AutofillId getAutofillId(View view) {
+        return new AutofillId(view.getAccessibilityViewId());
     }
 
-    private static AutoFillId getAutoFillId(View parent, int childId) {
-        return new AutoFillId(parent.getAccessibilityViewId(), childId);
+    private static AutofillId getAutofillId(View parent, int childId) {
+        return new AutofillId(parent.getAccessibilityViewId(), childId);
     }
 
-    private void startSession(AutoFillId id, IBinder windowToken,
-            Rect bounds, AutoFillValue value) {
+    private void startSession(AutofillId id, IBinder windowToken, Rect bounds,
+            AutofillValue value) {
         if (DEBUG) {
             Log.d(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value);
         }
@@ -301,7 +302,7 @@
             mService.startSession(mContext.getActivityToken(), windowToken,
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
                     mCallback != null);
-            final AutoFillClient client = getClient();
+            final AutofillClient client = getClient();
             if (client != null) {
                 client.resetableStateAvailable();
             }
@@ -323,11 +324,11 @@
         }
     }
 
-    private void updateSession(AutoFillId id, Rect bounds, AutoFillValue value, int flags) {
+    private void updateSession(AutofillId id, Rect bounds, AutofillValue value, int flags) {
         if (DEBUG) {
             if (VERBOSE || (flags & FLAG_FOCUS_LOST) != 0) {
                 Log.d(TAG, "updateSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
-                    + ", flags=" + flags);
+                        + ", flags=" + flags);
             }
         }
 
@@ -344,7 +345,7 @@
             return;
         }
         if (mServiceClient == null) {
-            mServiceClient = new AutoFillManagerClient(this);
+            mServiceClient = new AutofillManagerClient(this);
             try {
                 mEnabled = mService.addClient(mServiceClient, mContext.getUserId());
             } catch (RemoteException e) {
@@ -392,7 +393,7 @@
         }
     }
 
-    private void onAutofillEvent(IBinder windowToken, AutoFillId id, int event) {
+    private void onAutofillEvent(IBinder windowToken, AutofillId id, int event) {
         if (mCallback == null) return;
         if (id == null) {
             Log.w(TAG, "onAutofillEvent(): no id for event " + event);
@@ -466,31 +467,30 @@
                 @AutofillEventType int event) {}
     }
 
-    private static final class AutoFillManagerClient extends IAutoFillManagerClient.Stub {
-        private final WeakReference<AutoFillManager> mAutoFillManager;
+    private static final class AutofillManagerClient extends IAutoFillManagerClient.Stub {
+        private final WeakReference<AutofillManager> mAfm;
 
-        AutoFillManagerClient(AutoFillManager autoFillManager) {
-            mAutoFillManager = new WeakReference<>(autoFillManager);
+        AutofillManagerClient(AutofillManager autofillManager) {
+            mAfm = new WeakReference<>(autofillManager);
         }
 
         @Override
         public void setState(boolean enabled) {
-            final AutoFillManager autoFillManager = mAutoFillManager.get();
-            if (autoFillManager != null) {
-                autoFillManager.mContext.getMainThreadHandler().post(() ->
-                        autoFillManager.mEnabled = enabled);
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(() -> afm.mEnabled = enabled);
             }
         }
 
         @Override
-        public void autoFill(List<AutoFillId> ids, List<AutoFillValue> values) {
+        public void autofill(List<AutofillId> ids, List<AutofillValue> values) {
             // TODO(b/33197203): must keep the dataset so subsequent calls pass the same
             // dataset.extras to service
-            final AutoFillManager autoFillManager = mAutoFillManager.get();
-            if (autoFillManager != null) {
-                autoFillManager.mContext.getMainThreadHandler().post(() -> {
-                    if (autoFillManager.getClient() != null) {
-                        autoFillManager.getClient().autoFill(ids, values);
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(() -> {
+                    if (afm.getClient() != null) {
+                        afm.getClient().autofill(ids, values);
                     }
                 });
             }
@@ -498,23 +498,23 @@
 
         @Override
         public void authenticate(IntentSender intent, Intent fillInIntent) {
-            final AutoFillManager autoFillManager = mAutoFillManager.get();
-            if (autoFillManager != null) {
-                autoFillManager.mContext.getMainThreadHandler().post(() -> {
-                    if (autoFillManager.getClient() != null) {
-                        autoFillManager.getClient().authenticate(intent, fillInIntent);
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(() -> {
+                    if (afm.getClient() != null) {
+                        afm.getClient().authenticate(intent, fillInIntent);
                     }
                 });
             }
         }
 
         @Override
-        public void onAutofillEvent(IBinder windowToken, AutoFillId id, int event) {
-            final AutoFillManager autoFillManager = mAutoFillManager.get();
-            if (autoFillManager != null) {
-                autoFillManager.mContext.getMainThreadHandler().post(() -> {
-                    if (autoFillManager.getClient() != null) {
-                        autoFillManager.onAutofillEvent(windowToken, id, event);
+        public void onAutofillEvent(IBinder windowToken, AutofillId id, int event) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(() -> {
+                    if (afm.getClient() != null) {
+                        afm.onAutofillEvent(windowToken, id, event);
                     }
                 });
             }
diff --git a/core/java/android/view/autofill/AutofillValue.aidl b/core/java/android/view/autofill/AutofillValue.aidl
new file mode 100644
index 0000000..a015bad
--- /dev/null
+++ b/core/java/android/view/autofill/AutofillValue.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.view.autofill;
+
+parcelable AutofillValue;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/AutofillValue.java b/core/java/android/view/autofill/AutofillValue.java
new file mode 100644
index 0000000..0c7620e
--- /dev/null
+++ b/core/java/android/view/autofill/AutofillValue.java
@@ -0,0 +1,211 @@
+/*
+ * 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.view.autofill;
+
+import static android.view.autofill.Helper.DEBUG;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.View;
+
+/**
+ * Abstracts how a {@link View} can be autofilled by an
+ * {@link android.service.autofill.AutofillService}.
+ *
+ * <p>Each {@link AutofillValue} is associated with a {@code type}, as defined by
+ * {@link View#getAutofillType()}.
+ */
+public final class AutofillValue implements Parcelable {
+    private final String mText;
+    private final int mListIndex;
+    private final boolean mToggle;
+    private final long mDate;
+
+    private AutofillValue(CharSequence text, int listIndex, boolean toggle, long date) {
+        mText = (text == null) ? null : text.toString();
+        mListIndex = listIndex;
+        mToggle = toggle;
+        mDate = date;
+    }
+
+    /**
+     * Gets the value to autofill a text field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
+     */
+    public CharSequence getTextValue() {
+        return mText;
+    }
+
+    /**
+     * Gets the value to autofill a toggable field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
+     */
+    public boolean getToggleValue() {
+        return mToggle;
+    }
+
+    /**
+     * Gets the value to autofill a selection list field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
+     */
+    public int getListValue() {
+        return mListIndex;
+    }
+
+    /**
+     * Gets the value to autofill a date field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
+     */
+    public long getDateValue() {
+        return mDate;
+    }
+
+    /////////////////////////////////////
+    //  Object "contract" methods. //
+    /////////////////////////////////////
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mText == null) ? 0 : mText.hashCode());
+        result = prime * result + mListIndex;
+        result = prime * result + (mToggle ? 1231 : 1237);
+        result = prime * result + (int) (mDate ^ (mDate >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final AutofillValue other = (AutofillValue) obj;
+        if (mText == null) {
+            if (other.mText != null) return false;
+        } else {
+            if (!mText.equals(other.mText)) return false;
+        }
+        if (mListIndex != other.mListIndex) return false;
+        if (mToggle != other.mToggle) return false;
+        if (mDate != other.mDate) return false;
+        return true;
+    }
+
+    /** @hide */
+    public String coerceToString() {
+        // TODO(b/33197203): How can we filter on toggles or list values?
+        return mText;
+    }
+
+    @Override
+    public String toString() {
+        if (!DEBUG) return super.toString();
+
+        if (mText != null) {
+            return mText.length() + "_chars";
+        }
+
+        return "[l=" + mListIndex + ", t=" + mToggle + ", d=" + mDate + "]";
+    }
+
+    /////////////////////////////////////
+    //  Parcelable "contract" methods. //
+    /////////////////////////////////////
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mText);
+        parcel.writeInt(mListIndex);
+        parcel.writeInt(mToggle ? 1 : 0);
+        parcel.writeLong(mDate);
+    }
+
+    private AutofillValue(Parcel parcel) {
+        mText = parcel.readString();
+        mListIndex = parcel.readInt();
+        mToggle = parcel.readInt() == 1;
+        mDate = parcel.readLong();
+    }
+
+    public static final Parcelable.Creator<AutofillValue> CREATOR =
+            new Parcelable.Creator<AutofillValue>() {
+        @Override
+        public AutofillValue createFromParcel(Parcel source) {
+            return new AutofillValue(source);
+        }
+
+        @Override
+        public AutofillValue[] newArray(int size) {
+            return new AutofillValue[size];
+        }
+    };
+
+    ////////////////////
+    // Factory methods //
+    ////////////////////
+
+    /**
+     * Creates a new {@link AutofillValue} to autofill a {@link View} representing a text field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
+     */
+    // TODO(b/33197203): use cache
+    @Nullable
+    public static AutofillValue forText(@Nullable CharSequence value) {
+        return value == null ? null : new AutofillValue(value, 0, false, 0);
+    }
+
+    /**
+     * Creates a new {@link AutofillValue} to autofill a {@link View} representing a toggable
+     * field.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
+     */
+    public static AutofillValue forToggle(boolean value) {
+        return new AutofillValue(null, 0, value, 0);
+    }
+
+    /**
+     * Creates a new {@link AutofillValue} to autofill a {@link View} representing a selection
+     * list.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
+     */
+    public static AutofillValue forList(int value) {
+        return new AutofillValue(null, value, false, 0);
+    }
+
+    /**
+     * Creates a new {@link AutofillValue} to autofill a {@link View} representing a date.
+     *
+     * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
+     */
+    public static AutofillValue forDate(long value) {
+        return new AutofillValue(null, 0, false, value);
+    }
+}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index b36c0f1..07d8cab 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -19,8 +19,8 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 
 /**
@@ -31,10 +31,10 @@
 interface IAutoFillManager {
     boolean addClient(in IAutoFillManagerClient client, int userId);
     oneway void startSession(in IBinder activityToken, IBinder windowToken, in IBinder appCallback,
-            in AutoFillId autoFillId, in Rect bounds, in AutoFillValue value, int userId,
+            in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
             boolean hasCallback);
-    oneway void updateSession(in IBinder activityToken, in AutoFillId id, in Rect bounds,
-            in AutoFillValue value, int flags, int userId);
+    oneway void updateSession(in IBinder activityToken, in AutofillId id, in Rect bounds,
+            in AutofillValue value, int flags, int userId);
     oneway void finishSession(in IBinder activityToken, int userId);
     oneway void setAuthenticationResult(in Bundle data,
             in IBinder activityToken, int userId);
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 9eef7d0..eabf6b1 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -21,24 +21,24 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.IBinder;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 /**
- * Object running in the application process and responsible for auto-filling it.
+ * Object running in the application process and responsible for autofilling it.
  *
  * @hide
  */
 oneway interface IAutoFillManagerClient {
     /**
-     * Notifies the client when the auto-fill enabled state changed.
+     * Notifies the client when the autofill enabled state changed.
      */
     void setState(boolean enabled);
 
     /**
-      * Auto-fills the activity with the contents of a dataset.
+      * Autofills the activity with the contents of a dataset.
       */
-    void autoFill(in List<AutoFillId> ids, in List<AutoFillValue> values);
+    void autofill(in List<AutofillId> ids, in List<AutofillValue> values);
 
     /**
       * Authenticates a fill response or a data set.
@@ -48,5 +48,5 @@
     /**
      * Notifies the client when the auto-fill UI changed.
      */
-    void onAutofillEvent(in IBinder windowToken, in AutoFillId id, int event);
+    void onAutofillEvent(in IBinder windowToken, in AutofillId id, int event);
 }
diff --git a/core/java/android/view/textclassifier/EntityConfidence.java b/core/java/android/view/textclassifier/EntityConfidence.java
index 7aab71f..0589d204 100644
--- a/core/java/android/view/textclassifier/EntityConfidence.java
+++ b/core/java/android/view/textclassifier/EntityConfidence.java
@@ -42,10 +42,10 @@
         float score1 = mEntityConfidence.get(e1);
         float score2 = mEntityConfidence.get(e2);
         if (score1 > score2) {
-            return 1;
+            return -1;
         }
         if (score1 < score2) {
-            return -1;
+            return 1;
         }
         return 0;
     };
diff --git a/core/java/android/view/textclassifier/LangId.java b/core/java/android/view/textclassifier/LangId.java
index 53bc1b0..ada3c37c 100644
--- a/core/java/android/view/textclassifier/LangId.java
+++ b/core/java/android/view/textclassifier/LangId.java
@@ -37,8 +37,8 @@
     /**
      * Detects the language for given text.
      */
-    public String findLanguage(String text) {
-        return nativeFindLanguage(mModelPtr, text);
+    public ClassificationResult[] findLanguages(String text) {
+        return nativeFindLanguages(mModelPtr, text);
     }
 
     /**
@@ -50,8 +50,20 @@
 
     private static native long nativeNew(int fd);
 
-    private static native String nativeFindLanguage(long context, String text);
+    private static native ClassificationResult[] nativeFindLanguages(
+            long context, String text);
 
     private static native void nativeClose(long context);
-}
 
+    /** Classification result for findLanguage method. */
+    static final class ClassificationResult {
+        final String mLanguage;
+        /** float range: 0 - 1 */
+        final float mScore;
+
+        ClassificationResult(String language, float score) {
+            mLanguage = language;
+            mScore = score;
+        }
+    }
+}
diff --git a/core/java/android/view/textclassifier/SmartSelection.java b/core/java/android/view/textclassifier/SmartSelection.java
index 47c39e4..c48cd06 100644
--- a/core/java/android/view/textclassifier/SmartSelection.java
+++ b/core/java/android/view/textclassifier/SmartSelection.java
@@ -55,9 +55,11 @@
      *
      * The begin and end params are character indices in the context string.
      *
-     * Returns the type of the selection, e.g. "email", "address", "phone".
+     * Returns an array of ClassificationResult objects with the probability
+     * scores for different collections.
      */
-    public String classifyText(String context, int selectionBegin, int selectionEnd) {
+    public ClassificationResult[] classifyText(
+            String context, int selectionBegin, int selectionEnd) {
         return nativeClassifyText(mCtx, context, selectionBegin, selectionEnd);
     }
 
@@ -73,9 +75,21 @@
     private static native int[] nativeSuggest(
             long context, String text, int selectionBegin, int selectionEnd);
 
-    private static native String nativeClassifyText(
+    private static native ClassificationResult[] nativeClassifyText(
             long context, String text, int selectionBegin, int selectionEnd);
 
     private static native void nativeClose(long context);
+
+    /** Classification result for classifyText method. */
+    static final class ClassificationResult {
+        final String mCollection;
+        /** float range: 0 - 1 */
+        final float mScore;
+
+        ClassificationResult(String collection, float score) {
+            mCollection = collection;
+            mScore = score;
+        }
+    }
 }
 
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index c4d64d1..f032414 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -85,12 +85,17 @@
         Preconditions.checkArgument(text != null);
         try {
             if (text.length() > 0) {
-                final String language = getLanguageDetector().findLanguage(text.toString());
-                final Locale locale = new Locale.Builder().setLanguageTag(language).build();
-                return Collections.unmodifiableList(Arrays.asList(
-                        new TextLanguage.Builder(0, text.length())
-                                .setLanguage(locale, 1.0f /* confidence */)
-                                .build()));
+                final LangId.ClassificationResult[] results =
+                        getLanguageDetector().findLanguages(text.toString());
+                final TextLanguage.Builder tlBuilder = new TextLanguage.Builder(0, text.length());
+                final int size = results.length;
+                for (int i = 0; i < size; i++) {
+                    tlBuilder.setLanguage(
+                            new Locale.Builder().setLanguageTag(results[i].mLanguage).build(),
+                            results[i].mScore);
+                }
+
+                return Collections.unmodifiableList(Arrays.asList(tlBuilder.build()));
             }
         } catch (Throwable t) {
             // Avoid throwing from this method. Log the error.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 0486f9f..c95a1fb 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -86,10 +86,14 @@
                 final int start = startEnd[0];
                 final int end = startEnd[1];
                 if (start >= 0 && end <= string.length() && start <= end) {
-                    final String type = getSmartSelection().classifyText(string, start, end);
-                    return new TextSelection.Builder(start, end)
-                            .setEntityType(type, 1.0f)
-                            .build();
+                    final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
+                    final SmartSelection.ClassificationResult[] results =
+                            getSmartSelection().classifyText(string, start, end);
+                    final int size = results.length;
+                    for (int i = 0; i < size; i++) {
+                        tsBuilder.setEntityType(results[i].mCollection, results[i].mScore);
+                    }
+                    return tsBuilder.build();
                 } else {
                     // We can not trust the result. Log the issue and ignore the result.
                     Log.d(LOG_TAG, "Got bad indices for input text. Ignoring result.");
@@ -113,13 +117,13 @@
         try {
             if (text.length() > 0) {
                 final CharSequence classified = text.subSequence(startIndex, endIndex);
-                String type = getSmartSelection()
+                SmartSelection.ClassificationResult[] results = getSmartSelection()
                         .classifyText(text.toString(), startIndex, endIndex);
-                if (!TextUtils.isEmpty(type)) {
-                    type = type.toLowerCase(Locale.ENGLISH).trim();
+                if (results.length > 0) {
                     // TODO: Added this log for debug only. Remove before release.
-                    Log.d(LOG_TAG, String.format("Classification type: %s", type));
-                    return createClassificationResult(type, classified);
+                    Log.d(LOG_TAG,
+                            String.format("Classification type: %s", results[0].mCollection));
+                    return createClassificationResult(results, classified);
                 }
             }
         } catch (Throwable t) {
@@ -174,11 +178,17 @@
         }
     }
 
-    private TextClassificationResult createClassificationResult(String type, CharSequence text) {
+    private TextClassificationResult createClassificationResult(
+            SmartSelection.ClassificationResult[] classifications, CharSequence text) {
         final TextClassificationResult.Builder builder = new TextClassificationResult.Builder()
-                .setText(text.toString())
-                .setEntityType(type, 1.0f /* confidence */);
+                .setText(text.toString());
 
+        final int size = classifications.length;
+        for (int i = 0; i < size; i++) {
+            builder.setEntityType(classifications[i].mCollection, classifications[i].mScore);
+        }
+
+        final String type = classifications[0].mCollection;
         final Intent intent = IntentFactory.create(mContext, type, text.toString());
         final PackageManager pm;
         final ResolveInfo resolveInfo;
@@ -252,14 +262,17 @@
                 final int selectionEnd = selection[1];
                 if (selectionStart >= 0 && selectionEnd <= text.length()
                         && selectionStart <= selectionEnd) {
-                    final String type =
+                    final SmartSelection.ClassificationResult[] results =
                             smartSelection.classifyText(text, selectionStart, selectionEnd);
-                    if (matches(type, linkMask)) {
-                        final Intent intent = IntentFactory.create(
-                                context, type, text.substring(selectionStart, selectionEnd));
-                        if (hasActivityHandler(context, intent)) {
-                            final ClickableSpan span = createSpan(context, intent);
-                            spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+                    if (results.length > 0) {
+                        final String type = results[0].mCollection;
+                        if (matches(type, linkMask)) {
+                            final Intent intent = IntentFactory.create(
+                                    context, type, text.substring(selectionStart, selectionEnd));
+                            if (hasActivityHandler(context, intent)) {
+                                final ClickableSpan span = createSpan(context, intent);
+                                spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+                            }
                         }
                     }
                 }
@@ -272,6 +285,7 @@
          * Returns true if the classification type matches the specified linkMask.
          */
         private static boolean matches(String type, int linkMask) {
+            type = type.trim().toLowerCase(Locale.ENGLISH);
             if ((linkMask & Linkify.PHONE_NUMBERS) != 0
                     && TextClassifier.TYPE_PHONE.equals(type)) {
                 return true;
@@ -403,6 +417,7 @@
 
         @Nullable
         public static Intent create(Context context, String type, String text) {
+            type = type.trim().toLowerCase(Locale.ENGLISH);
             switch (type) {
                 case TextClassifier.TYPE_EMAIL:
                     return new Intent(Intent.ACTION_SENDTO)
@@ -418,12 +433,12 @@
                             .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
                 default:
                     return null;
-                // TODO: Add other classification types.
             }
         }
 
         @Nullable
         public static String getLabel(Context context, String type) {
+            type = type.trim().toLowerCase(Locale.ENGLISH);
             switch (type) {
                 case TextClassifier.TYPE_EMAIL:
                     return context.getString(com.android.internal.R.string.email);
@@ -435,7 +450,6 @@
                     return context.getString(com.android.internal.R.string.browse);
                 default:
                     return null;
-                // TODO: Add other classification types.
             }
         }
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3fbeb03..9a931c2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2612,8 +2612,8 @@
     }
 
     @Override
-    public void onProvideAutoFillVirtualStructure(ViewStructure structure, int flags) {
-        mProvider.getViewDelegate().onProvideAutoFillVirtualStructure(structure, flags);
+    public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
+        mProvider.getViewDelegate().onProvideAutofillVirtualStructure(structure, flags);
     }
 
     /** @hide */
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index ffc18b1..5724a9b 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -318,7 +318,7 @@
         public void onProvideVirtualStructure(android.view.ViewStructure structure);
 
         @SuppressWarnings("unused")
-        public default void onProvideAutoFillVirtualStructure(android.view.ViewStructure structure,
+        public default void onProvideAutofillVirtualStructure(android.view.ViewStructure structure,
                 int flags) {
         }
 
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index e6cd566..053574f 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -27,7 +27,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStructure;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.R;
 
@@ -492,8 +492,8 @@
     // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
 
     @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.onProvideAutofillStructure(structure, flags);
 
         if (getAdapter() == null) return;
 
@@ -506,12 +506,12 @@
             for (int i = 0; i < count; i++) {
                 options[i] = getAdapter().getItem(i).toString();
             }
-            structure.setAutoFillOptions(options);
+            structure.setAutofillOptions(options);
         }
     }
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
 
         final int position = value.getListValue();
@@ -524,7 +524,7 @@
     }
 
     @Override
-    public AutoFillValue getAutoFillValue() {
-        return isEnabled() ? AutoFillValue.forList(getSelectedItemPosition()) : null;
+    public AutofillValue getAutofillValue() {
+        return isEnabled() ? AutofillValue.forList(getSelectedItemPosition()) : null;
     }
 }
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 0b3cff1..e5505a6 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -34,7 +34,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutofillManager;
 
 /**
  * An AdapterView is a view whose children are determined by an {@link Adapter}.
@@ -915,8 +915,8 @@
                 dispatchOnItemSelected();
             }
         }
-        // Always notify AutoFillManager - it will return right away if auto-fill is disabled.
-        final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+        // Always notify AutoFillManager - it will return right away if autofill is disabled.
+        final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
             afm.valueChanged(this);
         }
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index dce33a0..81aec9c 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -35,8 +35,8 @@
 import android.view.ViewStructure;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.R;
 
@@ -69,7 +69,7 @@
     private OnCheckedChangeListener mOnCheckedChangeWidgetListener;
 
     // Indicates whether the toggle state was set from resources or dynamically, so it can be used
-    // to sanitize auto-fill requests.
+    // to sanitize autofill requests.
     private boolean mCheckedFromResource = false;
 
     private static final int[] CHECKED_STATE_SET = {
@@ -171,7 +171,7 @@
             if (mOnCheckedChangeWidgetListener != null) {
                 mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
             }
-            final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+            final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
             if (afm != null) {
                 afm.valueChanged(this);
             }
@@ -572,17 +572,17 @@
         stream.addProperty("checked", isChecked());
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
 
     @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.onProvideAutofillStructure(structure, flags);
 
         structure.setSanitized(mCheckedFromResource);
     }
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
 
         setChecked(value.getToggleValue());
@@ -594,7 +594,7 @@
     }
 
     @Override
-    public AutoFillValue getAutoFillValue() {
-        return isEnabled() ? AutoFillValue.forToggle(isChecked()) : null;
+    public AutofillValue getAutofillValue() {
+        return isEnabled() ? AutofillValue.forToggle(isChecked()) : null;
     }
 }
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index c905172..fa8316c 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -33,8 +33,8 @@
 import android.view.View;
 import android.view.ViewStructure;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.R;
 
@@ -180,7 +180,7 @@
         }
 
         mDelegate.setAutoFillChangeListener((v, y, m, d) -> {
-            final AutoFillManager afm = context.getSystemService(AutoFillManager.class);
+            final AutofillManager afm = context.getSystemService(AutofillManager.class);
             if (afm != null) {
                 afm.valueChanged(this);
             }
@@ -761,18 +761,18 @@
         void onValidationChanged(boolean valid);
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
 
     @Override
-    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
-        // This view is self-sufficient for auto-fill, so it needs to call
+    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
+        // This view is self-sufficient for autofill, so it needs to call
         // onProvideAutoFillStructure() to fill itself, but it does not need to call
         // dispatchProvideAutoFillStructure() to fill its children.
-        onProvideAutoFillStructure(structure, flags);
+        onProvideAutofillStructure(structure, flags);
     }
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
 
         mDelegate.updateDate(value.getDateValue());
@@ -784,7 +784,7 @@
     }
 
     @Override
-    public AutoFillValue getAutoFillValue() {
-        return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null;
+    public AutofillValue getAutofillValue() {
+        return isEnabled() ? AutofillValue.forDate(mDelegate.getDate()) : null;
     }
 }
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index bb8cd28..bd62d6c 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -16,7 +16,6 @@
 
 package android.widget;
 
-
 import android.annotation.IdRes;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -25,8 +24,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStructure;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.R;
 
@@ -67,7 +66,7 @@
     private PassThroughHierarchyChangeListener mPassThroughListener;
 
     // Indicates whether the child was set from resources or dynamically, so it can be used
-    // to sanitize auto-fill requests.
+    // to sanitize autofill requests.
     private int mInitialCheckedId = View.NO_ID;
 
     /**
@@ -187,7 +186,7 @@
         if (mOnCheckedChangeListener != null) {
             mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);
         }
-        final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+        final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
             afm.valueChanged(this);
         }
@@ -417,16 +416,16 @@
         }
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
 
     @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.onProvideAutofillStructure(structure, flags);
         structure.setSanitized(mCheckedId == mInitialCheckedId);
     }
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
 
         final int index = value.getListValue();
@@ -444,14 +443,14 @@
     }
 
     @Override
-    public AutoFillValue getAutoFillValue() {
+    public AutofillValue getAutofillValue() {
         if (!isEnabled()) return null;
 
         final int count = getChildCount();
         for (int i = 0; i < count; i++) {
             final View child = getChildAt(i);
             if (child.getId() == mCheckedId) {
-                return AutoFillValue.forList(i);
+                return AutofillValue.forList(i);
             }
         }
         return null;
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 3811e1a..ddf0e74 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -41,7 +41,6 @@
 import android.view.PointerIcon;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewStructure;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -914,27 +913,6 @@
         return super.onResolvePointerIcon(event, pointerIndex);
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
-
-    @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
-
-        if (getAdapter() == null) return;
-
-        // TODO(b/33197203): implement sanitization so initial value is only sanitized when coming
-        // from resources.
-
-        final int count = getAdapter().getCount();
-        if (count > 0) {
-            final String[] options = new String[count];
-            for (int i = 0; i < count; i++) {
-                options[i] = getAdapter().getItem(i).toString();
-            }
-            structure.setAutoFillOptions(options);
-        }
-    }
-
     static class SavedState extends AbsSpinner.SavedState {
         boolean showDropdown;
 
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index a9257e6..40253a1 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -1406,17 +1406,17 @@
     @Override
     public void onProvideStructure(ViewStructure structure) {
         super.onProvideStructure(structure);
-        onProvideAutoFillStructureForAssistOrAutoFill(structure);
+        onProvideAutoFillStructureForAssistOrAutofill(structure);
     }
 
     @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
-        onProvideAutoFillStructureForAssistOrAutoFill(structure);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.onProvideAutofillStructure(structure, flags);
+        onProvideAutoFillStructureForAssistOrAutofill(structure);
     }
 
     // NOTE: currently there is no difference for Assist or AutoFill, so it doesn't take flags
-    private void onProvideAutoFillStructureForAssistOrAutoFill(ViewStructure structure) {
+    private void onProvideAutoFillStructureForAssistOrAutofill(ViewStructure structure) {
         CharSequence switchText = isChecked() ? mTextOn : mTextOff;
         if (!TextUtils.isEmpty(switchText)) {
             CharSequence oldText = structure.getText();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b901ab4..ee70acc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -140,8 +140,8 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.AnimationUtils;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.CorrectionInfo;
@@ -732,7 +732,7 @@
     private boolean mHasPresetAutoSizeValues = false;
 
     // Indicates whether the text was set from resources or dynamically, so it can be used to
-    // sanitize auto-fill requests.
+    // sanitize autofill requests.
     private boolean mTextFromResource = false;
 
     /**
@@ -5231,7 +5231,7 @@
         if (needEditableForNotification) {
             sendAfterTextChanged((Editable) text);
         } else {
-            // Always notify AutoFillManager - it will return right away if auto-fill is disabled.
+            // Always notify AutoFillManager - it will return right away if autofill is disabled.
             notifyAutoFillManagerAfterTextChanged();
         }
 
@@ -9124,14 +9124,14 @@
             }
         }
 
-        // Always notify AutoFillManager - it will return right away if auto-fill is disabled.
+        // Always notify AutoFillManager - it will return right away if autofill is disabled.
         notifyAutoFillManagerAfterTextChanged();
 
         hideErrorIfUnchanged();
     }
 
     private void notifyAutoFillManagerAfterTextChanged() {
-        final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+        final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
             if (DEBUG_AUTOFILL) {
                 Log.v(LOG_TAG, "sendAfterTextChanged(): notify AFM for text=" + mText);
@@ -9886,24 +9886,24 @@
     @Override
     public void onProvideStructure(ViewStructure structure) {
         super.onProvideStructure(structure);
-        onProvideAutoStructureForAssistOrAutoFill(structure, false);
+        onProvideAutoStructureForAssistOrAutofill(structure, false);
     }
 
     @Override
-    public void onProvideAutoFillStructure(ViewStructure structure, int flags) {
-        super.onProvideAutoFillStructure(structure, flags);
-        onProvideAutoStructureForAssistOrAutoFill(structure, true);
+    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
+        super.onProvideAutofillStructure(structure, flags);
+        onProvideAutoStructureForAssistOrAutofill(structure, true);
     }
 
-    private void onProvideAutoStructureForAssistOrAutoFill(ViewStructure structure,
-            boolean forAutoFill) {
+    private void onProvideAutoStructureForAssistOrAutofill(ViewStructure structure,
+            boolean forAutofill) {
         final boolean isPassword = hasPasswordTransformationMethod()
                 || isPasswordInputType(getInputType());
-        if (forAutoFill) {
+        if (forAutofill) {
             structure.setSanitized(mTextFromResource);
         }
 
-        if (!isPassword || forAutoFill) {
+        if (!isPassword || forAutofill) {
             if (mLayout == null) {
                 assumeLayout();
             }
@@ -10010,10 +10010,10 @@
         structure.setInputType(getInputType());
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods
+    // TODO(b/33197203): add unit/CTS tests for autofill methods
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         final CharSequence text = value.getTextValue();
 
         if (text != null && isTextEditable()) {
@@ -10028,8 +10028,8 @@
 
     @Override
     @Nullable
-    public AutoFillValue getAutoFillValue() {
-        return isTextEditable() ? AutoFillValue.forText(getText()) : null;
+    public AutofillValue getAutofillValue() {
+        return isTextEditable() ? AutofillValue.forText(getText()) : null;
     }
 
     /** @hide */
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 3a19f21..1435983 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -31,8 +31,8 @@
 import android.view.View;
 import android.view.ViewStructure;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 
 import com.android.internal.R;
 
@@ -142,7 +142,7 @@
                 break;
         }
         mDelegate.setAutoFillChangeListener((v, h, m) -> {
-            final AutoFillManager afm = context.getSystemService(AutoFillManager.class);
+            final AutofillManager afm = context.getSystemService(AutofillManager.class);
             if (afm != null) {
                 afm.valueChanged(this);
             }
@@ -516,18 +516,18 @@
         }
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
 
     @Override
-    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
-        // This view is self-sufficient for auto-fill, so it needs to call
+    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
+        // This view is self-sufficient for autofill, so it needs to call
         // onProvideAutoFillStructure() to fill itself, but it does not need to call
         // dispatchProvideAutoFillStructure() to fill its children.
-        onProvideAutoFillStructure(structure, flags);
+        onProvideAutofillStructure(structure, flags);
     }
 
     @Override
-    public void autoFill(AutoFillValue value) {
+    public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
 
         mDelegate.setDate(value.getDateValue());
@@ -539,7 +539,7 @@
     }
 
     @Override
-    public AutoFillValue getAutoFillValue() {
-        return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null;
+    public AutofillValue getAutofillValue() {
+        return isEnabled() ? AutofillValue.forDate(mDelegate.getDate()) : null;
     }
 }
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index cf1bf62..c6cb837 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -19,6 +19,7 @@
 import com.android.internal.R;
 
 import android.content.Context;
+import android.os.Build;
 import android.provider.Settings;
 import android.text.TextUtils;
 
@@ -29,20 +30,21 @@
     public AmbientDisplayConfiguration(Context context) {
         mContext = context;
     }
-    
+
     public boolean enabled(int user) {
         return pulseOnNotificationEnabled(user)
                 || pulseOnPickupEnabled(user)
-                || pulseOnDoubleTapEnabled(user);
+                || pulseOnDoubleTapEnabled(user)
+                || alwaysOnEnabled(user);
     }
-    
+
     public boolean available() {
         return pulseOnNotificationAvailable() || pulseOnPickupAvailable()
                 || pulseOnDoubleTapAvailable();
     }
-    
+
     public boolean pulseOnNotificationEnabled(int user) {
-        return boolSetting(Settings.Secure.DOZE_ENABLED, user) && pulseOnNotificationAvailable();
+        return boolSettingDefaultOn(Settings.Secure.DOZE_ENABLED, user) && pulseOnNotificationAvailable();
     }
 
     public boolean pulseOnNotificationAvailable() {
@@ -50,17 +52,17 @@
     }
 
     public boolean pulseOnPickupEnabled(int user) {
-        return boolSetting(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user)
+        return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_PICK_UP, user)
                 && pulseOnPickupAvailable();
     }
-    
+
     public boolean pulseOnPickupAvailable() {
         return mContext.getResources().getBoolean(R.bool.config_dozePulsePickup)
                 && ambientDisplayAvailable();
     }
-    
+
     public boolean pulseOnDoubleTapEnabled(int user) {
-        return boolSetting(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, user)
+        return boolSettingDefaultOn(Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, user)
                 && pulseOnDoubleTapAvailable();
     }
 
@@ -72,6 +74,16 @@
         return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
     }
 
+    public boolean alwaysOnEnabled(int user) {
+        return boolSettingDefaultOff(Settings.Secure.DOZE_ALWAYS_ON, user)
+                && alwaysOnAvailable();
+    }
+
+    public boolean alwaysOnAvailable() {
+        // TODO: introduce config_dozeAlwaysOnAvailable. For now just debuggable builds.
+        return Build.IS_DEBUGGABLE && ambientDisplayAvailable();
+    }
+
     public String ambientDisplayComponent() {
         return mContext.getResources().getString(R.string.config_dozeComponent);
     }
@@ -80,8 +92,15 @@
         return !TextUtils.isEmpty(ambientDisplayComponent());
     }
 
-    private boolean boolSetting(String name, int user) {
-        return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, 1, user) != 0;
+    private boolean boolSettingDefaultOn(String name, int user) {
+        return boolSetting(name, user, 1);
     }
 
+    private boolean boolSettingDefaultOff(String name, int user) {
+        return boolSetting(name, user, 0);
+    }
+
+    private boolean boolSetting(String name, int user, int def) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0;
+    }
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 7ff115b..a8e16c9 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.policy;
 
+import android.view.accessibility.AccessibilityNodeInfo;
 import com.android.internal.R;
 import com.android.internal.policy.PhoneWindow.PanelFeatureState;
 import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
@@ -2251,6 +2252,11 @@
     }
 
     @Override
+    public int getAccessibilityViewId() {
+        return AccessibilityNodeInfo.ROOT_ITEM_ID;
+    }
+
+    @Override
     public String toString() {
         return "DecorView@" + Integer.toHexString(this.hashCode()) + "["
                 + getTitleSuffix(mWindow.getAttributes()) + "]";
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index f88ac49..ae31873 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -36,15 +36,18 @@
  */
 public class PipSnapAlgorithm {
 
+    // The below SNAP_MODE_* constants correspond to the config resource value
+    // config_pictureInPictureSnapMode and should not be changed independently.
     // Allows snapping to the four corners
     private static final int SNAP_MODE_CORNERS_ONLY = 0;
     // Allows snapping to the four corners and the mid-points on the long edge in each orientation
     private static final int SNAP_MODE_CORNERS_AND_SIDES = 1;
     // Allows snapping to anywhere along the edge of the screen
     private static final int SNAP_MODE_EDGE = 2;
-    // Allows snapping to four corners on a fling towards a corner or slow move near a corner
-    // snaps anywhere along the edge of screen otherwise
-    private static final int SNAP_MODE_CORNERS_AND_EDGES = 3;
+    // Allows snapping anywhere along the edge of the screen and magnets towards corners
+    private static final int SNAP_MODE_EDGE_MAGNET_CORNERS = 3;
+    // Allows snapping on the long edge in each orientation and magnets towards corners
+    private static final int SNAP_MODE_LONG_EDGE_MAGNET_CORNERS = 4;
 
     // The friction multiplier to control how slippery the PIP is when flung
     private static final float SCROLL_FRICTION_MULTIPLIER = 8f;
@@ -55,7 +58,7 @@
     private final Context mContext;
 
     private final ArrayList<Integer> mSnapGravities = new ArrayList<>();
-    private final int mDefaultSnapMode = SNAP_MODE_CORNERS_AND_EDGES;
+    private final int mDefaultSnapMode = SNAP_MODE_EDGE_MAGNET_CORNERS;
     private int mSnapMode = mDefaultSnapMode;
 
     private final float mDefaultSizePercent;
@@ -85,7 +88,9 @@
      * Updates the snap algorithm when the configuration changes.
      */
     public void onConfigurationChanged() {
-        mOrientation = mContext.getResources().getConfiguration().orientation;
+        Resources res = mContext.getResources();
+        mOrientation = res.getConfiguration().orientation;
+        mSnapMode = res.getInteger(com.android.internal.R.integer.config_pictureInPictureSnapMode);
         calculateSnapTargets();
     }
 
@@ -127,7 +132,8 @@
                 movementBounds.right + stackBounds.width(),
                 movementBounds.bottom + stackBounds.height());
         final Rect newBounds = new Rect(stackBounds);
-        if (mSnapMode == SNAP_MODE_CORNERS_AND_EDGES) {
+        if (mSnapMode == SNAP_MODE_LONG_EDGE_MAGNET_CORNERS
+                || mSnapMode == SNAP_MODE_EDGE_MAGNET_CORNERS) {
             final Rect tmpBounds = new Rect();
             final Point[] snapTargets = new Point[mSnapGravities.size()];
             for (int i = 0; i < mSnapGravities.size(); i++) {
@@ -137,11 +143,11 @@
             }
             Point snapTarget = findClosestPoint(stackBounds.left, stackBounds.top, snapTargets);
             float distance = distanceToPoint(snapTarget, stackBounds.left, stackBounds.top);
-            final float thresh = stackBounds.width() * CORNER_MAGNET_THRESHOLD;
+            final float thresh = Math.max(stackBounds.width(), stackBounds.height())
+                    * CORNER_MAGNET_THRESHOLD;
             if (distance < thresh) {
                 newBounds.offsetTo(snapTarget.x, snapTarget.y);
             } else {
-                // Otherwise we snap to the edge
                 snapRectToClosestEdge(stackBounds, movementBounds, newBounds);
             }
         } else if (mSnapMode == SNAP_MODE_EDGE) {
@@ -324,11 +330,20 @@
         final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
         final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
         final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
-        if (fromLeft <= fromTop && fromLeft <= fromRight && fromLeft <= fromBottom) {
+        int shortest;
+        if (mSnapMode == SNAP_MODE_LONG_EDGE_MAGNET_CORNERS) {
+            // Only check longest edges
+            shortest = (mOrientation == Configuration.ORIENTATION_LANDSCAPE)
+                    ? Math.min(fromTop, fromBottom)
+                    : Math.min(fromLeft, fromRight);
+        } else {
+            shortest = Math.min(Math.min(fromLeft, fromRight), Math.min(fromTop, fromBottom));
+        }
+        if (shortest == fromLeft) {
             boundsOut.offsetTo(movementBounds.left, boundedTop);
-        } else if (fromTop <= fromLeft && fromTop <= fromRight && fromTop <= fromBottom) {
+        } else if (shortest == fromTop) {
             boundsOut.offsetTo(boundedLeft, movementBounds.top);
-        } else if (fromRight < fromLeft && fromRight < fromTop && fromRight < fromBottom) {
+        } else if (shortest == fromRight) {
             boundsOut.offsetTo(movementBounds.right, boundedTop);
         } else {
             boundsOut.offsetTo(boundedLeft, movementBounds.bottom);
@@ -358,7 +373,8 @@
                 }
                 // Fall through
             case SNAP_MODE_CORNERS_ONLY:
-            case SNAP_MODE_CORNERS_AND_EDGES:
+            case SNAP_MODE_EDGE_MAGNET_CORNERS:
+            case SNAP_MODE_LONG_EDGE_MAGNET_CORNERS:
                 mSnapGravities.add(Gravity.TOP | Gravity.LEFT);
                 mSnapGravities.add(Gravity.TOP | Gravity.RIGHT);
                 mSnapGravities.add(Gravity.BOTTOM | Gravity.LEFT);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index be69d9f8..d0fbe7c 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -237,6 +237,35 @@
         return false;
     }
 
+    @NonNull
+    public static <T> List<T> filter(@Nullable List<?> list, Class<T> c) {
+        if (isEmpty(list)) return Collections.emptyList();
+        ArrayList<T> result = null;
+        for (int i = 0; i < list.size(); i++) {
+            final Object item = list.get(i);
+            if (c.isInstance(item)) {
+                result = add(result, (T) item);
+            }
+        }
+        return emptyIfNull(result);
+    }
+
+    public static <T> boolean any(@Nullable List<T> items,
+            java.util.function.Predicate<T> predicate) {
+        return find(items, predicate) != null;
+    }
+
+    @Nullable
+    public static <T> T find(@Nullable List<T> items,
+            java.util.function.Predicate<T> predicate) {
+        if (isEmpty(items)) return null;
+        for (int i = 0; i < items.size(); i++) {
+            final T item = items.get(i);
+            if (predicate.test(item)) return item;
+        }
+        return null;
+    }
+
     public static long total(@Nullable long[] array) {
         long total = 0;
         if (array != null) {
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
new file mode 100644
index 0000000..a208ccb
--- /dev/null
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.internal.util;
+
+import android.annotation.Nullable;
+
+import libcore.util.Objects;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+public class BitUtils {
+    private BitUtils() {}
+
+    public static boolean maskedEquals(long a, long b, long mask) {
+        return (a & mask) == (b & mask);
+    }
+
+    public static boolean maskedEquals(byte a, byte b, byte mask) {
+        return (a & mask) == (b & mask);
+    }
+
+    public static boolean maskedEquals(byte[] a, byte[] b, @Nullable byte[] mask) {
+        if (a == null || b == null) return a == b;
+        Preconditions.checkArgument(a.length == b.length, "Inputs must be of same size");
+        if (mask == null) return Arrays.equals(a, b);
+        Preconditions.checkArgument(a.length == mask.length, "Mask must be of same size as inputs");
+        for (int i = 0; i < mask.length; i++) {
+            if (!maskedEquals(a[i], b[i], mask[i])) return false;
+        }
+        return true;
+    }
+
+    public static boolean maskedEquals(UUID a, UUID b, @Nullable UUID mask) {
+        if (mask == null) {
+            return Objects.equal(a, b);
+        }
+        return maskedEquals(a.getLeastSignificantBits(), b.getLeastSignificantBits(),
+                    mask.getLeastSignificantBits())
+                && maskedEquals(a.getMostSignificantBits(), b.getMostSignificantBits(),
+                    mask.getMostSignificantBits());
+    }
+}
diff --git a/core/java/com/android/internal/view/SurfaceCallbackHelper.java b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
index 5b6a82c..507b673 100644
--- a/core/java/com/android/internal/view/SurfaceCallbackHelper.java
+++ b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
@@ -17,14 +17,11 @@
 package com.android.internal.view;
 
 import android.os.RemoteException;
-import android.view.IWindow;
-import android.view.IWindowSession;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
 public class SurfaceCallbackHelper {
-    IWindowSession mSession;
-    IWindow.Stub mWindow;
+    Runnable mRunnable;
 
     int mFinishDrawingCollected = 0;
     int mFinishDrawingExpected = 0;
@@ -37,26 +34,18 @@
                     if (mFinishDrawingCollected < mFinishDrawingExpected) {
                         return;
                     }
-                    try {
-                        mSession.finishDrawing(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    mRunnable.run();
                 }
             }
     };
 
-    public SurfaceCallbackHelper(IWindowSession session,
-            IWindow.Stub window) {
-        mSession = session;
-        mWindow = window;
+    public SurfaceCallbackHelper(Runnable callbacksCollected) {
+        mRunnable = callbacksCollected;
     }
 
     public void dispatchSurfaceRedrawNeededAsync(SurfaceHolder holder, SurfaceHolder.Callback callbacks[]) {
         if (callbacks == null || callbacks.length == 0) {
-            try {
-                mSession.finishDrawing(mWindow);
-            } catch (RemoteException e) {
-            }
+            mRunnable.run();
             return;
         }
 
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c9f9d6f..95b25932 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -197,7 +197,6 @@
     $(JNI_H_INCLUDE) \
     $(LOCAL_PATH)/android/graphics \
     $(LOCAL_PATH)/../../libs/hwui \
-    $(LOCAL_PATH)/../../../native/opengl/libs \
     $(LOCAL_PATH)/../../../native/vulkan/include \
     $(call include-path-for, bluedroid) \
     $(call include-path-for, libhardware)/hardware \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 417ef8a0..c1bb69d 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -633,8 +633,7 @@
         return nullObjectReturn("Could not open file");
     }
 
-    std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file,
-            SkFILEStream::kCallerPasses_Ownership));
+    std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file));
 
     // If there is no offset for the file descriptor, we use SkFILEStream directly.
     if (::lseek(descriptor, 0, SEEK_CUR) == 0) {
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 7e417b4..a77ed62 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -42,53 +42,16 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static void Shader_destructor(JNIEnv* env, jobject o, jlong shaderHandle, jlong shaderWithLMHandle)
-{
+static void Shader_safeUnref(JNIEnv* env, jobject o, jlong shaderHandle) {
     SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
     SkSafeUnref(shader);
 }
 
-static jlong Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, jlong matrixHandle)
-{
-    // ensure we have a valid matrix to use
-    const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    if (NULL == matrix) {
-        matrix = &SkMatrix::I();
-    }
-
-    // The current shader will no longer need a direct reference owned by Shader.java
-    // as all the data needed is contained within the newly created LocalMatrixShader.
-    SkASSERT(shaderHandle);
-    sk_sp<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));
-
-    // Attempt to peel off an existing proxy shader and get the proxy's matrix. If
-    // the proxy existed and it's matrix equals the desired matrix then just return
-    // the proxy, otherwise replace it with a new proxy containing the desired matrix.
-    //
-    // refAsALocalMatrixShader(): if the shader contains a proxy then it unwraps the proxy
-    //                            returning both the underlying shader and the proxy's matrix.
-    // newWithLocalMatrix(): will return a proxy shader that wraps the provided shader and
-    //                       concats the provided local matrix with the shader's matrix.
-    //
-    // WARNING: This proxy replacement only behaves like a setter because the Java
-    //          API enforces that all local matrices are set using this call and
-    //          not passed to the constructor of the Shader.
-    SkMatrix proxyMatrix;
-    sk_sp<SkShader> baseShader = currentShader->makeAsALocalMatrixShader(&proxyMatrix);
-    if (baseShader.get()) {
-        if (proxyMatrix == *matrix) {
-            return reinterpret_cast<jlong>(currentShader.release());
-        }
-        return reinterpret_cast<jlong>(baseShader->makeWithLocalMatrix(*matrix).release());
-    }
-    return reinterpret_cast<jlong>(currentShader->makeWithLocalMatrix(*matrix).release());
-}
-
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap,
-                                      jint tileModeX, jint tileModeY)
-{
+static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
+        jint tileModeX, jint tileModeY) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkBitmap bitmap;
     if (jbitmap) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
@@ -97,8 +60,8 @@
     }
 
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    sk_sp<SkShader> shader = image->makeShader((SkShader::TileMode)tileModeX,
-                                               (SkShader::TileMode)tileModeY);
+    sk_sp<SkShader> shader = image->makeShader(
+            (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY, matrix);
 
     ThrowIAE_IfNull(env, shader.get());
     return reinterpret_cast<jlong>(shader.release());
@@ -106,10 +69,10 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong LinearGradient_create1(JNIEnv* env, jobject o,
-                                    jfloat x0, jfloat y0, jfloat x1, jfloat y1,
-                                    jintArray colorArray, jfloatArray posArray, jint tileMode)
-{
+static jlong LinearGradient_create1(JNIEnv* env, jobject o, jlong matrixPtr,
+        jfloat x0, jfloat y0, jfloat x1, jfloat y1,
+        jintArray colorArray, jfloatArray posArray, jint tileMode) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkPoint pts[2];
     pts[0].set(x0, y0);
     pts[1].set(x1, y1);
@@ -126,17 +89,17 @@
 
     SkShader* shader = SkGradientShader::MakeLinear(pts,
             reinterpret_cast<const SkColor*>(colorValues), pos, count,
-            static_cast<SkShader::TileMode>(tileMode)).release();
+            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();
 
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
     return reinterpret_cast<jlong>(shader);
 }
 
-static jlong LinearGradient_create2(JNIEnv* env, jobject o,
-                                    jfloat x0, jfloat y0, jfloat x1, jfloat y1,
-                                    jint color0, jint color1, jint tileMode)
-{
+static jlong LinearGradient_create2(JNIEnv* env, jobject o, jlong matrixPtr,
+        jfloat x0, jfloat y0, jfloat x1, jfloat y1, jint color0, jint color1, jint tileMode) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
+
     SkPoint pts[2];
     pts[0].set(x0, y0);
     pts[1].set(x1, y1);
@@ -145,7 +108,8 @@
     colors[0] = color0;
     colors[1] = color1;
 
-    SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode).release();
+    SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2,
+            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
 
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
@@ -153,8 +117,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong RadialGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat radius,
-        jintArray colorArray, jfloatArray posArray, jint tileMode) {
+static jlong RadialGradient_create1(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
+        jfloat radius, jintArray colorArray, jfloatArray posArray, jint tileMode) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkPoint center;
     center.set(x, y);
 
@@ -170,7 +135,7 @@
 
     SkShader* shader = SkGradientShader::MakeRadial(center, radius,
             reinterpret_cast<const SkColor*>(colorValues), pos, count,
-            static_cast<SkShader::TileMode>(tileMode)).release();
+            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
                                  JNI_ABORT);
 
@@ -178,8 +143,9 @@
     return reinterpret_cast<jlong>(shader);
 }
 
-static jlong RadialGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat radius,
+static jlong RadialGradient_create2(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y, jfloat radius,
         jint color0, jint color1, jint tileMode) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkPoint center;
     center.set(x, y);
 
@@ -188,15 +154,16 @@
     colors[1] = color1;
 
     SkShader* s = SkGradientShader::MakeRadial(center, radius, colors, NULL, 2,
-            (SkShader::TileMode)tileMode).release();
+            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static jlong SweepGradient_create1(JNIEnv* env, jobject, jfloat x, jfloat y,
+static jlong SweepGradient_create1(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
         jintArray jcolors, jfloatArray jpositions) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     size_t      count = env->GetArrayLength(jcolors);
     const jint* colors = env->GetIntArrayElements(jcolors, NULL);
 
@@ -208,70 +175,78 @@
 #endif
 
     SkShader* shader = SkGradientShader::MakeSweep(x, y,
-            reinterpret_cast<const SkColor*>(colors), pos, count).release();
+            reinterpret_cast<const SkColor*>(colors), pos, count, /* flags */ 0, matrix).release();
     env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
                                  JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
     return reinterpret_cast<jlong>(shader);
 }
 
-static jlong SweepGradient_create2(JNIEnv* env, jobject, jfloat x, jfloat y,
+static jlong SweepGradient_create2(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
         int color0, int color1) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkColor colors[2];
     colors[0] = color0;
     colors[1] = color1;
-    SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2).release();
+    SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2,
+            /* flags */ 0, matrix).release();
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong ComposeShader_create(JNIEnv* env, jobject o,
-        jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle)
-{
+static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
+        jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
+    const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
     SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
     SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
-    SkShader* shader = SkShader::MakeComposeShader(sk_ref_sp(shaderA),
-                                                   sk_ref_sp(shaderB),
-                                                   mode).release();
+    sk_sp<SkShader> baseShader(SkShader::MakeComposeShader(
+            sk_ref_sp(shaderA), sk_ref_sp(shaderB), mode));
+
+    SkShader* shader;
+
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
     return reinterpret_cast<jlong>(shader);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 static const JNINativeMethod gColorMethods[] = {
-    { "nativeRGBToHSV",     "(III[F)V", (void*)Color_RGBToHSV   },
-    { "nativeHSVToColor",   "(I[F)I",   (void*)Color_HSVToColor }
+    { "nativeRGBToHSV",    "(III[F)V", (void*)Color_RGBToHSV   },
+    { "nativeHSVToColor",  "(I[F)I",   (void*)Color_HSVToColor }
 };
 
 static const JNINativeMethod gShaderMethods[] = {
-    { "nativeDestructor",        "(J)V",    (void*)Shader_destructor        },
-    { "nativeSetLocalMatrix",    "(JJ)J",   (void*)Shader_setLocalMatrix    }
+    { "nativeSafeUnref",   "(J)V",    (void*)Shader_safeUnref },
 };
 
 static const JNINativeMethod gBitmapShaderMethods[] = {
-    { "nativeCreate",     "(Landroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
+    { "nativeCreate",      "(JLandroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
 };
 
 static const JNINativeMethod gLinearGradientMethods[] = {
-    { "nativeCreate1",     "(FFFF[I[FI)J",  (void*)LinearGradient_create1     },
-    { "nativeCreate2",     "(FFFFIII)J",    (void*)LinearGradient_create2     },
+    { "nativeCreate1",     "(JFFFF[I[FI)J",  (void*)LinearGradient_create1     },
+    { "nativeCreate2",     "(JFFFFIII)J",    (void*)LinearGradient_create2     },
 };
 
 static const JNINativeMethod gRadialGradientMethods[] = {
-    { "nativeCreate1",     "(FFF[I[FI)J",  (void*)RadialGradient_create1     },
-    { "nativeCreate2",     "(FFFIII)J",    (void*)RadialGradient_create2     },
+    { "nativeCreate1",     "(JFFF[I[FI)J",  (void*)RadialGradient_create1     },
+    { "nativeCreate2",     "(JFFFIII)J",    (void*)RadialGradient_create2     },
 };
 
 static const JNINativeMethod gSweepGradientMethods[] = {
-    { "nativeCreate1",     "(FF[I[F)J",  (void*)SweepGradient_create1     },
-    { "nativeCreate2",     "(FFII)J",    (void*)SweepGradient_create2     },
+    { "nativeCreate1",     "(JFF[I[F)J",  (void*)SweepGradient_create1     },
+    { "nativeCreate2",     "(JFFII)J",    (void*)SweepGradient_create2     },
 };
 
 static const JNINativeMethod gComposeShaderMethods[] = {
-    { "nativeCreate",      "(JJI)J",   (void*)ComposeShader_create     },
+    { "nativeCreate",      "(JJJI)J",   (void*)ComposeShader_create     },
 };
 
 int register_android_graphics_Shader(JNIEnv* env)
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index f221392..6e8c931 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -452,10 +452,6 @@
             const RenderProperties& props = node.properties();
             uirenderer::Rect bounds(props.getWidth(), props.getHeight());
             transform.mapRect(bounds);
-            bounds.left -= info.windowInsetLeft;
-            bounds.right -= info.windowInsetLeft;
-            bounds.top -= info.windowInsetTop;
-            bounds.bottom -= info.windowInsetTop;
 
             if (CC_LIKELY(transform.isPureTranslate())) {
                 // snap/round the computed bounds, so they match the rounding behavior
@@ -627,9 +623,9 @@
 int register_android_view_RenderNode(JNIEnv* env) {
     jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
     gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
-            "updateWindowPosition_renderWorker", "(JIIII)V");
+            "updateSurfacePosition_renderWorker", "(JIIII)V");
     gSurfaceViewPositionLostMethod = GetMethodIDOrDie(env, clazz,
-            "windowPositionLost_uiRtSync", "(J)V");
+            "surfacePositionLost_uiRtSync", "(J)V");
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 6192271..713287e 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -21,6 +21,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_os_Parcel.h"
+#include "android/graphics/GraphicBuffer.h"
 #include "android/graphics/GraphicsJNI.h"
 
 #include "core_jni_helpers.h"
@@ -496,6 +497,30 @@
     return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal);
 }
 
+static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeObject,
+        jobject graphicBuffer) {
+    Surface* surface = reinterpret_cast<Surface*>(nativeObject);
+    sp<GraphicBuffer> bp = graphicBufferForJavaObject(env, graphicBuffer);
+    if (bp == nullptr) {
+        return BAD_VALUE;
+    }
+    int err = ((ANativeWindow*)surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
+            NATIVE_WINDOW_API_CPU);
+    if (err != OK) {
+        return err;
+    }
+    err = surface->attachBuffer(bp->getNativeBuffer());
+    if (err != OK) {
+        return err;
+    }
+    err = ((ANativeWindow*)surface)->queueBuffer(surface, bp->getNativeBuffer(), -1);
+    if (err != OK) {
+        return err;
+    }
+    err = surface->disconnect(NATIVE_WINDOW_API_CPU);
+    return err;
+}
+
 namespace uirenderer {
 
 using namespace android::uirenderer::renderthread;
@@ -574,6 +599,7 @@
     {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber },
     {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode },
     {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect},
+    {"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer},
 
     // HWUI context
     {"nHwuiCreate", "(JJ)J", (void*) hwui::create },
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a81901d..6fbf49b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -693,7 +693,6 @@
     return JNI_TRUE;
 }
 
-
 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
         jobject handleObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -702,6 +701,27 @@
     ctrl->deferTransactionUntil(handle, frameNumber);
 }
 
+static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jlong surfaceObject, jlong frameNumber) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
+
+    ctrl->deferTransactionUntil(barrier, frameNumber);
+}
+
+static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jobject newParentObject) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
+
+    ctrl->reparentChildren(handle);
+}
+
+static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong nativeObject) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    ctrl->detachChildren();
+}
+
 static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
         jint scalingMode) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -824,6 +844,12 @@
             (void*)nativeSetDisplayPowerMode },
     {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
+    {"nativeDeferTransactionUntilSurface", "(JJJ)V",
+            (void*)nativeDeferTransactionUntilSurface },
+    {"nativeReparentChildren", "(JLandroid/os/IBinder;)V",
+            (void*)nativeReparentChildren } ,
+    {"nativeSeverChildren", "(J)V",
+            (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp
index dad6958..508d897 100644
--- a/core/jni/android_view_SurfaceSession.cpp
+++ b/core/jni/android_view_SurfaceSession.cpp
@@ -24,6 +24,7 @@
 #include <utils/RefBase.h>
 
 #include <gui/SurfaceComposerClient.h>
+#include <gui/Surface.h>
 
 namespace android {
 
@@ -45,6 +46,13 @@
     return reinterpret_cast<jlong>(client);
 }
 
+static jlong nativeCreateScoped(JNIEnv* env, jclass clazz, jlong surfaceObject) {
+    Surface *parent = reinterpret_cast<Surface*>(surfaceObject);
+    SurfaceComposerClient* client = new SurfaceComposerClient(parent->getIGraphicBufferProducer());
+    client->incStrong((void*)nativeCreate);
+    return reinterpret_cast<jlong>(client);
+}
+
 static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
     SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr);
     client->decStrong((void*)nativeCreate);
@@ -55,11 +63,12 @@
     client->dispose();
 }
 
-
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
     { "nativeCreate", "()J",
             (void*)nativeCreate },
+    { "nativeCreateScoped", "(J)J",
+            (void*)nativeCreateScoped },
     { "nativeDestroy", "(J)V",
             (void*)nativeDestroy },
     { "nativeKill", "(J)V",
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 37eae48a..e1c0a21 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -27,7 +27,7 @@
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
-#include <EGL/egl_cache.h>
+#include <private/EGL/cache.h>
 
 #include <utils/Looper.h>
 #include <utils/RefBase.h>
@@ -178,13 +178,9 @@
             }
         }
         // TODO: This is hacky
-        info.windowInsetLeft = -stagingProperties().getLeft();
-        info.windowInsetTop = -stagingProperties().getTop();
         info.updateWindowPositions = true;
         RenderNode::prepareTree(info);
         info.updateWindowPositions = false;
-        info.windowInsetLeft = 0;
-        info.windowInsetTop = 0;
         info.errorHandler = nullptr;
     }
 
@@ -891,7 +887,7 @@
 static void android_view_ThreadedRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
         jstring diskCachePath) {
     const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
-    egl_cache_t::get()->setCacheFilename(cacheArray);
+    android::egl_set_cache_filename(cacheArray);
     env->ReleaseStringUTFChars(diskCachePath, cacheArray);
 }
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 56bec18..1ac05f9 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -22,9 +22,9 @@
 #include <utils/misc.h>
 
 
-#include <EGL/egl_display.h>
 #include <EGL/egl.h>
 #include <GLES/gl.h>
+#include <private/EGL/display.h>
 
 #include <gui/Surface.h>
 #include <gui/GLConsumer.h>
@@ -180,8 +180,7 @@
 
 static jint jni_getInitCount(JNIEnv *_env, jobject _clazz, jobject display) {
     EGLDisplay dpy = getDisplay(_env, display);
-    egl_display_t* eglDisplay = get_display_nowake(dpy);
-    return eglDisplay ? eglDisplay->getRefsCount() : 0;
+    return android::egl_get_init_count(dpy);
 }
 
 static jboolean jni_eglReleaseThread(JNIEnv *_env, jobject _this) {
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index ee50c29..7eb0582 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -341,7 +341,7 @@
     SettingProto input_methods_subtype_history = 5;
     SettingProto input_method_selector_visibility = 6;
     SettingProto voice_interaction_service = 7;
-    SettingProto auto_fill_service = 8;
+    SettingProto autofill_service = 8;
     SettingProto bluetooth_hci_log = 9;
     SettingProto user_setup_complete = 10;
     SettingProto completed_category_prefix = 11;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c2a2e69..c991f22 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -216,6 +216,7 @@
     <protected-broadcast android:name="android.btopp.intent.action.OPEN_INBOUND" />
     <protected-broadcast android:name="android.btopp.intent.action.TRANSFER_COMPLETE" />
     <protected-broadcast android:name="android.btopp.intent.action.ACCEPT" />
+    <protected-broadcast android:name="android.btopp.intent.action.DECLINE" />
     <protected-broadcast android:name="com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN" />
     <protected-broadcast android:name="com.android.bluetooth.pbap.authchall" />
     <protected-broadcast android:name="com.android.bluetooth.pbap.userconfirmtimeout" />
@@ -2305,6 +2306,10 @@
     <permission android:name="android.permission.RETRIEVE_WINDOW_TOKEN"
         android:protectionLevel="signature" />
 
+    <!-- @hide Allows an application to modify accessibility information from another app. -->
+    <permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA"
+                android:protectionLevel="signature" />
+
     <!-- @hide Allows an application to collect frame statistics -->
     <permission android:name="android.permission.FRAME_STATS"
          android:protectionLevel="signature" />
@@ -2440,10 +2445,16 @@
     <permission android:name="android.permission.BIND_VOICE_INTERACTION"
         android:protectionLevel="signature" />
 
-    <!-- Must be required by a {@link android.service.autofill.AutoFillService},
+    <!-- Must be required by a {@link android.service.autofill.AutofillService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
     -->
+    <permission android:name="android.permission.BIND_AUTOFILL"
+        android:protectionLevel="signature" />
+
+    <!--  TODO(b/35956626): temporary until clients change to BIND_AUTOFILL
+         <p>Protection level: signature
+    -->
     <permission android:name="android.permission.BIND_AUTO_FILL"
         android:protectionLevel="signature" />
 
@@ -3285,6 +3296,11 @@
     <permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows an application to show notifications before the device is provisioned.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.NOTIFICATION_DURING_SETUP"
+                android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an application to manage auto-fill sessions.
          @hide  <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.MANAGE_AUTO_FILL"
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index 7f57ded..6edb88e 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -28,7 +28,7 @@
 
     <!-- see comment in values/config.xml -->
     <dimen name="config_prefDialogWidth">580dp</dimen>
-    
+
     <!-- If true, the screen can be rotated via the accelerometer in all 4
          rotations as the default behavior. -->
     <bool name="config_allowAllRotations">true</bool>
@@ -41,5 +41,15 @@
     <dimen name="config_minScalingSpan">32mm</dimen>
 
     <integer name="config_dockedStackDividerSnapMode">1</integer>
+
+    <!-- The snap mode to use for picture-in-picture. These values correspond to constants defined
+         in PipSnapAlgorithm and should not be changed independently.
+             0 - Snap to the four corners
+             1 - Snap to the four corners and the mid-points on the long edge in each orientation
+             2 - Snap anywhere along the edge of the screen
+             3 - Snap anywhere along the edge of the screen and magnet to corners
+             4 - Snap to the long edges in each orientation and magnet to corners
+    -->
+    <integer name="config_pictureInPictureSnapMode">3</integer>
 </resources>
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b3cb2c7..21c8780 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2293,22 +2293,22 @@
             <enum name="auto" value="0x00000010" />
         </attr>
 
-        <!-- Controls the auto-fill behavior for this view. -->
-        <attr name="autoFillMode">
+        <!-- Controls the autofill behavior for this view. -->
+        <attr name="autofillMode">
             <!-- Inherit the behavior from the parent. If there is no parent it is auto. This is the
                  default value for this attribute.-->
             <enum name="inherit" value="0" />
-            <!-- Allows this view to automatically trigger an auto-fill request when it get focus.
+            <!-- Allows this view to automatically trigger an autofill request when it get focus.
                  -->
             <enum name="auto" value="1" />
-            <!-- Do not trigger an auto-fill request when this view is focused. The user can still
-                 manually force an auto-fill request for this view. -->
+            <!-- Do not trigger an autofill request when this view is focused. The user can still
+                 manually force an autofill request for this view. -->
             <enum name="manual" value="2" />
         </attr>
 
-        <!-- Describes the content of a view so that a auto-fill service can fill in the appropriate
+        <!-- Describes the content of a view so that a autofill service can fill in the appropriate
              data. Multiple flags can be combined to mean e.g. emailAddress or postalAddress. -->
-        <attr name="autoFillHint">
+        <attr name="autofillHint">
             <!-- No hint. -->
             <flag name="none" value="0" />
             <!-- The view contains an email address. -->
@@ -7717,14 +7717,21 @@
     </declare-styleable>
 
     <!-- =============================== -->
-    <!-- AutoFill attributes -->
+    <!-- Autofill attributes -->
     <!-- =============================== -->
     <eat-comment />
 
     <!-- Use <code>autofill-service</code> as the root tag of the XML resource that describes a
-         {@link android.service.autofill.AutoFillService}, which is referenced from its
+         {@link android.service.autofill.AutofillService}, which is referenced from its
          {@link android.service.autofill#SERVICE_META_DATA} meta-data entry.
     -->
+    <declare-styleable name="AutofillService">
+        <!-- Fully qualified class name of an activity that allows the user to modify
+             the settings for this service. -->
+        <attr name="settingsActivity" />
+    </declare-styleable>
+
+    <!--  TODO(b/35956626): temporary until clients change to AutofillService -->
     <declare-styleable name="AutoFillService">
         <!-- Fully qualified class name of an activity that allows the user to modify
              the settings for this service. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a3a0c83..6e0d9dc 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -470,6 +470,8 @@
     <integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
     <integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
     <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
+    <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
+    <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
     <!-- Integer parameters of the wifi to cellular handover feature
          wifi should not stick to bad networks -->
     <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
@@ -2569,6 +2571,16 @@
          ratio larger than this is considered to wide and short to be usable. -->
     <item name="config_pictureInPictureMaxAspectRatio" format="float" type="dimen">2.35</item>
 
+    <!-- The snap mode to use for picture-in-picture. These values correspond to constants defined
+         in PipSnapAlgorithm and should not be changed independently.
+             0 - Snap to the four corners
+             1 - Snap to the four corners and the mid-points on the long edge in each orientation
+             2 - Snap anywhere along the edge of the screen
+             3 - Snap anywhere along the edge of the screen and magnet to corners
+             4 - Snap to the long edges in each orientation and magnet to corners
+    -->
+    <integer name="config_pictureInPictureSnapMode">4</integer>
+
     <!-- Controls the snap mode for the docked stack divider
              0 - 3 snap targets: left/top has 16:9 ratio, 1:1, and right/bottom has 16:9 ratio
              1 - 3 snap targets: fixed ratio, 1:1, (1 - fixed ratio)
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 613616f..f8a071d 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -135,4 +135,7 @@
 
   <!-- ItemTouchHelper uses this id to save a View's original elevation. -->
   <item type="id" name="item_touch_helper_previous_elevation"/>
+
+  <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. -->
+  <item type="id" name="accessibilityActionMoveWindow" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b664448..359fbcb 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2797,12 +2797,12 @@
         <public name="numericModifiers" />
         <public name="fontProviderAuthority" />
         <public name="fontProviderQuery" />
-        <public name="autoFillMode" />
+        <public name="autofillMode" />
         <public name="primaryContentAlpha" />
         <public name="secondaryContentAlpha" />
         <public name="requiredFeature" />
         <public name="requiredNotFeature" />
-        <public name="autoFillHint" />
+        <public name="autofillHint" />
         <public name="fontProviderPackage" />
         <public name="importantForAutofill" />
     </public-group>
@@ -2812,6 +2812,7 @@
 
     <public-group type="id" first-id="0x01020041">
         <public name="textAssist" />
+        <public name="accessibilityActionMoveWindow" />
     </public-group>
 
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bd8d572..d1d406d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3167,13 +3167,13 @@
     <skip />
     <!-- Name of notification channel the system post notification to inform the use about apps
          that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] -->
-    <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> draw over other apps</string>
+    <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> displaying over other apps</string>
     <!-- Notification title when an application is displaying ui on-top of other apps
          [CHAR LIMIT=30] -->
-    <string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> app displaying on top.</string>
+    <string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is displaying over other apps.</string>
     <!-- Notification body when an application is displaying ui on-top of other apps
          [CHAR LIMIT=NONE] -->
-    <string name="alert_windows_notification_message">Parts of this app may remain visible at all times. If this feature isn\'t working correctly, turn it off.</string>
+    <string name="alert_windows_notification_message">If you don’t want <xliff:g id="name" example="Google Maps">%s</xliff:g> to use this feature, tap to open settings and turn it off.</string>
     <!-- Notification action to turn-off app displaying on-top of other apps. [CHAR LIMIT=20] -->
     <string name="alert_windows_notification_turn_off_action">TURN OFF</string>
 
@@ -3195,11 +3195,15 @@
     <string name="ext_media_unmountable_notification_title">Corrupted <xliff:g id="name" example="SD card">%s</xliff:g></string>
     <!-- Notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
     <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Tap to fix.</string>
+    <!-- TV-specifiv notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
+    <string name="ext_media_unmountable_notification_message" product="tv"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Select to fix.</string>
 
     <!-- Notification title when external media is unsupported [CHAR LIMIT=30] -->
     <string name="ext_media_unsupported_notification_title">Unsupported <xliff:g id="name" example="SD card">%s</xliff:g></string>
     <!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] -->
     <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Tap to set up in a supported format.</string>
+    <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
+    <string name="ext_media_unsupported_notification_message" product="tv">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Select to set up in a supported format.</string>
 
     <!-- Notification title when external media is unsafely removed [CHAR LIMIT=30] -->
     <string name="ext_media_badremoval_notification_title"><xliff:g id="name" example="SD card">%s</xliff:g> unexpectedly removed</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 32babab..0c318cf 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1556,6 +1556,7 @@
   <java-symbol type="dimen" name="docked_stack_minimize_thickness" />
   <java-symbol type="dimen" name="pip_minimized_visible_size" />
   <java-symbol type="integer" name="config_dockedStackDividerSnapMode" />
+  <java-symbol type="integer" name="config_pictureInPictureSnapMode" />
   <java-symbol type="fraction" name="docked_stack_divider_fixed_ratio" />
   <java-symbol type="fraction" name="thumbnail_fullscreen_scale" />
   <java-symbol type="integer" name="thumbnail_width_tv" />
diff --git a/core/tests/coretests/src/android/metrics/LogMakerTest.java b/core/tests/coretests/src/android/metrics/LogMakerTest.java
index ece44be..bab9f63 100644
--- a/core/tests/coretests/src/android/metrics/LogMakerTest.java
+++ b/core/tests/coretests/src/android/metrics/LogMakerTest.java
@@ -171,6 +171,14 @@
         assertEquals(null, builder.getPackageName());
     }
 
+    public void testSetAndClearPid() {
+        LogMaker builder = new LogMaker(0);
+        builder.setProcessId(1);
+        assertEquals(1, builder.getProcessId());
+        builder.clearProcessId();
+        assertEquals(-1, builder.getProcessId());
+    }
+
     public void testGiantLogOmitted() {
         LogMaker badBuilder = new LogMaker(0);
         StringBuilder b = new StringBuilder();
diff --git a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
index d1c68a9..09cbbff 100644
--- a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
@@ -52,7 +52,7 @@
         mResolver = getMockContentResolver();
     }
 
-    public void testFindPath_docUri() throws Exception {
+    public void testFindDocumentPath_docUri() throws Exception {
         final Path expected = new Path(ROOT_ID, Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID));
         mProvider.nextPath = expected;
 
@@ -65,7 +65,7 @@
         }
     }
 
-    public void testFindPath_treeUri() throws Exception {
+    public void testFindDocumentPath_treeUri() throws Exception {
         mProvider.nextIsChildDocument = true;
 
         final Path expected = new Path(null, Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID));
@@ -73,12 +73,13 @@
 
         final Uri docUri = buildTreeDocumentUri(
                 TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        final List<String> actual = DocumentsContract.findDocumentPath(mResolver, docUri);
+        final Path actual = DocumentsContract.findDocumentPath(mResolver, docUri);
 
-        assertEquals(expected.getPath(), actual);
+        assertNull(actual.getRootId());
+        assertEquals(expected.getPath(), actual.getPath());
     }
 
-    public void testFindPath_treeUri_throwsOnNonChildDocument() throws Exception {
+    public void testFindDocumentPath_treeUri_throwsOnNonChildDocument() throws Exception {
         mProvider.nextPath = new Path(null, Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID));
 
         final Uri docUri = buildTreeDocumentUri(
@@ -86,18 +87,28 @@
         assertNull(DocumentsContract.findDocumentPath(mResolver, docUri));
     }
 
-    public void testFindPath_treeUri_erasesNonNullRootId() throws Exception {
+    public void testFindDocumentPath_treeUri_erasesNonNullRootId() throws Exception {
         mProvider.nextIsChildDocument = true;
 
         mProvider.nextPath = new Path(ROOT_ID, Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID));
 
         final Uri docUri = buildTreeDocumentUri(
                 TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        try (ContentProviderClient client =
-                     mResolver.acquireUnstableContentProviderClient(docUri)) {
-            Path path = DocumentsContract.findDocumentPath(client, docUri);
-            assertNull(path.getRootId());
-        }
+        Path path = DocumentsContract.findDocumentPath(mResolver, docUri);
+        assertNull(path.getRootId());
+        assertEquals(Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID), path.getPath());
+    }
+
+    public void testFindDocumentPath_treeUri_erasesDocsOutsideTree() throws Exception {
+        mProvider.nextIsChildDocument = true;
+
+        mProvider.nextPath = new Path(
+                null, Arrays.asList(ANCESTOR_DOCUMENT_ID, PARENT_DOCUMENT_ID, DOCUMENT_ID));
+
+        final Uri docUri = buildTreeDocumentUri(
+                TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
+        Path path = DocumentsContract.findDocumentPath(mResolver, docUri);
+        assertEquals(Arrays.asList(PARENT_DOCUMENT_ID, DOCUMENT_ID), path.getPath());
     }
 
     private static Uri buildTreeDocumentUri(String authority, String parentDocId, String docId) {
diff --git a/core/tests/coretests/src/android/provider/FontsContractTest.java b/core/tests/coretests/src/android/provider/FontsContractTest.java
index db623a4..d90fc2b 100644
--- a/core/tests/coretests/src/android/provider/FontsContractTest.java
+++ b/core/tests/coretests/src/android/provider/FontsContractTest.java
@@ -15,12 +15,12 @@
  */
 package android.provider;
 
-import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.pm.ApplicationInfo;
@@ -28,6 +28,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.Signature;
+import android.database.MatrixCursor;
 import android.graphics.Typeface;
 import android.graphics.fonts.FontRequest;
 import android.graphics.fonts.FontResult;
@@ -72,11 +73,12 @@
         mResultReceiver = mock(ResultReceiver.class);
     }
 
-    public void testGetFontFromProvider() {
+    public void testGetFontFromProvider_resultOK() {
         mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
 
         final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        verify(mResultReceiver).send(eq(FontsContract.RESULT_CODE_OK), bundleCaptor.capture());
+        verify(mResultReceiver).send(
+                eq(FontsContract.Columns.RESULT_CODE_OK), bundleCaptor.capture());
 
         Bundle bundle = bundleCaptor.getValue();
         assertNotNull(bundle);
@@ -96,7 +98,8 @@
 
         final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
         mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
-        verify(mResultReceiver).send(eq(FontsContract.RESULT_CODE_OK), bundleCaptor.capture());
+        verify(mResultReceiver).send(
+                eq(FontsContract.Columns.RESULT_CODE_OK), bundleCaptor.capture());
 
         Bundle bundle = bundleCaptor.getValue();
         assertNotNull(bundle);
@@ -111,11 +114,79 @@
         assertNotNull(fontResult.getFileDescriptor());
     }
 
+    public void testGetFontFromProvider_resultFontNotFound() {
+        // Make the provider return unknown
+        mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND,null);
+    }
+
+    public void testGetFontFromProvider_resultFontUnavailable() {
+        // Make the provider return font unavailable
+        mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE,null);
+    }
+
+    public void testGetFontFromProvider_resultMalformedQuery() {
+        // Make the provider return font unavailable
+        mProvider.setResultCode(FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY,null);
+    }
+
+    public void testGetFontFromProvider_resultFontNotFoundSecondRow() {
+        MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
+                FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
+                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
+        mProvider.setCustomCursor(cursor);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+    }
+
+    public void testGetFontFromProvider_resultFontNotFoundOtherRow() {
+        MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
+                FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
+                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_OK});
+        mProvider.setCustomCursor(cursor);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+    }
+
+    public void testGetFontFromProvider_resultCodeIsNegativeNumber() {
+        MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
+                FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
+                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL, -5});
+        mProvider.setCustomCursor(cursor);
+        mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
+
+        verify(mResultReceiver).send(FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
+    }
+
     public void testGetProvider_providerNotFound() {
         when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(null);
 
-        ProviderInfo result = mContract.getProvider(request);
+        ProviderInfo result = mContract.getProvider(request, mResultReceiver);
 
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
         assertNull(result);
     }
 
@@ -124,8 +195,9 @@
         info.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
         when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info);
 
-        ProviderInfo result = mContract.getProvider(request);
+        ProviderInfo result = mContract.getProvider(request, mResultReceiver);
 
+        verifyZeroInteractions(mResultReceiver);
         assertEquals(info, result);
     }
 
@@ -136,8 +208,10 @@
         when(mPackageManager.resolveContentProvider(anyString(), anyInt())).thenReturn(info);
 
         ProviderInfo result = mContract.getProvider(
-                new FontRequest(TestFontsProvider.AUTHORITY, "com.wrong.package", "query"));
+                new FontRequest(TestFontsProvider.AUTHORITY, "com.wrong.package", "query"),
+                mResultReceiver);
 
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
         assertNull(result);
     }
 
@@ -146,8 +220,9 @@
         setupPackageManager();
 
         // The default request is missing the certificates info.
-        ProviderInfo result = mContract.getProvider(request);
+        ProviderInfo result = mContract.getProvider(request, mResultReceiver);
 
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
         assertNull(result);
     }
 
@@ -159,8 +234,9 @@
         List<byte[]> certList = Arrays.asList(wrongCert);
         FontRequest requestWrongCerts = new FontRequest(
                 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
-        ProviderInfo result = mContract.getProvider(requestWrongCerts);
+        ProviderInfo result = mContract.getProvider(requestWrongCerts, mResultReceiver);
 
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
         assertNull(result);
     }
 
@@ -171,8 +247,9 @@
         List<byte[]> certList = Arrays.asList(BYTE_ARRAY);
         FontRequest requestRightCerts = new FontRequest(
                 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
-        ProviderInfo result = mContract.getProvider(requestRightCerts);
+        ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
 
+        verifyZeroInteractions(mResultReceiver);
         assertEquals(info, result);
     }
 
@@ -184,9 +261,10 @@
         List<byte[]> certList = Arrays.asList(wrongCert, BYTE_ARRAY);
         FontRequest requestRightCerts = new FontRequest(
                 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", Arrays.asList(certList));
-        ProviderInfo result = mContract.getProvider(requestRightCerts);
+        ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
 
         // There is one too many certs, should fail as the set doesn't match.
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_WRONG_CERTIFICATES, null);
         assertNull(result);
     }
 
@@ -200,8 +278,9 @@
         certList.add(Arrays.asList(BYTE_ARRAY));
         FontRequest requestRightCerts = new FontRequest(
                 TestFontsProvider.AUTHORITY, PACKAGE_NAME, "query", certList);
-        ProviderInfo result = mContract.getProvider(requestRightCerts);
+        ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
 
+        verifyZeroInteractions(mResultReceiver);
         assertEquals(info, result);
     }
 
@@ -213,8 +292,9 @@
         certList.add(Arrays.asList(BYTE_ARRAY));
         FontRequest requestRightCerts = new FontRequest(
                 TestFontsProvider.AUTHORITY, "com.wrong.package.name", "query", certList);
-        ProviderInfo result = mContract.getProvider(requestRightCerts);
+        ProviderInfo result = mContract.getProvider(requestRightCerts, mResultReceiver);
 
+        verify(mResultReceiver).send(FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND, null);
         assertNull(result);
     }
 
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 696d498..903ef84 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -385,7 +385,7 @@
                  Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
                  Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
                  Settings.Secure.ASSIST_STRUCTURE_ENABLED,
-                 Settings.Secure.AUTO_FILL_SERVICE,
+                 Settings.Secure.AUTOFILL_SERVICE,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
diff --git a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
index d61049d..1bd8ff6 100644
--- a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
@@ -85,7 +85,7 @@
     }
 
     @Override
-    public Path findDocumentPath(String documentId, @Nullable String parentDocumentId) {
+    public Path findDocumentPath(@Nullable String parentDocumentId, String documentId) {
         lastDocumentId = documentId;
         lastParentDocumentId = parentDocumentId;
 
diff --git a/core/tests/coretests/src/android/provider/TestFontsProvider.java b/core/tests/coretests/src/android/provider/TestFontsProvider.java
index 6d40f37..13f5318 100644
--- a/core/tests/coretests/src/android/provider/TestFontsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestFontsProvider.java
@@ -41,6 +41,15 @@
 
     private ParcelFileDescriptor mPfd;
     private boolean mReturnAllFields = true;
+    private int mResultCode = FontsContract.Columns.RESULT_CODE_OK;
+    private MatrixCursor mCustomCursor = null;
+
+    /**
+     * Used by tests to modify the result code that should be returned.
+     */
+    void setResultCode(int resultCode) {
+        mResultCode = resultCode;
+    }
 
     /**
      * Used by tests to switch whether all fields should be returned or not.
@@ -49,6 +58,13 @@
         mReturnAllFields = returnAllFields;
     }
 
+    /**
+     * Used by tests to control what values are returned.
+     */
+    void setCustomCursor(MatrixCursor cursor) {
+        mCustomCursor = cursor;
+    }
+
     @Override
     public boolean onCreate() {
         mPfd = createFontFile();
@@ -58,12 +74,15 @@
     @Override
     public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
             @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+        if (mCustomCursor != null) {
+            return mCustomCursor;
+        }
         MatrixCursor cursor;
         if (mReturnAllFields) {
             cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
                     FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
-                    FontsContract.Columns.STYLE });
-            cursor.addRow(new Object[] { 1, TTC_INDEX, VARIATION_SETTINGS, STYLE });
+                    FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
+            cursor.addRow(new Object[] { 1, TTC_INDEX, VARIATION_SETTINGS, STYLE, mResultCode });
         } else {
             cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID });
             cursor.addRow(new Object[] { 1 });
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
new file mode 100644
index 0000000..ee37cb9
--- /dev/null
+++ b/data/sounds/AudioTv.mk
@@ -0,0 +1,125 @@
+# Copyright 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := frameworks/base/data/sounds
+
+PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
+    $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
+    $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
+    $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
+    $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
+    $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \
+    $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
+    $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
+    $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+    $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+    $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \
+    $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \
+    $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
+    $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
+    $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+    $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
+    $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+    $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+    $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \
+    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+    $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+    $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
+    $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
+    $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
+    $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
+    $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
+    $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
+    $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
+    $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \
+    $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \
+    $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \
+    $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
+    $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+    $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
+    $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \
+    $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
+    $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
+    $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \
+    $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \
+    $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \
+    $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
+    $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
+    $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \
+    $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+    $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
+    $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \
+    $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
+    $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
+    $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
+    $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \
+    $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \
+    $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
+    $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
+    $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
+    $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
+    $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
+    $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 9211225..7e6756e 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -28,23 +28,56 @@
      * @hide
      */
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
-    public final Bitmap mBitmap;
+    public Bitmap mBitmap;
 
-    private TileMode mTileX;
-    private TileMode mTileY;
+    private int mTileX;
+    private int mTileY;
 
     /**
      * Call this to create a new shader that will draw with a bitmap.
      *
-     * @param bitmap            The bitmap to use inside the shader
-     * @param tileX             The tiling mode for x to draw the bitmap in.
-     * @param tileY             The tiling mode for y to draw the bitmap in.
+     * @param bitmap The bitmap to use inside the shader
+     * @param tileX The tiling mode for x to draw the bitmap in.
+     * @param tileY The tiling mode for y to draw the bitmap in.
      */
-    public BitmapShader(@NonNull Bitmap bitmap, TileMode tileX, TileMode tileY) {
+    public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
+        set(bitmap, tileX, tileY);
+    }
+
+    private BitmapShader(Bitmap bitmap, int tileX, int tileY) {
+        setInternal(bitmap, tileX, tileY);
+    }
+
+    /**
+     * Reinitialize the BitmapShader's Bitmap and tile modes.
+     *
+     * @param bitmap The bitmap to use inside the shader
+     * @param tileX The tiling mode for x to draw the bitmap in.
+     * @param tileY The tiling mode for y to draw the bitmap in.
+     */
+    public void set(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
+        if (tileX == null || tileY == null) {
+            throw new IllegalArgumentException();
+        }
+        setInternal(bitmap, tileX.nativeInt, tileY.nativeInt);
+    }
+
+    private void setInternal(Bitmap bitmap, int tileX, int tileY) {
+        if (bitmap == null) {
+            throw new IllegalArgumentException("Bitmap must be non-null");
+        }
+        if (bitmap == mBitmap && tileX == mTileX && tileY == mTileY) {
+            return;
+        }
+        discardNativeInstance();
         mBitmap = bitmap;
         mTileX = tileX;
         mTileY = tileY;
-        init(nativeCreate(bitmap, tileX.nativeInt, tileY.nativeInt));
+    }
+
+    @Override
+    long createNativeInstance(long nativeMatrix) {
+        return nativeCreate(nativeMatrix, mBitmap, mTileX, mTileY);
     }
 
     /**
@@ -57,6 +90,6 @@
         return copy;
     }
 
-    private static native long nativeCreate(Bitmap bitmap, int shaderTileModeX,
-            int shaderTileModeY);
+    private static native long nativeCreate(long nativeMatrix, Bitmap bitmap,
+            int shaderTileModeX, int shaderTileModeY);
 }
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 36fc596..8438bf2 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -16,44 +16,107 @@
 
 package android.graphics;
 
+
+import android.annotation.NonNull;
+
 /** A subclass of shader that returns the composition of two other shaders, combined by
     an {@link android.graphics.Xfermode} subclass.
 */
 public class ComposeShader extends Shader {
 
+    Shader mShaderA;
+    private long mNativeInstanceShaderA;
+    Shader mShaderB;
+    private long mNativeInstanceShaderB;
     private int mPorterDuffMode;
-    final Shader mShaderA;
-    final Shader mShaderB;
 
-    /** Create a new compose shader, given shaders A, B, and a combining mode.
-        When the mode is applied, it will be given the result from shader A as its
-        "dst", and the result from shader B as its "src".
-        @param shaderA  The colors from this shader are seen as the "dst" by the mode
-        @param shaderB  The colors from this shader are seen as the "src" by the mode
-        @param mode     The mode that combines the colors from the two shaders. If mode
-                        is null, then SRC_OVER is assumed.
+    /**
+     * Create a new compose shader, given shaders A, B, and a combining mode.
+     * When the mode is applied, it will be given the result from shader A as its
+     * "dst", and the result from shader B as its "src".
+     *
+     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
+     * @param shaderB  The colors from this shader are seen as the "src" by the mode
+     * @param mode     The mode that combines the colors from the two shaders. If mode
+     *                 is null, then SRC_OVER is assumed.
     */
-    public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) {
+    public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
         this(shaderA, shaderB, mode.porterDuffMode);
     }
 
-    /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
-        When the mode is applied, it will be given the result from shader A as its
-        "dst", and the result from shader B as its "src".
-        @param shaderA  The colors from this shader are seen as the "dst" by the mode
-        @param shaderB  The colors from this shader are seen as the "src" by the mode
-        @param mode     The PorterDuff mode that combines the colors from the two shaders.
+    /**
+     * Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
+     * When the mode is applied, it will be given the result from shader A as its
+     * "dst", and the result from shader B as its "src".
+     *
+     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
+     * @param shaderB  The colors from this shader are seen as the "src" by the mode
+     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
     */
-    public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) {
+    public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
+            @NonNull PorterDuff.Mode mode) {
         this(shaderA, shaderB, mode.nativeInt);
     }
 
     private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
+        setInternal(shaderA, shaderB, nativeMode);
+    }
+
+    /**
+     * Reinitialize the ComposeShader's component Shaders and blend mode.
+     *
+     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
+     * @param shaderB  The colors from this shader are seen as the "src" by the mode
+     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
+     */
+    public void set(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
+        setInternal(shaderA, shaderB, mode.porterDuffMode);
+    }
+
+    /**
+     * Reinitialize the ComposeShader's component Shaders and blend mode.
+     *
+     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
+     * @param shaderB  The colors from this shader are seen as the "src" by the mode
+     * @param mode     The PorterDuff mode that combines the colors from the two shaders.
+     */
+    public void set(@NonNull Shader shaderA, @NonNull Shader shaderB,
+            @NonNull PorterDuff.Mode mode) {
+        setInternal(shaderA, shaderB, mode.nativeInt);
+    }
+
+    private void setInternal(Shader shaderA, Shader shaderB, int nativeMode) {
+        if (shaderA == null || shaderB == null) {
+            throw new IllegalArgumentException("Shader parameters must not be null");
+        }
+
+        if (shaderA == mShaderA && shaderB == mShaderB && mPorterDuffMode == nativeMode) {
+            // no work to do...
+            return;
+        }
+
+        discardNativeInstance();
         mShaderA = shaderA;
         mShaderB = shaderB;
         mPorterDuffMode = nativeMode;
-        init(nativeCreate(shaderA.getNativeInstance(), shaderB.getNativeInstance(),
-                nativeMode));
+    }
+
+    @Override
+    long createNativeInstance(long nativeMatrix) {
+        mNativeInstanceShaderA = mShaderA.getNativeInstance();
+        mNativeInstanceShaderB = mShaderB.getNativeInstance();
+        return nativeCreate(nativeMatrix,
+                mShaderA.getNativeInstance(), mShaderB.getNativeInstance(), mPorterDuffMode);
+    }
+
+    @Override
+    void verifyNativeInstance() {
+        if (mShaderA.getNativeInstance() != mNativeInstanceShaderA
+                || mShaderB.getNativeInstance() != mNativeInstanceShaderB) {
+            // Child shader native instance has been updated,
+            // so our cached native instance is no longer valid - discard it
+            discardNativeInstance();
+        }
     }
 
     /**
@@ -67,6 +130,6 @@
         return copy;
     }
 
-    private static native long nativeCreate(long native_shaderA, long native_shaderB,
-            int porterDuffMode);
+    private static native long nativeCreate(long nativeMatrix,
+            long nativeShaderA, long nativeShaderB, int porterDuffMode);
 }
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 7b1145c..0e4cd0a 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -16,6 +16,10 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 public class LinearGradient extends Shader {
 
     private static final int TYPE_COLORS_AND_POSITIONS = 1;
@@ -38,47 +42,88 @@
 
     private TileMode mTileMode;
 
-    /** Create a shader that draws a linear gradient along a line.
-        @param x0           The x-coordinate for the start of the gradient line
-        @param y0           The y-coordinate for the start of the gradient line
-        @param x1           The x-coordinate for the end of the gradient line
-        @param y1           The y-coordinate for the end of the gradient line
-        @param  colors      The colors to be distributed along the gradient line
-        @param  positions   May be null. The relative positions [0..1] of
-                            each corresponding color in the colors array. If this is null,
-                            the the colors are distributed evenly along the gradient line.
-        @param  tile        The Shader tiling mode
+    /**
+     * Create a shader that draws a linear gradient along a line.
+     *
+     * @param x0           The x-coordinate for the start of the gradient line
+     * @param y0           The y-coordinate for the start of the gradient line
+     * @param x1           The x-coordinate for the end of the gradient line
+     * @param y1           The y-coordinate for the end of the gradient line
+     * @param colors       The colors to be distributed along the gradient line
+     * @param positions    May be null. The relative positions [0..1] of
+     *                     each corresponding color in the colors array. If this is null,
+     *                     the the colors are distributed evenly along the gradient line.
+     * @param tile         The Shader tiling mode
     */
-    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
-            TileMode tile) {
+    public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
+            @Nullable float positions[], @NonNull TileMode tile) {
+        set(x0, y0, x1, y1, colors, positions, tile);
+    }
+
+    /**
+     * Create a shader that draws a linear gradient along a line.
+     *
+     * @param x0       The x-coordinate for the start of the gradient line
+     * @param y0       The y-coordinate for the start of the gradient line
+     * @param x1       The x-coordinate for the end of the gradient line
+     * @param y1       The y-coordinate for the end of the gradient line
+     * @param color0   The color at the start of the gradient line.
+     * @param color1   The color at the end of the gradient line.
+     * @param tile     The Shader tiling mode
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1,
+            @ColorInt int color0, @ColorInt int color1,
+            @NonNull TileMode tile) {
+        set(x0, y0, x1, y1, color0, color1, tile);
+    }
+
+    /**
+     * Reinitialize the shader.
+     *
+     * @param x0           The x-coordinate for the start of the gradient line
+     * @param y0           The y-coordinate for the start of the gradient line
+     * @param x1           The x-coordinate for the end of the gradient line
+     * @param y1           The y-coordinate for the end of the gradient line
+     * @param colors       The colors to be distributed along the gradient line
+     * @param positions    May be null. The relative positions [0..1] of
+     *                     each corresponding color in the colors array. If this is null,
+     *                     the the colors are distributed evenly along the gradient line.
+     * @param  tile        The Shader tiling mode
+     */
+    public void set(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
+            @Nullable float positions[], @NonNull TileMode tile) {
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
         }
         if (positions != null && colors.length != positions.length) {
             throw new IllegalArgumentException("color and position arrays must be of equal length");
         }
+        discardNativeInstance();
         mType = TYPE_COLORS_AND_POSITIONS;
         mX0 = x0;
         mY0 = y0;
         mX1 = x1;
         mY1 = y1;
-        mColors = colors;
-        mPositions = positions;
+        mColors = colors.clone();
+        mPositions = positions != null ? positions.clone() : null;
         mTileMode = tile;
-        init(nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt));
     }
 
-    /** Create a shader that draws a linear gradient along a line.
-        @param x0       The x-coordinate for the start of the gradient line
-        @param y0       The y-coordinate for the start of the gradient line
-        @param x1       The x-coordinate for the end of the gradient line
-        @param y1       The y-coordinate for the end of the gradient line
-        @param  color0  The color at the start of the gradient line.
-        @param  color1  The color at the end of the gradient line.
-        @param  tile    The Shader tiling mode
+    /**
+     * Reinitialize the shader.
+     *
+     * @param x0       The x-coordinate for the start of the gradient line
+     * @param y0       The y-coordinate for the start of the gradient line
+     * @param x1       The x-coordinate for the end of the gradient line
+     * @param y1       The y-coordinate for the end of the gradient line
+     * @param color0   The color at the start of the gradient line.
+     * @param color1   The color at the end of the gradient line.
+     * @param tile     The Shader tiling mode
     */
-    public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
-            TileMode tile) {
+    public void set(float x0, float y0, float x1, float y1,
+            @ColorInt int color0, @ColorInt int color1,
+            @NonNull TileMode tile) {
+        discardNativeInstance();
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mX0 = x0;
         mY0 = y0;
@@ -86,8 +131,20 @@
         mY1 = y1;
         mColor0 = color0;
         mColor1 = color1;
+        mColors = null;
+        mPositions = null;
         mTileMode = tile;
-        init(nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt));
+    }
+
+    @Override
+    long createNativeInstance(long nativeMatrix) {
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            return nativeCreate1(nativeMatrix, mX0, mY0, mX1, mY1,
+                    mColors, mPositions, mTileMode.nativeInt);
+        } else { // TYPE_COLOR_START_AND_COLOR_END
+            return nativeCreate2(nativeMatrix, mX0, mY0, mX1, mY1,
+                    mColor0, mColor1, mTileMode.nativeInt);
+        }
     }
 
     /**
@@ -96,24 +153,18 @@
     @Override
     protected Shader copy() {
         final LinearGradient copy;
-        switch (mType) {
-            case TYPE_COLORS_AND_POSITIONS:
-                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColors.clone(),
-                        mPositions != null ? mPositions.clone() : null, mTileMode);
-                break;
-            case TYPE_COLOR_START_AND_COLOR_END:
-                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColor0, mColor1, mTileMode);
-                break;
-            default:
-                throw new IllegalArgumentException("LinearGradient should be created with either " +
-                        "colors and positions or start color and end color");
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            copy = new LinearGradient(mX0, mY0, mX1, mY1, mColors.clone(),
+                    mPositions != null ? mPositions.clone() : null, mTileMode);
+        } else { // TYPE_COLOR_START_AND_COLOR_END
+            copy = new LinearGradient(mX0, mY0, mX1, mY1, mColor0, mColor1, mTileMode);
         }
         copyLocalMatrix(copy);
         return copy;
     }
 
-    private native long nativeCreate1(float x0, float y0, float x1, float y1,
+    private native long nativeCreate1(long matrix, float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
-    private native long nativeCreate2(float x0, float y0, float x1, float y1,
+    private native long nativeCreate2(long matrix, float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode);
 }
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index ade14c64..ae8f7da 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.ColorInt;
 
 public class RadialGradient extends Shader {
 
@@ -40,19 +41,55 @@
 
     private TileMode mTileMode;
 
-    /** Create a shader that draws a radial gradient given the center and radius.
-        @param centerX  The x-coordinate of the center of the radius
-        @param centerY  The y-coordinate of the center of the radius
-        @param radius   Must be positive. The radius of the circle for this gradient.
-        @param colors   The colors to be distributed between the center and edge of the circle
-        @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
-                        <code>1.0f</code>. The relative position of each corresponding color in
-                        the colors array. If <code>null</code>, colors are distributed evenly
-                        between the center and edge of the circle.
-        @param tileMode The Shader tiling mode
-    */
+    /**
+     * Create a shader that draws a radial gradient given the center and radius.
+     *
+     * @param centerX  The x-coordinate of the center of the radius
+     * @param centerY  The y-coordinate of the center of the radius
+     * @param radius   Must be positive. The radius of the circle for this gradient.
+     * @param colors   The colors to be distributed between the center and edge of the circle
+     * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
+     *                 <code>1.0f</code>. The relative position of each corresponding color in
+     *                 the colors array. If <code>null</code>, colors are distributed evenly
+     *                 between the center and edge of the circle.
+     * @param tileMode The Shader tiling mode
+     */
     public RadialGradient(float centerX, float centerY, float radius,
-               @NonNull int colors[], @Nullable float stops[], @NonNull TileMode tileMode) {
+            @NonNull @ColorInt int colors[], @Nullable float stops[],
+            @NonNull TileMode tileMode) {
+        set(centerX, centerY, radius, colors, stops, tileMode);
+    }
+
+    /**
+     * Create a shader that draws a radial gradient given the center and radius.
+     *
+     * @param centerX     The x-coordinate of the center of the radius
+     * @param centerY     The y-coordinate of the center of the radius
+     * @param radius      Must be positive. The radius of the circle for this gradient
+     * @param centerColor The color at the center of the circle.
+     * @param edgeColor   The color at the edge of the circle.
+     * @param tileMode    The Shader tiling mode
+     */
+    public RadialGradient(float centerX, float centerY, float radius,
+            @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
+        set(centerX, centerY, radius, centerColor, edgeColor, tileMode);
+    }
+
+    /**
+     * Reinitialize the shader.
+     *
+     * @param centerX  The x-coordinate of the center of the radius
+     * @param centerY  The y-coordinate of the center of the radius
+     * @param radius   Must be positive. The radius of the circle for this gradient.
+     * @param colors   The colors to be distributed between the center and edge of the circle
+     * @param stops    May be <code>null</code>. Valid values are between <code>0.0f</code> and
+     *                 <code>1.0f</code>. The relative position of each corresponding color in
+     *                 the colors array. If <code>null</code>, colors are distributed evenly
+     *                 between the center and edge of the circle.
+     * @param tileMode The Shader tiling mode
+     */
+    public void set(float centerX, float centerY, float radius,
+            @NonNull @ColorInt int colors[], @Nullable float stops[], @NonNull TileMode tileMode) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
@@ -62,29 +99,32 @@
         if (stops != null && colors.length != stops.length) {
             throw new IllegalArgumentException("color and position arrays must be of equal length");
         }
+        discardNativeInstance();
         mType = TYPE_COLORS_AND_POSITIONS;
         mX = centerX;
         mY = centerY;
         mRadius = radius;
-        mColors = colors;
-        mPositions = stops;
+        mColors = colors.clone();
+        mPositions = stops != null ? stops.clone() : null;
         mTileMode = tileMode;
-        init(nativeCreate1(centerX, centerY, radius, colors, stops, tileMode.nativeInt));
     }
 
-    /** Create a shader that draws a radial gradient given the center and radius.
-        @param centerX     The x-coordinate of the center of the radius
-        @param centerY     The y-coordinate of the center of the radius
-        @param radius      Must be positive. The radius of the circle for this gradient
-        @param centerColor The color at the center of the circle.
-        @param edgeColor   The color at the edge of the circle.
-        @param tileMode    The Shader tiling mode
-    */
-    public RadialGradient(float centerX, float centerY, float radius,
-            int centerColor, int edgeColor, @NonNull TileMode tileMode) {
+    /**
+     * Reinitialize the shader.
+     *
+     * @param centerX     The x-coordinate of the center of the radius
+     * @param centerY     The y-coordinate of the center of the radius
+     * @param radius      Must be positive. The radius of the circle for this gradient
+     * @param centerColor The color at the center of the circle.
+     * @param edgeColor   The color at the edge of the circle.
+     * @param tileMode    The Shader tiling mode
+     */
+    public void set(float centerX, float centerY, float radius,
+            @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
+        discardNativeInstance();
         mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
         mX = centerX;
         mY = centerY;
@@ -92,7 +132,17 @@
         mCenterColor = centerColor;
         mEdgeColor = edgeColor;
         mTileMode = tileMode;
-        init(nativeCreate2(centerX, centerY, radius, centerColor, edgeColor, tileMode.nativeInt));
+    }
+
+    @Override
+    long createNativeInstance(long nativeMatrix) {
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            return nativeCreate1(nativeMatrix, mX, mY, mRadius,
+                    mColors, mPositions, mTileMode.nativeInt);
+        } else { // TYPE_COLOR_CENTER_AND_COLOR_EDGE
+            return nativeCreate2(nativeMatrix, mX, mY, mRadius,
+                    mCenterColor, mEdgeColor, mTileMode.nativeInt);
+        }
     }
 
     /**
@@ -101,25 +151,19 @@
     @Override
     protected Shader copy() {
         final RadialGradient copy;
-        switch (mType) {
-            case TYPE_COLORS_AND_POSITIONS:
-                copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
-                        mPositions != null ? mPositions.clone() : null, mTileMode);
-                break;
-            case TYPE_COLOR_CENTER_AND_COLOR_EDGE:
-                copy = new RadialGradient(mX, mY, mRadius, mCenterColor, mEdgeColor, mTileMode);
-                break;
-            default:
-                throw new IllegalArgumentException("RadialGradient should be created with either " +
-                        "colors and positions or center color and edge color");
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
+                    mPositions != null ? mPositions.clone() : null, mTileMode);
+        } else { // TYPE_COLOR_CENTER_AND_COLOR_EDGE
+            copy = new RadialGradient(mX, mY, mRadius, mCenterColor, mEdgeColor, mTileMode);
         }
         copyLocalMatrix(copy);
         return copy;
     }
 
-    private static native long nativeCreate1(float x, float y, float radius,
+    private static native long nativeCreate1(long matrix, float x, float y, float radius,
             int colors[], float positions[], int tileMode);
-    private static native long nativeCreate2(float x, float y, float radius,
+    private static native long nativeCreate2(long matrix, float x, float y, float radius,
             int color0, int color1, int tileMode);
 }
 
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 94983b3..a91b410 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 /**
  * Shader is the based class for objects that return horizontal spans of colors
  * during drawing. A subclass of Shader is installed in a Paint calling
@@ -24,18 +27,16 @@
  */
 public class Shader {
     /**
-     * This is set by subclasses, but don't make it public.
+     * @deprecated Use subclass constructors directly instead.
      */
-    private long native_instance;
+    @Deprecated
+    public Shader() {}
 
     /**
-     * Initialization step that should be called by subclasses in their
-     * constructors. Calling again may result in memory leaks.
-     * @hide
+     * Current native shader instance. Created and updated lazily when {@link #getNativeInstance()}
+     * is called - otherwise may be out of date with java setters/properties.
      */
-    protected void init(long ni) {
-        native_instance = ni;
-    }
+    private long mNativeInstance;
 
     private Matrix mLocalMatrix;
 
@@ -63,13 +64,13 @@
 
     /**
      * Return true if the shader has a non-identity local matrix.
-     * @param localM If not null, it is set to the shader's local matrix.
+     * @param localM Set to the local matrix of the shader, if the shader's matrix is non-null.
      * @return true if the shader has a non-identity local matrix
      */
-    public boolean getLocalMatrix(Matrix localM) {
+    public boolean getLocalMatrix(@NonNull Matrix localM) {
         if (mLocalMatrix != null) {
             localM.set(mLocalMatrix);
-            return !mLocalMatrix.isIdentity();
+            return true;
         }
         return false;
     }
@@ -80,18 +81,46 @@
      *
      * @param localM The shader's new local matrix, or null to specify identity
      */
-    public void setLocalMatrix(Matrix localM) {
-        mLocalMatrix = localM;
-        native_instance = nativeSetLocalMatrix(native_instance,
-                localM == null ? 0 : localM.native_instance);
+    public void setLocalMatrix(@Nullable Matrix localM) {
+        if (localM == null || localM.isIdentity()) {
+            if (mLocalMatrix != null) {
+                mLocalMatrix = null;
+                discardNativeInstance();
+            }
+        } else {
+            if (mLocalMatrix == null) {
+                mLocalMatrix = new Matrix(localM);
+                discardNativeInstance();
+            } else if (!mLocalMatrix.equals(localM)) {
+                mLocalMatrix.set(localM);
+                discardNativeInstance();
+            }
+        }
     }
 
+    long createNativeInstance(long nativeMatrix) {
+        return 0;
+    }
+
+    void discardNativeInstance() {
+        nativeSafeUnref(mNativeInstance);
+        mNativeInstance = 0;
+    }
+
+    /**
+     * Callback for subclasses to call {@link #discardNativeInstance()} if the most recently
+     * constructed native instance is no longer valid.
+     */
+    void verifyNativeInstance() {
+    }
+
+    @Override
     protected void finalize() throws Throwable {
         try {
-            super.finalize();
+            nativeSafeUnref(mNativeInstance);
+            mNativeInstance = -1;
         } finally {
-            nativeDestructor(native_instance);
-            native_instance = 0;  // Other finalizers can still call us.
+            super.finalize();
         }
     }
 
@@ -108,22 +137,26 @@
      * @hide
      */
     protected void copyLocalMatrix(Shader dest) {
-        if (mLocalMatrix != null) {
-            final Matrix lm = new Matrix();
-            getLocalMatrix(lm);
-            dest.setLocalMatrix(lm);
-        } else {
-            dest.setLocalMatrix(null);
-        }
+        dest.mLocalMatrix.set(mLocalMatrix);
     }
 
     /**
      * @hide
      */
     public long getNativeInstance() {
-        return native_instance;
+        if (mNativeInstance == -1) {
+            throw new IllegalStateException("attempting to use a finalized Shader");
+        }
+
+        // verify mNativeInstance is valid
+        verifyNativeInstance();
+
+        if (mNativeInstance == 0) {
+            mNativeInstance = createNativeInstance(mLocalMatrix == null
+                    ? 0 : mLocalMatrix.native_instance);
+        }
+        return mNativeInstance;
     }
 
-    private static native void nativeDestructor(long native_shader);
-    private static native long nativeSetLocalMatrix(long native_shader, long matrix_instance);
+    private static native void nativeSafeUnref(long nativeInstance);
 }
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 008891d..0a1aef6 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -16,6 +16,10 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 public class SweepGradient extends Shader {
 
     private static final int TYPE_COLORS_AND_POSITIONS = 1;
@@ -35,7 +39,7 @@
     private int mColor1;
 
     /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
+     * A Shader that draws a sweep gradient around a center point.
      *
      * @param cx       The x-coordinate of the center
      * @param cy       The y-coordinate of the center
@@ -49,37 +53,79 @@
      *                 spaced evenly.
      */
     public SweepGradient(float cx, float cy,
-                         int colors[], float positions[]) {
-        if (colors.length < 2) {
-            throw new IllegalArgumentException("needs >= 2 number of colors");
-        }
-        if (positions != null && colors.length != positions.length) {
-            throw new IllegalArgumentException(
-                        "color and position arrays must be of equal length");
-        }
-        mType = TYPE_COLORS_AND_POSITIONS;
-        mCx = cx;
-        mCy = cy;
-        mColors = colors;
-        mPositions = positions;
-        init(nativeCreate1(cx, cy, colors, positions));
+            @NonNull @ColorInt int colors[], @Nullable float positions[]) {
+        set(cx, cy, colors, positions);
     }
 
     /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
+     * A Shader that draws a sweep gradient around a center point.
      *
      * @param cx       The x-coordinate of the center
      * @param cy       The y-coordinate of the center
      * @param color0   The color to use at the start of the sweep
      * @param color1   The color to use at the end of the sweep
      */
-    public SweepGradient(float cx, float cy, int color0, int color1) {
+    public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
+        set(cx, cy, color0, color1);
+    }
+
+    /**
+     * Reinitialize the shader.
+     *
+     * @param cx       The x-coordinate of the center
+     * @param cy       The y-coordinate of the center
+     * @param colors   The colors to be distributed between around the center.
+     *                 There must be at least 2 colors in the array.
+     * @param positions May be NULL. The relative position of
+     *                 each corresponding color in the colors array, beginning
+     *                 with 0 and ending with 1.0. If the values are not
+     *                 monotonic, the drawing may produce unexpected results.
+     *                 If positions is NULL, then the colors are automatically
+     *                 spaced evenly.
+     */
+    public void set(float cx, float cy,
+            @NonNull @ColorInt int colors[], @Nullable float positions[]) {
+        if (colors.length < 2) {
+            throw new IllegalArgumentException("needs >= 2 number of colors");
+        }
+        if (positions != null && colors.length != positions.length) {
+            throw new IllegalArgumentException(
+                    "color and position arrays must be of equal length");
+        }
+        discardNativeInstance();
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mCx = cx;
+        mCy = cy;
+        mColors = colors.clone();
+        mPositions = positions != null ? positions.clone() : null;
+    }
+
+    /**
+     * Reinitialize the shader.
+     *
+     * @param cx       The x-coordinate of the center
+     * @param cy       The y-coordinate of the center
+     * @param color0   The color to use at the start of the sweep
+     * @param color1   The color to use at the end of the sweep
+     */
+    public void set(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
+        discardNativeInstance();
         mType = TYPE_COLOR_START_AND_COLOR_END;
         mCx = cx;
         mCy = cy;
         mColor0 = color0;
         mColor1 = color1;
-        init(nativeCreate2(cx, cy, color0, color1));
+        mColors = null;
+        mPositions = null;
+    }
+
+    @Override
+    long createNativeInstance(long nativeMatrix) {
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            return nativeCreate1(nativeMatrix, mCx, mCy, mColors, mPositions);
+        } else { // TYPE_COLOR_START_AND_COLOR_END
+            return nativeCreate2(nativeMatrix, mCx, mCy, mColor0, mColor1);
+        }
     }
 
     /**
@@ -88,23 +134,19 @@
     @Override
     protected Shader copy() {
         final SweepGradient copy;
-        switch (mType) {
-            case TYPE_COLORS_AND_POSITIONS:
-                copy = new SweepGradient(mCx, mCy, mColors.clone(),
-                        mPositions != null ? mPositions.clone() : null);
-                break;
-            case TYPE_COLOR_START_AND_COLOR_END:
-                copy = new SweepGradient(mCx, mCy, mColor0, mColor1);
-                break;
-            default:
-                throw new IllegalArgumentException("SweepGradient should be created with either " +
-                        "colors and positions or start color and end color");
+        if (mType == TYPE_COLORS_AND_POSITIONS) {
+            copy = new SweepGradient(mCx, mCy, mColors.clone(),
+                    mPositions != null ? mPositions.clone() : null);
+        } else { // TYPE_COLOR_START_AND_COLOR_END
+            copy = new SweepGradient(mCx, mCy, mColor0, mColor1);
         }
         copyLocalMatrix(copy);
         return copy;
     }
 
-    private static native long nativeCreate1(float x, float y, int colors[], float positions[]);
-    private static native long nativeCreate2(float x, float y, int color0, int color1);
+    private static native long nativeCreate1(long matrix, float x, float y,
+            int colors[], float positions[]);
+    private static native long nativeCreate2(long matrix, float x, float y,
+            int color0, int color1);
 }
 
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 8b30903..6de19cb 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -32,7 +32,6 @@
 import android.util.LongSparseArray;
 import android.util.LruCache;
 import android.util.SparseArray;
-import android.graphics.FontListParser;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -287,13 +286,11 @@
             callback.onTypefaceRetrieved(cachedTypeface);
             return;
         }
-        if (resultCode == FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND) {
-            callback.onTypefaceRequestFailed(
-                    FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
+        if (resultCode != FontsContract.Columns.RESULT_CODE_OK) {
+            callback.onTypefaceRequestFailed(resultCode);
             return;
         }
-        if (resultCode == FontsContract.RESULT_CODE_FONT_NOT_FOUND
-                || resultData == null) {
+        if (resultData == null) {
             callback.onTypefaceRequestFailed(
                     FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
             return;
@@ -356,21 +353,37 @@
          * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
          * provider was not found on the device.
          */
-        int FAIL_REASON_PROVIDER_NOT_FOUND = 0;
+        int FAIL_REASON_PROVIDER_NOT_FOUND = FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND;
+        /**
+         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+         * provider must be authenticated and the given certificates do not match its signature.
+         */
+        int FAIL_REASON_WRONG_CERTIFICATES = FontsContract.RESULT_CODE_WRONG_CERTIFICATES;
         /**
          * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
          * returned by the provider was not loaded properly.
          */
-        int FAIL_REASON_FONT_LOAD_ERROR = 1;
+        int FAIL_REASON_FONT_LOAD_ERROR = -3;
         /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
          * provider did not return any results for the given query.
          */
-        int FAIL_REASON_FONT_NOT_FOUND = 2;
+        int FAIL_REASON_FONT_NOT_FOUND = FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND;
+        /**
+         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
+         * provider found the queried font, but it is currently unavailable.
+         */
+        int FAIL_REASON_FONT_UNAVAILABLE = FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE;
+        /**
+         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
+         * query was not supported by the provider.
+         */
+        int FAIL_REASON_MALFORMED_QUERY = FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY;
 
         /** @hide */
-        @IntDef({FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR,
-                FAIL_REASON_FONT_NOT_FOUND})
+        @IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR,
+                FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE,
+                FAIL_REASON_MALFORMED_QUERY })
         @Retention(RetentionPolicy.SOURCE)
         @interface FontRequestFailReason {}
 
@@ -386,8 +399,10 @@
          * Called when a Typeface request done via {@link Typeface#create(FontRequest,
          * FontRequestCallback)} fails.
          * @param reason One of {@link #FAIL_REASON_PROVIDER_NOT_FOUND},
-         *               {@link #FAIL_REASON_FONT_NOT_FOUND} or
-         *               {@link #FAIL_REASON_FONT_LOAD_ERROR}.
+         *               {@link #FAIL_REASON_FONT_NOT_FOUND},
+         *               {@link #FAIL_REASON_FONT_LOAD_ERROR},
+         *               {@link #FAIL_REASON_FONT_UNAVAILABLE} or
+         *               {@link #FAIL_REASON_MALFORMED_QUERY}.
          */
         void onTypefaceRequestFailed(@FontRequestFailReason int reason);
     }
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index c6fbe2bd5..e39614b 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -91,8 +91,6 @@
     LayerUpdateQueue* layerUpdateQueue = nullptr;
     ErrorHandler* errorHandler = nullptr;
 
-    int32_t windowInsetLeft = 0;
-    int32_t windowInsetTop = 0;
     bool updateWindowPositions = false;
 
     struct Out {
diff --git a/media/java/android/media/AudioFocusRequest.java b/media/java/android/media/AudioFocusRequest.java
index 1b75a78..73f912b 100644
--- a/media/java/android/media/AudioFocusRequest.java
+++ b/media/java/android/media/AudioFocusRequest.java
@@ -303,12 +303,12 @@
          * by this {@code Builder}'s configuration methods.
          * @return the {@code AudioFocusRequest} instance qualified by all the properties set
          *   on this {@code Builder}.
-         * @throws IllegalArgumentException thrown when focus request is set to accept delayed
-         *    focus, or to pause on duck, but no focus change listener was set.
+         * @throws IllegalStateException thrown when attempting to build a focus request that is set
+         *    to accept delayed focus, or to pause on duck, but no focus change listener was set.
          */
         public AudioFocusRequest build() {
             if ((mDelayedFocus || mPausesOnDuck) && (mFocusListener == null)) {
-                throw new IllegalArgumentException(
+                throw new IllegalStateException(
                         "Can't use delayed focus or pause on duck without a listener");
             }
             final int flags = 0
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index dc69a69..f13ccc1 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2234,8 +2234,11 @@
      *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
      *      as the playback of a song or a video.
      *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @deprecated use {@link #requestAudioFocus(AudioFocusRequest)}
      */
     public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) {
+        PlayerBase.deprecateStreamTypeForPlayback(streamType,
+                "AudioManager", "requestAudioFocus()");
         int status = AUDIOFOCUS_REQUEST_FAILED;
 
         try {
@@ -2502,6 +2505,7 @@
      *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
      *  @param l the listener with which focus was requested.
      *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @deprecated use {@link #abandonAudioFocusRequest(AudioFocusRequest)}
      */
     public int abandonAudioFocus(OnAudioFocusChangeListener l) {
         return abandonAudioFocus(l, null /*AudioAttributes, legacy behavior*/);
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index 796d6f3..af11e07 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -431,8 +431,8 @@
                 dest.writeDouble(mDurationMs);
                 // this needs to match the native Interpolator parceling
                 dest.writeInt(mInterpolatorType);
-                dest.writeFloat(0.f); // first slope
-                dest.writeFloat(0.f); // last slope
+                dest.writeFloat(0.f); // first slope (specifying for native side)
+                dest.writeFloat(0.f); // last slope (specifying for native side)
                 // mTimes and mVolumes should have the same length.
                 dest.writeInt(mTimes.length);
                 for (int i = 0; i < mTimes.length; ++i) {
@@ -456,8 +456,8 @@
                     final double durationMs = p.readDouble();
                     // this needs to match the native Interpolator parceling
                     final int interpolatorType = p.readInt();
-                    final float firstSlope = p.readFloat(); // ignored
-                    final float lastSlope = p.readFloat();  // ignored
+                    final float firstSlope = p.readFloat(); // ignored on the Java side
+                    final float lastSlope = p.readFloat();  // ignored on the Java side
                     final int length = p.readInt();
                     final float[] times = new float[length];
                     final float[] volumes = new float[length];
@@ -593,6 +593,10 @@
          * {@code times[]} and {@code volumes[]} are two arrays representing points
          * for the volume curve.
          *
+         * Note that {@code times[]} and {@code volumes[]} are explicitly checked against
+         * null here to provide the proper error string - those are legitimate
+         * arguments to this method.
+         *
          * @param times the x coordinates for the points,
          *        must be between 0.f and 1.f and be monotonic.
          * @param volumes the y coordinates for the points,
@@ -644,10 +648,14 @@
         }
 
         private static void checkCurveForErrorsAndThrowException(
-                @Nullable float[] times, @Nullable float[] volumes, boolean log) {
+                @Nullable float[] times, @Nullable float[] volumes, boolean log, boolean ise) {
             final String error = checkCurveForErrors(times, volumes, log);
             if (error != null) {
-                throw new IllegalArgumentException(error);
+                if (ise) {
+                    throw new IllegalStateException(error);
+                } else {
+                    throw new IllegalArgumentException(error);
+                }
             }
         }
 
@@ -840,8 +848,8 @@
              */
 
             public @NonNull Builder setCurve(@NonNull float[] times, @NonNull float[] volumes) {
-                checkCurveForErrorsAndThrowException(
-                        times, volumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(times, volumes, log, false /* ise */);
                 mTimes = times.clone();
                 mVolumes = volumes.clone();
                 return this;
@@ -853,11 +861,11 @@
              * to the start.
              *
              * @return the same {@code Builder} instance.
-             * @throws IllegalArgumentException if curve has not been set.
+             * @throws IllegalStateException if curve has not been set.
              */
             public @NonNull Builder reflectTimes() {
-                checkCurveForErrorsAndThrowException(
-                        mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
                 int i;
                 for (i = 0; i < mTimes.length / 2; ++i) {
                     float temp = mTimes[i];
@@ -878,11 +886,11 @@
              * becomes the min volume and vice versa.
              *
              * @return the same {@code Builder} instance.
-             * @throws IllegalArgumentException if curve has not been set.
+             * @throws IllegalStateException if curve has not been set.
              */
             public @NonNull Builder invertVolumes() {
-                checkCurveForErrorsAndThrowException(
-                        mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
                 float min = mVolumes[0];
                 float max = mVolumes[0];
                 for (int i = 1; i < mVolumes.length; ++i) {
@@ -908,12 +916,12 @@
              *
              * @param volume the target end volume to use.
              * @return the same {@code Builder} instance.
-             * @throws IllegalArgumentException if {@code volume}
-             *         is not valid or if curve has not been set.
+             * @throws IllegalArgumentException if {@code volume} is not valid.
+             * @throws IllegalStateException if curve has not been set.
              */
             public @NonNull Builder scaleToEndVolume(float volume) {
                 final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
-                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
                 checkValidVolumeAndThrowException(volume, log);
                 final float startVolume = mVolumes[0];
                 final float endVolume = mVolumes[mVolumes.length - 1];
@@ -942,12 +950,12 @@
              *
              * @param volume the target start volume to use.
              * @return the same {@code Builder} instance.
-             * @throws IllegalArgumentException if {@code volume}
-             *         is not valid or if curve has not been set.
+             * @throws IllegalArgumentException if {@code volume} is not valid.
+             * @throws IllegalStateException if curve has not been set.
              */
             public @NonNull Builder scaleToStartVolume(float volume) {
                 final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
-                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log);
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
                 checkValidVolumeAndThrowException(volume, log);
                 final float startVolume = mVolumes[0];
                 final float endVolume = mVolumes[mVolumes.length - 1];
@@ -971,11 +979,11 @@
              * Builds a new {@link VolumeShaper} object.
              *
              * @return a new {@link VolumeShaper} object.
-             * @throws IllegalArgumentException if curve is not properly set.
+             * @throws IllegalStateException if curve is not properly set.
              */
             public @NonNull Configuration build() {
-                checkCurveForErrorsAndThrowException(
-                        mTimes, mVolumes, (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0);
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
                 return new Configuration(mType, mId, mOptionFlags, mDurationMs,
                         mInterpolatorType, mTimes, mVolumes);
             }
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 81db37e..7122eaf 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -471,6 +471,7 @@
      * @param extras The bundle of service-specific arguments to send to the media browser
      *            service. The contents of this bundle may affect the search result.
      * @param callback The callback to receive the search result.
+     * @throws IllegalStateException if the browser is not connected to the media browser service.
      */
     public void search(@NonNull final String query, final Bundle extras, SearchCallback callback) {
         if (TextUtils.isEmpty(query)) {
@@ -480,14 +481,8 @@
             throw new IllegalArgumentException("callback cannot be null.");
         }
         if (mState != CONNECT_STATE_CONNECTED) {
-            Log.i(TAG, "Not connected, unable to search.");
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    callback.onError(query, extras);
-                }
-            });
-            return;
+            throw new IllegalStateException("search() called while not connected (state="
+                    + getStateLabel(mState) + ")");
         }
         ResultReceiver receiver = new ResultReceiver(mHandler) {
             @Override
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index aee9d38e..e5af357 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -776,8 +776,8 @@
         mSurface = null;
         mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
             @Override
-            protected void updateWindow() {
-                super.updateWindow();
+            protected void updateSurface() {
+                super.updateSurface();
                 relayoutSessionOverlayView();
             }};
         // The surface view's content should be treated as secure all the time.
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index b00f5a5..f5e19f9 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -722,6 +722,9 @@
 
     LockedImage lockedImg = LockedImage();
     Image_getLockedImage(env, thiz, &lockedImg);
+    if (env->ExceptionCheck()) {
+        return NULL;
+    }
     // Create all SurfacePlanes
     for (int i = 0; i < numPlanes; i++) {
         Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat,
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 9a78544..476f016 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -45,8 +45,8 @@
 
 import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
 
-import org.mockito.ArgumentMatcher;
 import org.mockito.ArgumentCaptor;
+import org.mockito.compat.ArgumentMatcher;
 import static org.mockito.Mockito.*;
 
 public class CameraDeviceBinderTest extends AndroidTestCase {
@@ -168,7 +168,7 @@
 
     class IsMetadataNotEmpty extends ArgumentMatcher<CameraMetadataNative> {
         @Override
-        public boolean matches(Object obj) {
+        public boolean matchesObject(Object obj) {
             return !((CameraMetadataNative) obj).isEmpty();
         }
     }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index 86c2284..712039d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -37,9 +37,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.hamcrest.Description;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
 
 public class MediaInserterTest extends InstrumentationTestCase {
 
@@ -67,7 +67,7 @@
         }
 
         @Override
-        public boolean matches(Object argument) {
+        public boolean matchesObject(Object argument) {
             if (!(argument instanceof Uri)) {
                 return false;
             }
@@ -79,13 +79,9 @@
         }
 
         @Override
-        public void describeTo(Description description) {
-            description
-                    .appendText("expected a TableUri '")
-                    .appendText(mUri.toString())
-                    .appendText("'");
+        public String toString() {
+            return "expected a TableUri '" + mUri.toString() + "'";
         }
-
     }
 
     private static Uri eqUri(Uri in) {
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index d910920..2e642ec 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -17,16 +17,16 @@
  */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.carrierdefaultapp"
-    android:sharedUserId="android.uid.phone" >
+    package="com.android.carrierdefaultapp">
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
 
     <application android:label="@string/app_name" >
         <receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver">
diff --git a/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml b/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
index 5896757..dc54fe2 100644
--- a/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
+++ b/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
@@ -14,13 +14,12 @@
     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="@dimen/glif_icon_size"
-    android:height="@dimen/glif_icon_size"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-    <path
-        android:fillColor="?android:attr/colorPrimary"
-        android:pathData="M39.98,8c0,-2.21 -1.77,-4 -3.98,-4L20,4L8,16v24c0,2.21 1.79,4 4,4h24.02c2.21,0 3.98,-1.79 3.98,-4l-0.02,-32zM18,38h-4v-4h4v4zM34,38h-4v-4h4v4zM18,30h-4v-8h4v8zM26,38h-4v-8h4v8zM26,26h-4v-4h4v4zM34,30h-4v-8h4v8z" />
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+<path
+    android:fillColor="#757575"
+    android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM13,17h-2v-2h2v2zM13,13h-2L11,8h2v5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index 838ff39..fe5669d 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="app_name">CarrierDefaultApp</string>
-    <string name="portal_notification_id">Activate your service</string>
-    <string name="no_data_notification_id">No data service</string>
-    <string name="portal_notification_detail">Tap to activate your service</string>
-    <string name="no_data_notification_detail">No Service, please contact your service provider</string>
+    <string name="android_system_label">Android System</string>
+    <string name="portal_notification_id">Mobile data has run out</string>
+    <string name="no_data_notification_id">No Mobile data service</string>
+    <string name="portal_notification_detail">Tap to add funds to your %s SIM</string>
+    <string name="no_data_notification_detail">Please contact your service provider %s</string>
     <string name="progress_dialogue_network_connection">Connecting to captive portal...</string>
     <string name="alert_dialogue_network_timeout">Network timeout, would you like to retry?</string>
     <string name="alert_dialogue_network_timeout_title">Network unavailable</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index db4890f..d9bd2fc 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.os.Bundle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -146,18 +147,25 @@
 
     private static Notification getNotification(Context context, int titleId, int textId,
                                          PendingIntent pendingIntent) {
-        Resources resources = context.getResources();
+        final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        final Resources resources = context.getResources();
+        final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                resources.getString(R.string.android_system_label));
         Notification.Builder builder = new Notification.Builder(context)
                 .setContentTitle(resources.getString(titleId))
-                .setContentText(resources.getString(textId))
+                .setContentText(String.format(resources.getString(textId),
+                        telephonyMgr.getNetworkOperatorName()))
                 .setSmallIcon(R.drawable.ic_sim_card)
+                .setColor(context.getColor(
+                        com.android.internal.R.color.system_notification_accent_color))
                 .setOngoing(true)
                 .setPriority(Notification.PRIORITY_HIGH)
                 .setDefaults(Notification.DEFAULT_ALL)
                 .setVisibility(Notification.VISIBILITY_PUBLIC)
                 .setLocalOnly(true)
                 .setWhen(System.currentTimeMillis())
-                .setShowWhen(false);
+                .setShowWhen(false)
+                .setExtras(extras);
 
         if (pendingIntent != null) {
             builder.setContentIntent(pendingIntent);
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 65cac09..34bc4eb 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -26,6 +26,8 @@
     <uses-permission android:name="android.permission.BLUETOOTH"/>
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
 
     <application
         android:allowClearUserData="true"
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 12bab18..14b9de5 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -16,10 +16,9 @@
 
 package com.android.companiondevicemanager;
 
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
 
 import android.app.Activity;
-import android.bluetooth.BluetoothDevice;
 import android.companion.CompanionDeviceManager;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -34,6 +33,8 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.android.companiondevicemanager.DeviceDiscoveryService.DeviceFilterPair;
+
 public class DeviceChooserActivity extends Activity {
 
     private static final boolean DEBUG = false;
@@ -55,11 +56,11 @@
 
         if (getService().mRequest.isSingleDevice()) {
             setContentView(R.layout.device_confirmation);
-            final BluetoothDevice selectedDevice = getService().mDevicesFound.get(0);
+            final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
             setTitle(Html.fromHtml(getString(
                     R.string.confirmation_title,
                     getCallingAppName(),
-                    getDeviceDisplayName(selectedDevice)), 0));
+                    selectedDevice.getDisplayName()), 0));
             getService().mSelectedDevice = selectedDevice;
         } else {
             setContentView(R.layout.device_chooser);
@@ -127,10 +128,11 @@
         return DeviceDiscoveryService.sInstance;
     }
 
-    protected void onPairTapped(BluetoothDevice selectedDevice) {
-        getService().onDeviceSelected(getCallingPackage(), selectedDevice.getAddress());
+   protected void onPairTapped(DeviceFilterPair selectedDevice) {
+        getService().onDeviceSelected(
+                getCallingPackage(), getDeviceMacAddress(selectedDevice.device));
         setResult(RESULT_OK,
-                new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
+                new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice.device));
         finish();
     }
 }
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index f0f9108..e1e60bb 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -16,8 +16,10 @@
 
 package com.android.companiondevicemanager;
 
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
-import static android.companion.BluetoothLEDeviceFilter.nullsafe;
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
+
+import static com.android.internal.util.ArrayUtils.isEmpty;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -32,28 +34,38 @@
 import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanSettings;
 import android.companion.AssociationRequest;
+import android.companion.BluetoothDeviceFilter;
+import android.companion.BluetoothDeviceFilterUtils;
 import android.companion.BluetoothLEDeviceFilter;
 import android.companion.CompanionDeviceManager;
+import android.companion.DeviceFilter;
 import android.companion.ICompanionDeviceDiscoveryService;
 import android.companion.ICompanionDeviceDiscoveryServiceCallback;
 import android.companion.IFindDeviceCallback;
+import android.companion.WifiDeviceFilter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
+import android.net.wifi.WifiManager;
 import android.os.IBinder;
+import android.os.Parcelable;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.TextView;
 
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
+
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 public class DeviceDiscoveryService extends Service {
 
@@ -63,12 +75,16 @@
     static DeviceDiscoveryService sInstance;
 
     private BluetoothAdapter mBluetoothAdapter;
-    private BluetoothLEDeviceFilter mFilter;
-    private ScanFilter mScanFilter;
+    private WifiManager mWifiManager;
     private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
-    AssociationRequest<?> mRequest;
-    List<BluetoothDevice> mDevicesFound;
-    BluetoothDevice mSelectedDevice;
+    private List<DeviceFilter<?>> mFilters;
+    private List<BluetoothLEDeviceFilter> mBLEFilters;
+    private List<BluetoothDeviceFilter> mBluetoothFilters;
+    private List<WifiDeviceFilter> mWifiFilters;
+    private List<ScanFilter> mBLEScanFilters;
+    AssociationRequest mRequest;
+    List<DeviceFilterPair> mDevicesFound;
+    DeviceFilterPair mSelectedDevice;
     DevicesAdapter mDevicesAdapter;
     IFindDeviceCallback mFindCallback;
     ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
@@ -95,11 +111,13 @@
     private final ScanCallback mBLEScanCallback = new ScanCallback() {
         @Override
         public void onScanResult(int callbackType, ScanResult result) {
-            final BluetoothDevice device = result.getDevice();
+            final DeviceFilterPair<ScanResult> deviceFilterPair
+                    = DeviceFilterPair.findMatch(result, mBLEFilters);
+            if (deviceFilterPair == null) return;
             if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
-                onDeviceLost(device);
+                onDeviceLost(deviceFilterPair);
             } else {
-                onDeviceFound(device);
+                onDeviceFound(deviceFilterPair);
             }
         }
     };
@@ -109,18 +127,38 @@
     private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            final BluetoothDevice device = intent.getParcelableExtra(
-                    BluetoothDevice.EXTRA_DEVICE);
-            if (!mFilter.matches(device)) return; // ignore device
-
+            final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            final DeviceFilterPair<BluetoothDevice> deviceFilterPair
+                    = DeviceFilterPair.findMatch(device, mBluetoothFilters);
+            if (deviceFilterPair == null) return;
             if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
-                onDeviceFound(device);
+                onDeviceFound(deviceFilterPair);
             } else {
-                onDeviceLost(device);
+                onDeviceLost(deviceFilterPair);
             }
         }
     };
 
+    private BroadcastReceiver mWifiDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                List<android.net.wifi.ScanResult> scanResults = mWifiManager.getScanResults();
+
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Wifi scan results: " + TextUtils.join("\n", scanResults));
+                }
+
+                for (int i = 0; i < scanResults.size(); i++) {
+                    DeviceFilterPair<android.net.wifi.ScanResult> deviceFilterPair =
+                            DeviceFilterPair.findMatch(scanResults.get(i), mWifiFilters);
+                    if (deviceFilterPair != null) onDeviceFound(deviceFilterPair);
+                }
+            }
+
+        }
+    };
+
     @Override
     public IBinder onBind(Intent intent) {
         if (DEBUG) Log.i(LOG_TAG, "onBind(" + intent + ")");
@@ -135,6 +173,7 @@
 
         mBluetoothAdapter = getSystemService(BluetoothManager.class).getAdapter();
         mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
+        mWifiManager = getSystemService(WifiManager.class);
 
         mDevicesFound = new ArrayList<>();
         mDevicesAdapter = new DevicesAdapter();
@@ -142,23 +181,39 @@
         sInstance = this;
     }
 
-    private void startDiscovery(AssociationRequest<?> request) {
-        //TODO support other protocols as well
+    private void startDiscovery(AssociationRequest request) {
         mRequest = request;
-        mFilter = nullsafe((BluetoothLEDeviceFilter) request.getDeviceFilter());
-        mScanFilter = mFilter.getScanFilter();
+
+        mFilters = request.getDeviceFilters();
+        mWifiFilters = ArrayUtils.filter(mFilters, WifiDeviceFilter.class);
+        mBluetoothFilters = ArrayUtils.filter(mFilters, BluetoothDeviceFilter.class);
+        mBLEFilters = ArrayUtils.filter(mFilters, BluetoothLEDeviceFilter.class);
+        mBLEScanFilters = ArrayUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter);
 
         reset();
 
-        final IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
-        intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
+        if (shouldScan(mBluetoothFilters)) {
+            final IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
+            intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
 
-        registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
-        mBluetoothAdapter.startDiscovery();
+            registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
+            mBluetoothAdapter.startDiscovery();
+        }
 
-        mBLEScanner.startScan(
-                Collections.singletonList(mScanFilter), mDefaultScanSettings, mBLEScanCallback);
+        if (shouldScan(mBLEFilters)) {
+            mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
+        }
+
+        if (shouldScan(mWifiFilters)) {
+            registerReceiver(mWifiDeviceFoundBroadcastReceiver,
+                    new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+            mWifiManager.startScan();
+        }
+    }
+
+    private boolean shouldScan(List<? extends DeviceFilter> mediumSpecificFilters) {
+        return !isEmpty(mediumSpecificFilters) || isEmpty(mFilters);
     }
 
     private void reset() {
@@ -178,25 +233,18 @@
         mBluetoothAdapter.cancelDiscovery();
         mBLEScanner.stopScan(mBLEScanCallback);
         unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
+        unregisterReceiver(mWifiDeviceFoundBroadcastReceiver);
         stopSelf();
     }
 
-    private void onDeviceFound(BluetoothDevice device) {
+    private void onDeviceFound(@Nullable DeviceFilterPair device) {
         if (mDevicesFound.contains(device)) {
             return;
         }
 
-        if (DEBUG) {
-            Log.i(LOG_TAG, "Considering device " + getDeviceDisplayName(device));
-        }
+        if (DEBUG) Log.i(LOG_TAG, "Found device " + device.getDisplayName() + " "
+                + getDeviceMacAddress(device.device));
 
-        if (!mFilter.matches(device)) {
-            return;
-        }
-
-        if (DEBUG) {
-            Log.i(LOG_TAG, "Found device " + getDeviceDisplayName(device));
-        }
         if (mDevicesFound.isEmpty()) {
             onReadyToShowUI();
         }
@@ -217,12 +265,10 @@
         }
     }
 
-    private void onDeviceLost(BluetoothDevice device) {
+    private void onDeviceLost(@Nullable DeviceFilterPair device) {
         mDevicesFound.remove(device);
         mDevicesAdapter.notifyDataSetChanged();
-        if (DEBUG) {
-            Log.i(LOG_TAG, "Lost device " + getDeviceDisplayName(device));
-        }
+        if (DEBUG) Log.i(LOG_TAG, "Lost device " + device.getDisplayName());
     }
 
     void onDeviceSelected(String callingPackage, String deviceAddress) {
@@ -236,7 +282,8 @@
         }
     }
 
-    class DevicesAdapter extends ArrayAdapter<BluetoothDevice> {
+    class DevicesAdapter extends ArrayAdapter<DeviceFilterPair> {
+        //TODO wifi icon
         private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
 
         private Drawable icon(int drawableRes) {
@@ -261,8 +308,8 @@
             return view;
         }
 
-        private void bind(TextView textView, BluetoothDevice device) {
-            textView.setText(getDeviceDisplayName(device));
+        private void bind(TextView textView, DeviceFilterPair device) {
+            textView.setText(device.getDisplayName());
             textView.setBackgroundColor(
                     device.equals(mSelectedDevice)
                             ? Color.GRAY
@@ -285,4 +332,62 @@
             return textView;
         }
     }
+
+    /**
+     * A pair of device and a filter that matched this device if any.
+     *
+     * @param <T> device type
+     */
+    static class DeviceFilterPair<T extends Parcelable> {
+        public final T device;
+        @Nullable
+        public final DeviceFilter<T> filter;
+
+        private DeviceFilterPair(T device, @Nullable DeviceFilter<T> filter) {
+            this.device = device;
+            this.filter = filter;
+        }
+
+        /**
+         * {@code (device, null)} if the filters list is empty or null
+         * {@code null} if none of the provided filters match the device
+         * {@code (device, filter)} where filter is among the list of filters and matches the device
+         */
+        @Nullable
+        public static <T extends Parcelable> DeviceFilterPair<T> findMatch(
+                T dev, @Nullable List<? extends DeviceFilter<T>> filters) {
+            if (isEmpty(filters)) return new DeviceFilterPair<>(dev, null);
+            final DeviceFilter<T> matchingFilter = ArrayUtils.find(filters, (f) -> f.matches(dev));
+            return matchingFilter != null ? new DeviceFilterPair<>(dev, matchingFilter) : null;
+        }
+
+        public String getDisplayName() {
+            if (filter == null) {
+                Preconditions.checkNotNull(device);
+                if (device instanceof BluetoothDevice) {
+                    return getDeviceDisplayNameInternal((BluetoothDevice) device);
+                } else if (device instanceof android.net.wifi.ScanResult) {
+                    return getDeviceDisplayNameInternal((android.net.wifi.ScanResult) device);
+                } else if (device instanceof ScanResult) {
+                    return getDeviceDisplayNameInternal(((ScanResult) device).getDevice());
+                } else {
+                    throw new IllegalArgumentException("Unknown device type: " + device.getClass());
+                }
+            }
+            return filter.getDeviceDisplayName(device);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            DeviceFilterPair<?> that = (DeviceFilterPair<?>) o;
+            return Objects.equals(getDeviceMacAddress(device), getDeviceMacAddress(that.device));
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(getDeviceMacAddress(device));
+        }
+    }
 }
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 3cc9f65e..8802010 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -19,24 +19,14 @@
 import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
 import android.content.UriPermission;
-import android.content.pm.ParceledListSlice;
-import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.database.MatrixCursor.RowBuilder;
-import android.graphics.Point;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.CancellationSignal;
 import android.os.Environment;
-import android.os.FileObserver;
-import android.os.FileUtils;
-import android.os.Handler;
-import android.os.ParcelFileDescriptor;
-import android.os.ParcelFileDescriptor.OnCloseListener;
 import android.os.UserHandle;
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
@@ -45,15 +35,12 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsContract.Root;
-import android.provider.DocumentsProvider;
-import android.provider.MediaStore;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.DebugUtils;
 import android.util.Log;
 import android.util.Pair;
-import android.webkit.MimeTypeMap;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.FileSystemProvider;
@@ -62,10 +49,8 @@
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 
@@ -408,7 +393,7 @@
     }
 
     @Override
-    public Path findDocumentPath(String childDocId, @Nullable String parentDocId)
+    public Path findDocumentPath(@Nullable String parentDocId, String childDocId)
             throws FileNotFoundException {
         final Pair<RootInfo, File> resolvedDocId = resolveDocId(childDocId, false);
         final RootInfo root = resolvedDocId.first;
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index b8c10a6..e60b5a9 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -435,7 +435,7 @@
     }
 
     @Override
-    public Path findDocumentPath(String childDocumentId, String parentDocumentId)
+    public Path findDocumentPath(String parentDocumentId, String childDocumentId)
             throws FileNotFoundException {
         final LinkedList<String> ids = new LinkedList<>();
         final Identifier childIdentifier = mDatabase.createIdentifier(childDocumentId);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 491e24d..29783e4 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -35,7 +35,6 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.LinkedList;
-import java.util.Objects;
 import java.util.Queue;
 import java.util.concurrent.TimeoutException;
 
@@ -802,7 +801,7 @@
         setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
         setupHierarchyDocuments("1");
 
-        final Path path = mProvider.findDocumentPath("15", null);
+        final Path path = mProvider.findDocumentPath(null, "15");
         assertEquals("1", path.getRootId());
         assertEquals(4, path.getPath().size());
         assertEquals("1", path.getPath().get(0));
@@ -816,7 +815,7 @@
         setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
         setupHierarchyDocuments("1");
 
-        final Path path = mProvider.findDocumentPath("18", "3");
+        final Path path = mProvider.findDocumentPath("3", "18");
         assertNull(path.getRootId());
         assertEquals(3, path.getPath().size());
         assertEquals("3", path.getPath().get(0));
@@ -831,7 +830,7 @@
                 new MtpRoot(0, 1, "Storage B", 1000, 1000, "") });
         setupHierarchyDocuments("2");
 
-        final Path path = mProvider.findDocumentPath("16", null);
+        final Path path = mProvider.findDocumentPath(null, "16");
         assertEquals("2", path.getRootId());
         assertEquals(4, path.getPath().size());
         assertEquals("2", path.getPath().get(0));
@@ -847,7 +846,7 @@
                 new MtpRoot(0, 1, "Storage B", 1000, 1000, "") });
         setupHierarchyDocuments("2");
 
-        final Path path = mProvider.findDocumentPath("19", "4");
+        final Path path = mProvider.findDocumentPath("4", "19");
         assertNull(path.getRootId());
         assertEquals(3, path.getPath().size());
         assertEquals("4", path.getPath().get(0));
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
index 8cfec7a..594a294 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
@@ -44,10 +44,9 @@
 import android.view.inputmethod.InputMethodInfo;
 import com.android.settingslib.BaseTest;
 
-import org.hamcrest.Description;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -249,7 +248,7 @@
         }
 
         @Override
-        public boolean matches(Object argument) {
+        public boolean matchesObject(Object argument) {
             if (argument instanceof Intent) {
                 return ((Intent) argument).filterEquals(mIntent);
             }
@@ -257,8 +256,8 @@
         }
 
         @Override
-        public void describeTo(Description description) {
-            description.appendText("Expected: " + mIntent);
+        public String toString() {
+            return "Expected: " + mIntent;
         }
     }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 0676efd..1fe3c48 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -976,8 +976,8 @@
                 Settings.Secure.VOICE_INTERACTION_SERVICE,
                 SecureSettingsProto.VOICE_INTERACTION_SERVICE);
         dumpSetting(s, p,
-                Settings.Secure.AUTO_FILL_SERVICE,
-                SecureSettingsProto.AUTO_FILL_SERVICE);
+                Settings.Secure.AUTOFILL_SERVICE,
+                SecureSettingsProto.AUTOFILL_SERVICE);
         dumpSetting(s, p,
                 Settings.Secure.BLUETOOTH_HCI_LOG,
                 SecureSettingsProto.BLUETOOTH_HCI_LOG);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 0916abe..91a4e79 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1578,8 +1578,14 @@
     }
 
     private List<String> getSettingsNamesLocked(int settingsType, int userId) {
-        ApplicationInfo ai = getCallingApplicationInfoOrThrow(userId);
-        if (ai.isInstantApp()) {
+        boolean instantApp;
+        if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
+            instantApp = false;
+        } else {
+            ApplicationInfo ai = getCallingApplicationInfoOrThrow();
+            instantApp = ai.isInstantApp();
+        }
+        if (instantApp) {
             return new ArrayList<String>(getInstantAppAccessibleSettings(settingsType));
         } else {
             return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
@@ -1590,7 +1596,7 @@
         if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
             return;
         }
-        ApplicationInfo ai = getCallingApplicationInfoOrThrow(userId);
+        ApplicationInfo ai = getCallingApplicationInfoOrThrow();
         if (!ai.isInstantApp()) {
             return;
         }
@@ -1600,10 +1606,16 @@
         }
     }
 
-    private ApplicationInfo getCallingApplicationInfoOrThrow(int userId) {
+    private ApplicationInfo getCallingApplicationInfoOrThrow() {
+        // We always use the callingUid for this lookup. This means that if hypothetically an
+        // app was installed in user A with cross user and in user B as an Instant App
+        // the app in A would be able to see all the settings in user B. However since cross
+        // user is a system permission and the app must be uninstalled in B and then installed as
+        // an Instant App that situation is not realistic or supported.
         ApplicationInfo ai = null;
         try {
-            ai = mPackageManager.getApplicationInfo(getCallingPackage(), 0 , userId);
+            ai = mPackageManager.getApplicationInfo(getCallingPackage(), 0
+                    , UserHandle.getCallingUserId());
         } catch (RemoteException ignored) {
         }
         if (ai == null) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b2e2a2c..dcc5501 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -177,6 +177,9 @@
 
     <uses-permission android:name="android.permission.MODIFY_THEME_OVERLAY" />
 
+    <!-- accessibility -->
+    <uses-permission android:name="android.permission.MODIFY_ACCESSIBILITY_DATA" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index fc0b568..51adc1e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -28,25 +28,42 @@
     androidprv:layout_maxWidth="@dimen/keyguard_security_width"
     androidprv:layout_maxHeight="@dimen/keyguard_security_height"
     android:gravity="center_horizontal|top">
-    <LinearLayout
+    <RelativeLayout
         android:id="@+id/keyguard_clock_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal|top"
-        android:orientation="vertical" >
+        android:layout_gravity="center_horizontal|top">
         <TextClock
             android:id="@+id/clock_view"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentTop="true"
             android:textColor="@color/clock_white"
             android:singleLine="true"
             style="@style/widget_big_thin"
             android:format12Hour="@string/keyguard_widget_12_hours_format"
             android:format24Hour="@string/keyguard_widget_24_hours_format"
             android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+        <com.android.systemui.ChargingView
+            android:id="@+id/battery_doze"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignTop="@id/clock_view"
+            android:layout_alignBottom="@id/clock_view"
+            android:layout_toEndOf="@id/clock_view"
+            android:visibility="invisible"
+            android:src="@drawable/ic_aod_charging_24dp"
+            android:contentDescription="@string/accessibility_ambient_display_charging"
+        />
 
-        <include layout="@layout/keyguard_status_area" />
+        <include layout="@layout/keyguard_status_area"
+            android:id="@+id/keyguard_status_area"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/clock_view" />
+
         <TextView
             android:id="@+id/owner_info"
             android:layout_marginLeft="16dp"
@@ -54,12 +71,13 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/date_owner_info_margin"
-            android:layout_gravity="center_horizontal"
+            android:layout_centerHorizontal="true"
+            android:layout_below="@id/keyguard_status_area"
             android:textColor="@color/clock_gray"
             android:textSize="@dimen/widget_label_font_size"
             android:letterSpacing="0.05"
             android:ellipsize="marquee"
             android:singleLine="true" />
 
-    </LinearLayout>
+    </RelativeLayout>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml
new file mode 100644
index 0000000..6134b8f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_aod_charging_24dp.xml
@@ -0,0 +1,24 @@
+<!--
+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="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M11.0,22.98l0.0,-8.98 -4.0,0.0 6.0,-13.0 0.0,9.0 4.0,0.0z"
+        android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/pip_expand_ll.xml b/packages/SystemUI/res/drawable/pip_expand_ll.xml
new file mode 100644
index 0000000..a8b82b5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_expand_ll.xml
@@ -0,0 +1,34 @@
+<?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="60dp"
+    android:height="60dp"
+    android:viewportWidth="60"
+    android:viewportHeight="60">
+
+    <path
+        android:fillColor="#fff"
+        android:pathData="M7.5,52h45a5,5,0,0,0,5-5V12.95A5,5,0,0,0,52.5,8H7.5a5,5,0,0,0-5,4.95V47A5,5,0,0,0,7.5,52Zm-1-5V13a1,1,0,0,1,1-1h45a1,1,0,0,1,1,1V47a1,1,0,0,1-1,1H7.5A1,1,0,0,1,6.5,47Z" />
+    <path
+        android:pathData="M0,0V60H60V0H0Z" />
+    <path
+        android:fillColor="#fff"
+        android:pathData="M35,39.14v2a1,1,0,0,0,1,1H46.5a1,1,0,0,0,1-1V30.64a1,1,0,0,0-1-1h-2a1,1,0,0,0-1,1v7.5H36A1,1,0,0,0,35,39.14Z" />
+    <path
+        android:fillColor="#fff"
+        android:pathData="M13.5,30.36h2a1,1,0,0,0,1-1v-7.5H24a1,1,0,0,0,1-1v-2a1,1,0,0,0-1-1H13.5a1,1,0,0,0-1,1v10.5A1,1,0,0,0,13.5,30.36Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pip_expand_lr.xml b/packages/SystemUI/res/drawable/pip_expand_lr.xml
new file mode 100644
index 0000000..44d97ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_expand_lr.xml
@@ -0,0 +1,39 @@
+<?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="60dp"
+    android:height="60dp"
+    android:viewportWidth="60"
+    android:viewportHeight="60">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M57.5,47V12.95c0-2.75-2.25-4.95-5-4.95h-45c-2.75,0-5,2.2-5,4.95V47c0,2.75,2.25,5,5,5h45
+C55.25,52,57.5,49.75,57.5,47z
+M52.5,48h-45c-0.55,0-1-0.45-1-1V13c0-0.55,0.45-1,1-1h45c0.55,0,1,0.45,1,1v34
+C53.5,47.55,53.05,48,52.5,48z" />
+    <path
+        android:pathData="M60,0v60H0L0,0L60,0z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M25,39.14v2c0,0.55-0.45,1-1,1H13.5c-0.55,0-1-0.45-1-1v-10.5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v7.5
+H24C24.55,38.14,25,38.59,25,39.14z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M46.5,30.36h-2c-0.55,0-1-0.45-1-1v-7.5H36c-0.55,0-1-0.45-1-1v-2c0-0.55,0.45-1,1-1h10.5
+c0.55,0,1,0.45,1,1v10.5C47.5,29.91,47.05,30.36,46.5,30.36z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pip_expand_pl.xml b/packages/SystemUI/res/drawable/pip_expand_pl.xml
new file mode 100644
index 0000000..57b9358
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_expand_pl.xml
@@ -0,0 +1,39 @@
+<?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="60dp"
+    android:height="60dp"
+    android:viewportWidth="60"
+    android:viewportHeight="60">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M47,2.5H12.95C10.2,2.5,8,4.75,8,7.5v45c0,2.75,2.2,5,4.95,5H47c2.75,0,5-2.25,5-5v-45
+C52,4.75,49.75,2.5,47,2.5z
+M48,7.5v45c0,0.55-0.45,1-1,1H13c-0.55,0-1-0.45-1-1v-45c0-0.55,0.45-1,1-1h34
+C47.55,6.5,48,6.95,48,7.5z" />
+    <path
+        android:pathData="M0,0l60,0v60H0L0,0z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M39.14,35h2c0.55,0,1,0.45,1,1v10.5c0,0.55-0.45,1-1,1h-10.5c-0.55,0-1-0.45-1-1v-2c0-0.55,0.45-1,1-1h7.5
+V36C38.14,35.45,38.59,35,39.14,35z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M30.36,13.5v2c0,0.55-0.45,1-1,1h-7.5V24c0,0.55-0.45,1-1,1h-2c-0.55,0-1-0.45-1-1V13.5c0-0.55,0.45-1,1-1
+h10.5C29.91,12.5,30.36,12.95,30.36,13.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pip_expand.xml b/packages/SystemUI/res/drawable/pip_expand_pr.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/pip_expand.xml
rename to packages/SystemUI/res/drawable/pip_expand_pr.xml
diff --git a/packages/SystemUI/res/layout/pip_menu_action.xml b/packages/SystemUI/res/layout/pip_menu_action.xml
index 9b954f7..77efc9b 100644
--- a/packages/SystemUI/res/layout/pip_menu_action.xml
+++ b/packages/SystemUI/res/layout/pip_menu_action.xml
@@ -15,7 +15,7 @@
 -->
 <ImageView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="48dp"
-    android:layout_height="48dp"
-    android:padding="10dp"
+    android:layout_width="@dimen/pip_action_size"
+    android:layout_height="@dimen/pip_action_size"
+    android:padding="@dimen/pip_action_padding"
     android:background="?android:selectableItemBackgroundBorderless" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
index f38c8ff..5e49d05 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -18,38 +18,39 @@
     android:id="@+id/menu"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="#00000000">
+    android:background="#4D000000">
     <!-- The above background is only for the dismiss button ripple to show. -->
 
     <ImageView
         android:id="@+id/dismiss"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
+        android:layout_width="@dimen/pip_action_size"
+        android:layout_height="@dimen/pip_action_size"
         android:layout_gravity="top|end"
-        android:padding="10dp"
+        android:padding="@dimen/pip_action_padding"
         android:contentDescription="@string/pip_phone_close"
         android:src="@drawable/ic_close_white"
         android:background="?android:selectableItemBackgroundBorderless" />
 
+    <!-- The margins for this container is calculated in the code depending on whether the
+         actions_container is visible. -->
     <FrameLayout
         android:id="@+id/expand_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         <ImageView
-            android:layout_width="64dp"
-            android:layout_height="64dp"
+            android:id="@+id/expand_button"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
             android:layout_gravity="center"
             android:contentDescription="@string/pip_phone_expand"
-            android:src="@drawable/pip_expand"
             android:background="?android:selectableItemBackgroundBorderless" />
     </FrameLayout>
 
     <FrameLayout
         android:id="@+id/actions_container"
         android:layout_width="match_parent"
-        android:layout_height="48dp"
+        android:layout_height="@dimen/pip_action_size"
         android:layout_gravity="bottom"
-        android:background="#66000000"
         android:visibility="invisible">
         <LinearLayout
             android:id="@+id/actions_group"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f331d87..ffaa7ba 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -738,6 +738,16 @@
          the configuration of the device, so we can't use -land resources. -->
     <dimen name="pip_between_action_padding_land">8dp</dimen>
 
+    <!-- The height of the PiP actions container in which the actions are vertically centered. -->
+    <dimen name="pip_action_size">48dp</dimen>
+
+    <!-- The padding around a PiP actions. -->
+    <dimen name="pip_action_padding">12dp</dimen>
+
+    <!-- The bottom margin of the expand container when there are actions.
+         Equal to pip_action_size - pip_action_padding. -->
+    <dimen name="pip_expand_container_edge_margin">36dp</dimen>
+
     <dimen name="default_gear_space">18dp</dimen>
     <dimen name="cell_overlay_padding">18dp</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 93ae763..1541649 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -565,6 +565,9 @@
     <!-- Content description of the display brightness slider (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_brightness">Display brightness</string>
 
+    <!-- Content description of the charging indicator on Ambient Display (lower-power version of the lock screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_ambient_display_charging">Charging</string>
+
     <!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
     <string name="data_usage_disabled_dialog_3g_title">2G-3G data is paused</string>
     <!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
@@ -1815,6 +1818,9 @@
     <!-- App label of the instant apps notification [CHAR LIMIT=60] -->
     <string name="instant_apps">Instant Apps</string>
 
+    <!-- Title of menu shown over picture-in-picture. Used for accessibility. -->
+    <string name="pip_menu_title">Picture in picture menu</string>
+
     <!-- Message of the instant apps notification indicating they don't need install [CHAR LIMIT=NONE] -->
     <string name="instant_apps_message">Instant apps don\'t require installation.</string>
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f8f4f2a..2655837 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -35,6 +35,7 @@
 import android.widget.TextView;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.ChargingView;
 
 import java.util.Locale;
 
@@ -50,6 +51,7 @@
     private TextClock mClockView;
     private TextView mOwnerInfo;
     private ViewGroup mClockContainer;
+    private ChargingView mBatteryDoze;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -114,6 +116,7 @@
         mDateView.setShowCurrentUserTime(true);
         mClockView.setShowCurrentUserTime(true);
         mOwnerInfo = (TextView) findViewById(R.id.owner_info);
+        mBatteryDoze = (ChargingView) findViewById(R.id.battery_doze);
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
         setEnableMarquee(shouldMarquee);
@@ -273,10 +276,11 @@
         final int N = mClockContainer.getChildCount();
         for (int i = 0; i < N; i++) {
             View child = mClockContainer.getChildAt(i);
-            if (child == mClockView) {
+            if (child == mClockView || child == mBatteryDoze) {
                 continue;
             }
             child.setAlpha(dark ? 0 : 1);
         }
+        mBatteryDoze.setDark(dark);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ChargingView.java b/packages/SystemUI/src/com/android/systemui/ChargingView.java
new file mode 100644
index 0000000..555cc74
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ChargingView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+/**
+ * A view that only shows its drawable while the phone is charging.
+ *
+ * Also reloads its drawable upon density changes.
+ */
+public class ChargingView extends ImageView implements
+        BatteryController.BatteryStateChangeCallback,
+        ConfigurationController.ConfigurationListener {
+
+    private BatteryController mBatteryController;
+    private int mImageResource;
+    private boolean mCharging;
+    private boolean mDark;
+
+    public ChargingView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.src});
+        int srcResId = a.getResourceId(0, 0);
+
+        if (srcResId != 0) {
+            mImageResource = srcResId;
+        }
+
+        a.recycle();
+
+        updateVisibility();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mBatteryController = Dependency.get(BatteryController.class);
+        mBatteryController.addCallback(this);
+        Dependency.get(ConfigurationController.class).addCallback(this);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mBatteryController.removeCallback(this);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
+    }
+
+    @Override
+    public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+        mCharging = charging;
+        updateVisibility();
+    }
+
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        setImageResource(mImageResource);
+    }
+
+    public void setDark(boolean dark) {
+        mDark = dark;
+        updateVisibility();
+    }
+
+    private void updateVisibility() {
+        setVisibility(mCharging && mDark ? VISIBLE : INVISIBLE);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 5d57daa..ba8e54a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -22,12 +22,12 @@
 import android.content.Context;
 import android.hardware.SensorManager;
 import android.os.Handler;
-import android.os.PowerManager;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.systemui.SystemUIApplication;
 import com.android.systemui.plugins.doze.DozeProvider;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.wakelock.WakeLock;
 
 public class DozeFactory {
 
@@ -41,19 +41,17 @@
     public DozeMachine assembleMachine(DozeService dozeService) {
         Context context = dozeService;
         SensorManager sensorManager = context.getSystemService(SensorManager.class);
-        PowerManager powerManager = context.getSystemService(PowerManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
 
         DozeHost host = getHost(dozeService);
         AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
         DozeParameters params = new DozeParameters(context);
         Handler handler = new Handler();
-        DozeFactory.WakeLock wakeLock = new DozeFactory.WakeLock(powerManager.newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, "Doze"));
+        WakeLock wakeLock = WakeLock.createPartial(context, "Doze");
 
         DozeMachine machine = new DozeMachine(
                 DozeScreenStatePreventingAdapter.wrapIfNeeded(dozeService, params),
-                params,
+                config,
                 wakeLock);
         machine.setParts(new DozeMachine.Part[]{
                 createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
@@ -157,28 +155,4 @@
         final SystemUIApplication app = (SystemUIApplication) appCandidate;
         return app.getComponent(DozeHost.class);
     }
-
-    /** A wrapper around {@link PowerManager.WakeLock} for testability. */
-    public static class WakeLock implements DozeProvider.WakeLock {
-        private final PowerManager.WakeLock mInner;
-
-        public WakeLock(PowerManager.WakeLock inner) {
-            mInner = inner;
-        }
-
-        /** @see PowerManager.WakeLock#acquire() */
-        public void acquire() {
-            mInner.acquire();
-        }
-
-        /** @see PowerManager.WakeLock#release() */
-        public void release() {
-            mInner.release();
-        }
-
-        /** @see PowerManager.WakeLock#wrap(Runnable) */
-        public Runnable wrap(Runnable runnable) {
-            return mInner.wrap(runnable);
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index c9eb790..f27521e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -17,12 +17,14 @@
 package com.android.systemui.doze;
 
 import android.annotation.MainThread;
+import android.os.UserHandle;
 import android.util.Log;
 import android.view.Display;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.util.Preconditions;
-import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.Assert;
+import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -94,17 +96,18 @@
     }
 
     private final Service mDozeService;
-    private final DozeFactory.WakeLock mWakeLock;
-    private final DozeParameters mParams;
+    private final WakeLock mWakeLock;
+    private final AmbientDisplayConfiguration mConfig;
     private Part[] mParts;
 
     private final ArrayList<State> mQueuedRequests = new ArrayList<>();
     private State mState = State.UNINITIALIZED;
     private boolean mWakeLockHeldForCurrentState = false;
 
-    public DozeMachine(Service service, DozeParameters params, DozeFactory.WakeLock wakeLock) {
+    public DozeMachine(Service service, AmbientDisplayConfiguration config,
+            WakeLock wakeLock) {
         mDozeService = service;
-        mParams = params;
+        mConfig = config;
         mWakeLock = wakeLock;
     }
 
@@ -267,7 +270,7 @@
         switch (state) {
             case INITIALIZED:
             case DOZE_PULSE_DONE:
-                transitionTo(mParams.getAlwaysOn()
+                transitionTo(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
                         ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
                 break;
             default:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 9cc927d..2ac0657 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -36,6 +36,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -53,14 +54,14 @@
     private final TriggerSensor mPickupSensor;
     private final DozeParameters mDozeParameters;
     private final AmbientDisplayConfiguration mConfig;
-    private final DozeFactory.WakeLock mWakeLock;
+    private final WakeLock mWakeLock;
     private final Callback mCallback;
 
     private final Handler mHandler = new Handler();
 
 
     public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
-            AmbientDisplayConfiguration config, DozeFactory.WakeLock wakeLock, Callback callback) {
+            AmbientDisplayConfiguration config, WakeLock wakeLock, Callback callback) {
         mContext = context;
         mSensorManager = sensorManager;
         mDozeParameters = dozeParameters;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b5c7dd3..1b9bf73 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -36,6 +36,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.Assert;
+import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
 
@@ -57,7 +58,7 @@
     private final DozeParameters mDozeParameters;
     private final SensorManager mSensorManager;
     private final Handler mHandler;
-    private final DozeFactory.WakeLock mWakeLock;
+    private final WakeLock mWakeLock;
     private final boolean mAllowPulseTriggers;
     private final UiModeManager mUiModeManager;
     private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
@@ -69,7 +70,7 @@
     public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost,
             AmbientDisplayConfiguration config,
             DozeParameters dozeParameters, SensorManager sensorManager, Handler handler,
-            DozeFactory.WakeLock wakeLock, boolean allowPulseTriggers) {
+            WakeLock wakeLock, boolean allowPulseTriggers) {
         mContext = context;
         mMachine = machine;
         mDozeHost = dozeHost;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 76e0283..f577654 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -21,6 +21,8 @@
 import android.os.Handler;
 import android.os.SystemClock;
 
+import com.android.systemui.util.wakelock.WakeLock;
+
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 
@@ -33,14 +35,14 @@
     private final AlarmManager mAlarmManager;
     private final DozeHost mHost;
     private final Handler mHandler;
-    private final DozeFactory.WakeLock mWakeLock;
+    private final WakeLock mWakeLock;
     private final DozeMachine mMachine;
     private final AlarmManager.OnAlarmListener mTimeTick;
 
     private boolean mTimeTickScheduled = false;
 
     public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
-            DozeFactory.WakeLock wakeLock, DozeHost host, Handler handler) {
+            WakeLock wakeLock, DozeHost host, Handler handler) {
         mContext = context;
         mAlarmManager = alarmManager;
         mMachine = machine;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
index 7a1849e..762d6bc 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
@@ -44,6 +44,14 @@
     }
 
     /**
+     * Listener interface for callers to learn when this class is registered or unregistered with
+     * window manager
+     */
+    public interface RegistrationListener {
+        void onRegistrationChanged(boolean isRegistered);
+    }
+
+    /**
      * Input handler used for the PiP input consumer.
      */
     private final class PipInputEventReceiver extends InputEventReceiver {
@@ -71,6 +79,7 @@
 
     private PipInputEventReceiver mInputEventReceiver;
     private TouchListener mListener;
+    private RegistrationListener mRegistrationListener;
 
     public InputConsumerController(IWindowManager windowManager) {
         mWindowManager = windowManager;
@@ -85,6 +94,22 @@
     }
 
     /**
+     * Sets the registration listener.
+     */
+    public void setRegistrationListener(RegistrationListener listener) {
+        mRegistrationListener = listener;
+    }
+
+    /**
+     * Check if the InputConsumer is currently registered with WindowManager
+     *
+     * @return {@code true} if registered, {@code false} if not.
+     */
+    public boolean isRegistered() {
+        return mInputEventReceiver != null;
+    }
+
+    /**
      * Registers the input consumer.
      */
     public void registerInputConsumer() {
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 65de22e..86e2c49 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -16,6 +16,11 @@
 
 package com.android.systemui.pip.phone;
 
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACTIONS;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -26,20 +31,25 @@
 import android.app.RemoteAction;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.util.Log;
+import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -71,6 +81,7 @@
     private View mMenuContainer;
     private LinearLayout mActionsGroup;
     private View mDismissButton;
+    private ImageView mExpandButton;
     private int mBetweenActionPaddingLand;
 
     private ObjectAnimator mMenuContainerAnimator;
@@ -85,7 +96,8 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MESSAGE_SHOW_MENU:
-                    showMenu();
+                    Pair<Rect, Rect> bounds = (Pair<Rect, Rect>) msg.obj;
+                    showMenu(bounds.first, bounds.second);
                     break;
                 case MESSAGE_POKE_MENU:
                     cancelDelayedFinish();
@@ -94,7 +106,8 @@
                     hideMenu();
                     break;
                 case MESSAGE_UPDATE_ACTIONS:
-                    setActions(((ParceledListSlice) msg.obj).getList());
+                    Pair<Rect, ParceledListSlice> data = (Pair<Rect, ParceledListSlice>) msg.obj;
+                    setActions(data.first, data.second.getList());
                     break;
             }
         }
@@ -117,15 +130,6 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.pip_menu_activity);
 
-        Intent startingIntent = getIntent();
-        mToControllerMessenger = startingIntent.getParcelableExtra(
-                PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER);
-        ParceledListSlice actions = startingIntent.getParcelableExtra(
-                PipMenuActivityController.EXTRA_ACTIONS);
-        if (actions != null) {
-            setActions(actions.getList());
-        }
-
         mMenuContainer = findViewById(R.id.menu);
         mMenuContainer.setOnClickListener((v) -> {
             expandPip();
@@ -137,15 +141,17 @@
         mActionsGroup = (LinearLayout) findViewById(R.id.actions_group);
         mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
                 R.dimen.pip_between_action_padding_land);
+        mExpandButton = (ImageView) findViewById(R.id.expand_button);
 
+        updateFromIntent(getIntent());
+        setTitle(R.string.pip_menu_title);
         notifyActivityCallback(mMessenger);
-        showMenu();
     }
 
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
-        showMenu();
+        updateFromIntent(intent);
     }
 
     @Override
@@ -214,13 +220,14 @@
         // Do nothing
     }
 
-    private void showMenu() {
+    private void showMenu(Rect stackBounds, Rect movementBounds) {
         if (!mMenuVisible) {
             if (mMenuContainerAnimator != null) {
                 mMenuContainerAnimator.cancel();
             }
 
             notifyMenuVisibility(true);
+            updateExpandButtonFromBounds(stackBounds, movementBounds);
             mMenuContainerAnimator = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
                     mMenuContainer.getAlpha(), 1f);
             mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
@@ -257,19 +264,52 @@
                     if (animationFinishedRunnable != null) {
                         animationFinishedRunnable.run();
                     }
+                    if (getSystemService(AccessibilityManager.class).isEnabled()) {
+                        finish();
+                    }
                 }
             });
             mMenuContainerAnimator.start();
         }
     }
 
-    private void setActions(List<RemoteAction> actions) {
-        mActions.clear();
-        mActions.addAll(actions);
-        updateActionViews();
+    private void updateFromIntent(Intent intent) {
+        Rect stackBounds = Rect.unflattenFromString(intent.getStringExtra(EXTRA_STACK_BOUNDS));
+        Rect movementBounds = Rect.unflattenFromString(intent.getStringExtra(
+                EXTRA_MOVEMENT_BOUNDS));
+        mToControllerMessenger = intent.getParcelableExtra(EXTRA_CONTROLLER_MESSENGER);
+        ParceledListSlice actions = intent.getParcelableExtra(EXTRA_ACTIONS);
+        if (actions != null) {
+            setActions(stackBounds, actions.getList());
+        }
+        showMenu(stackBounds, movementBounds);
     }
 
-    private void updateActionViews() {
+    private void updateExpandButtonFromBounds(Rect stackBounds, Rect movementBounds) {
+        if (stackBounds == null) {
+            return;
+        }
+
+        boolean isLandscapePip = stackBounds.width() > stackBounds.height();
+        boolean left = stackBounds.left < movementBounds.centerX();
+        boolean top = stackBounds.top < movementBounds.centerY();
+        boolean expandL = (left && top) || (!left && !top);
+        int iconResId;
+        if (isLandscapePip) {
+            iconResId = expandL ? R.drawable.pip_expand_ll : R.drawable.pip_expand_lr;
+        } else {
+            iconResId = expandL ? R.drawable.pip_expand_pl : R.drawable.pip_expand_pr;
+        }
+        mExpandButton.setImageResource(iconResId);
+    }
+
+    private void setActions(Rect stackBounds, List<RemoteAction> actions) {
+        mActions.clear();
+        mActions.addAll(actions);
+        updateActionViews(stackBounds);
+    }
+
+    private void updateActionViews(Rect stackBounds) {
         ViewGroup expandContainer = (ViewGroup) findViewById(R.id.expand_container);
         ViewGroup actionsContainer = (ViewGroup) findViewById(R.id.actions_container);
         actionsContainer.setOnTouchListener((v, ev) -> {
@@ -277,7 +317,6 @@
             return true;
         });
 
-        int actionsContainerHeight = 0;
         if (mActions.isEmpty()) {
             actionsContainer.setVisibility(View.INVISIBLE);
         } else {
@@ -286,9 +325,8 @@
                 mActionsGroup.removeAllViews();
 
                 // Recreate the layout
-                final View decorView = getWindow().getDecorView();
-                final boolean isLandscapePip = decorView.getMeasuredWidth()
-                        > decorView.getMeasuredHeight();
+                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);
@@ -314,13 +352,17 @@
                     mActionsGroup.addView(actionView);
                 }
             }
-            actionsContainerHeight = actionsContainer.getLayoutParams().height;
-        }
 
-        // Update the expand container margin to account for the existence of the action container
-        ((FrameLayout.LayoutParams) expandContainer.getLayoutParams()).bottomMargin =
-                actionsContainerHeight;
-        expandContainer.requestLayout();
+            // Update the expand container margin to adjust the center of the expand button to
+            // account for the existence of the action container
+            FrameLayout.LayoutParams expandedLp =
+                    (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
+            expandedLp.topMargin = getResources().getDimensionPixelSize(
+                    R.dimen.pip_action_padding);
+            expandedLp.bottomMargin = getResources().getDimensionPixelSize(
+                    R.dimen.pip_expand_container_edge_margin);
+            expandContainer.requestLayout();
+        }
     }
 
     private void notifyRegisterInputConsumer() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 0b1c3ec..badf64b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -25,12 +25,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Pair;
 import android.view.IWindowManager;
 
 import com.android.systemui.pip.phone.PipMediaController.ActionListener;
@@ -51,6 +53,8 @@
 
     public static final String EXTRA_CONTROLLER_MESSENGER = "messenger";
     public static final String EXTRA_ACTIONS = "actions";
+    public static final String EXTRA_STACK_BOUNDS = "stack_bounds";
+    public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds";
 
     public static final int MESSAGE_MENU_VISIBILITY_CHANGED = 100;
     public static final int MESSAGE_EXPAND_PIP = 101;
@@ -177,10 +181,11 @@
     /**
      * Shows the menu activity.
      */
-    public void showMenu() {
+    public void showMenu(Rect stackBounds, Rect movementBounds) {
         if (mToActivityMessenger != null) {
             Message m = Message.obtain();
             m.what = PipMenuActivity.MESSAGE_SHOW_MENU;
+            m.obj = new Pair<>(stackBounds, movementBounds);
             try {
                 mToActivityMessenger.send(m);
             } catch (RemoteException e) {
@@ -195,6 +200,8 @@
                     Intent intent = new Intent(mContext, PipMenuActivity.class);
                     intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger);
                     intent.putExtra(EXTRA_ACTIONS, resolveMenuActions());
+                    intent.putExtra(EXTRA_STACK_BOUNDS, stackBounds.flattenToString());
+                    intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds.flattenToString());
                     ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
                     options.setLaunchTaskId(
                             pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
@@ -269,9 +276,20 @@
      */
     private void updateMenuActions() {
         if (mToActivityMessenger != null) {
+            // Fetch the pinned stack bounds
+            Rect stackBounds = null;
+            try {
+                StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+                if (pinnedStackInfo != null) {
+                    stackBounds = pinnedStackInfo.bounds;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error showing PIP menu activity", e);
+            }
+
             Message m = Message.obtain();
             m.what = PipMenuActivity.MESSAGE_UPDATE_ACTIONS;
-            m.obj = resolveMenuActions();
+            m.obj = new Pair<>(stackBounds, resolveMenuActions());
             try {
                 mToActivityMessenger.send(m);
             } catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 20c1136..49d89a2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -56,7 +56,8 @@
 
     private static final int DEFAULT_MOVE_STACK_DURATION = 225;
     private static final int SNAP_STACK_DURATION = 225;
-    private static final int DISMISS_STACK_DURATION = 375;
+    private static final int DRAG_TO_TARGET_DISMISS_STACK_DURATION = 375;
+    private static final int DRAG_TO_DISMISS_STACK_DURATION = 175;
     private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
     private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
     private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 300;
@@ -65,6 +66,8 @@
 
     // The fraction of the stack width that the user has to drag offscreen to minimize the PiP
     private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.2f;
+    // The fraction of the stack height that the user has to drag offscreen to minimize the PiP
+    private static final float DISMISS_OFFSCREEN_FRACTION = 0.35f;
 
     private Context mContext;
     private IActivityManager mActivityManager;
@@ -194,6 +197,19 @@
     }
 
     /**
+     * @return whether the PiP at the current bounds should be dismissed.
+     */
+    boolean shouldDismissPip() {
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        if (mBounds.bottom > displaySize.y) {
+            float offscreenFraction = (float) (mBounds.bottom - displaySize.y) / mBounds.height();
+            return offscreenFraction >= DISMISS_OFFSCREEN_FRACTION;
+        }
+        return false;
+    }
+
+    /**
      * Flings the minimized PiP to the closest minimized snap target.
      */
     Rect flingToMinimizedState(float velocityY, Rect movementBounds) {
@@ -298,15 +314,37 @@
     }
 
     /**
+     * Animates the dismissal of the PiP off the edge of the screen.
+     */
+    Rect animateDragToEdgeDismiss(Rect pipBounds) {
+        cancelAnimations();
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        Rect toBounds = new Rect(pipBounds);
+        toBounds.offset(0, displaySize.y - pipBounds.top);
+        mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION,
+                FAST_OUT_LINEAR_IN, mUpdateBoundsListener);
+        mBoundsAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                dismissPip();
+            }
+        });
+        mBoundsAnimator.start();
+        return toBounds;
+    }
+
+    /**
      * Animates the dismissal of the PiP over the dismiss target bounds.
      */
-    Rect animateDismissFromDrag(Rect dismissBounds) {
+    Rect animateDragToTargetDismiss(Rect dismissBounds) {
         cancelAnimations();
         Rect toBounds = new Rect(dismissBounds.centerX(),
                 dismissBounds.centerY(),
                 dismissBounds.centerX() + 1,
                 dismissBounds.centerY() + 1);
-        mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DISMISS_STACK_DURATION,
+        mBoundsAnimator = createAnimationToBounds(mBounds, toBounds,
+                DRAG_TO_TARGET_DISMISS_STACK_DURATION,
                 FAST_OUT_LINEAR_IN, mUpdateBoundsListener);
         mBoundsAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 010522d..17c3448 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -21,14 +21,22 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Size;
 import android.view.IPinnedStackController;
-import android.view.IWindowManager;
+import android.view.MagnificationSpec;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -37,6 +45,8 @@
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
@@ -52,7 +62,8 @@
     private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 200;
 
     // Allow dragging the PIP to a location to close it
-    private static final boolean ENABLE_DRAG_TO_DISMISS = false;
+    private static final boolean ENABLE_DISMISS_DRAG_TO_TARGET = false;
+    private static final boolean ENABLE_DISMISS_DRAG_TO_EDGE = false;
 
     private final Context mContext;
     private final IActivityManager mActivityManager;
@@ -63,6 +74,7 @@
     private final PipMenuActivityController mMenuController;
     private final PipDismissViewController mDismissViewController;
     private final PipSnapAlgorithm mSnapAlgorithm;
+    private final AccessibilityManager mAccessibilityManager;
 
     // The current movement bounds
     private Rect mMovementBounds = new Rect();
@@ -78,18 +90,26 @@
     private Runnable mShowDismissAffordance = new Runnable() {
         @Override
         public void run() {
-            if (ENABLE_DRAG_TO_DISMISS) {
+            if (ENABLE_DISMISS_DRAG_TO_TARGET) {
                 mDismissViewController.showDismissTarget(mMotionHelper.getBounds());
             }
         }
     };
 
+    private Runnable mShowMenuRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+        }
+    };
+
     // Behaviour states
     private boolean mIsMenuVisible;
     private boolean mIsMinimized;
     private boolean mIsImeShowing;
     private int mImeHeight;
     private float mSavedSnapFraction = -1f;
+    private boolean mSendingHoverAccessibilityEvents;
 
     // Touch state
     private final PipTouchState mTouchState;
@@ -137,6 +157,7 @@
         // Initialize the Pip input consumer
         mContext = context;
         mActivityManager = activityManager;
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         mViewConfig = ViewConfiguration.get(context);
         mMenuController = menuController;
         mMenuController.addListener(mMenuListener);
@@ -154,6 +175,8 @@
 
         // Register the listener for input consumer touch events
         inputConsumerController.setTouchListener(this::handleTouchEvent);
+        inputConsumerController.setRegistrationListener(this::onRegistrationChanged);
+        onRegistrationChanged(inputConsumerController.isRegistered());
     }
 
     public void setTouchEnabled(boolean enabled) {
@@ -238,6 +261,11 @@
         updateMovementBounds(mIsMenuVisible);
     }
 
+    private void onRegistrationChanged(boolean isRegistered) {
+        mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
+                ? new AccessibilityInteractionConnection() : null);
+    }
+
     private boolean handleTouchEvent(MotionEvent ev) {
         // Skip touch handling until we are bound to the controller
         if (mPinnedStackController == null) {
@@ -281,6 +309,31 @@
                 mTouchState.reset();
                 break;
             }
+            case MotionEvent.ACTION_HOVER_ENTER:
+            case MotionEvent.ACTION_HOVER_MOVE: {
+                if (!mSendingHoverAccessibilityEvents) {
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+                    AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo();
+                    event.setSource(info);
+                    info.recycle();
+                    mAccessibilityManager.sendAccessibilityEvent(event);
+                    mSendingHoverAccessibilityEvents = true;
+                }
+                break;
+            }
+            case MotionEvent.ACTION_HOVER_EXIT: {
+                if (mSendingHoverAccessibilityEvents) {
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+                    AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo();
+                    event.setSource(info);
+                    info.recycle();
+                    mAccessibilityManager.sendAccessibilityEvent(event);
+                    mSendingHoverAccessibilityEvents = false;
+                }
+                break;
+            }
         }
         return !mIsMenuVisible;
     }
@@ -378,7 +431,7 @@
                 mMenuController.pokeMenu();
             }
 
-            if (ENABLE_DRAG_TO_DISMISS) {
+            if (ENABLE_DISMISS_DRAG_TO_TARGET) {
                 mDismissViewController.createDismissTarget();
                 mHandler.postDelayed(mShowDismissAffordance, SHOW_DISMISS_AFFORDANCE_DELAY);
             }
@@ -394,7 +447,7 @@
                 mSavedSnapFraction = -1f;
             }
 
-            if (touchState.startedDragging() && ENABLE_DRAG_TO_DISMISS) {
+            if (touchState.startedDragging() && ENABLE_DISMISS_DRAG_TO_TARGET) {
                 mHandler.removeCallbacks(mShowDismissAffordance);
                 mDismissViewController.showDismissTarget(mMotionHelper.getBounds());
             }
@@ -408,11 +461,16 @@
                 if (!touchState.allowDraggingOffscreen()) {
                     left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
                 }
-                top = Math.max(mMovementBounds.top, Math.min(mMovementBounds.bottom, top));
+                if (ENABLE_DISMISS_DRAG_TO_EDGE) {
+                    // Allow pip to move past bottom bounds
+                    top = Math.max(mMovementBounds.top, top);
+                } else {
+                    top = Math.max(mMovementBounds.top, Math.min(mMovementBounds.bottom, top));
+                }
                 mTmpBounds.offsetTo((int) left, (int) top);
                 mMotionHelper.movePip(mTmpBounds);
 
-                if (ENABLE_DRAG_TO_DISMISS) {
+                if (ENABLE_DISMISS_DRAG_TO_TARGET) {
                     mDismissViewController.updateDismissTarget(mTmpBounds);
                 }
                 return true;
@@ -427,7 +485,7 @@
             }
 
             try {
-                if (ENABLE_DRAG_TO_DISMISS) {
+                if (ENABLE_DISMISS_DRAG_TO_TARGET) {
                     mHandler.removeCallbacks(mShowDismissAffordance);
                     PointF vel = mTouchState.getVelocity();
                     final float velocity = PointF.length(vel.x, vel.y);
@@ -435,7 +493,7 @@
                             && velocity < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
                         if (mDismissViewController.shouldDismiss(mMotionHelper.getBounds())) {
                             Rect dismissBounds = mDismissViewController.getDismissBounds();
-                            mMotionHelper.animateDismissFromDrag(dismissBounds);
+                            mMotionHelper.animateDragToTargetDismiss(dismissBounds);
                             MetricsLogger.action(mContext,
                                     MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
                                     METRIC_VALUE_DISMISSED_BY_DRAG);
@@ -448,9 +506,17 @@
             }
 
             if (touchState.isDragging()) {
-                PointF vel = mTouchState.getVelocity();
-                if (!mIsMinimized && (mMotionHelper.shouldMinimizePip()
-                        || isHorizontalFlingTowardsCurrentEdge(vel))) {
+                final boolean onLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
+                boolean isFlingToBot = isFlingTowardsEdge(touchState, 4 /* bottom */);
+                if (ENABLE_DISMISS_DRAG_TO_EDGE
+                        && (mMotionHelper.shouldDismissPip() || isFlingToBot)) {
+                    mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds());
+                    MetricsLogger.action(mContext,
+                            MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
+                            METRIC_VALUE_DISMISSED_BY_DRAG);
+                    return true;
+                } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip()
+                        || isFlingTowardsEdge(touchState, onLeft ? 2 : 3))) {
                     // Pip should be minimized
                     setMinimizedStateInternal(true);
                     if (mMenuController.isMenuVisible()) {
@@ -472,9 +538,10 @@
                 // If the menu is still visible, and we aren't minimized, then just poke the menu
                 // so that it will timeout after the user stops touching it
                 if (mMenuController.isMenuVisible()) {
-                    mMenuController.showMenu();
+                    mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
                 }
 
+                final PointF vel = mTouchState.getVelocity();
                 final float velocity = PointF.length(vel.x, vel.y);
                 if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
                     mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds);
@@ -486,7 +553,7 @@
                 mMotionHelper.animateToClosestSnapTarget(mMovementBounds);
                 setMinimizedStateInternal(false);
             } else if (!mIsMenuVisible) {
-                mMenuController.showMenu();
+                mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
             } else {
                 mMotionHelper.expandPip();
             }
@@ -495,29 +562,39 @@
     };
 
     /**
-     * @return whether the gesture ending in the {@param vel} is fast enough to be a fling towards
-     *         the same edge the PIP is on. Used to identify a minimize gesture.
+     * @return whether the gesture ending in {@param vel} is fast enough to be a fling and towards
+     *         the provided {@param edge} where:
+     *
+     *         1 = top
+     *         2 = left
+     *         3 = right
+     *         4 = bottom
      */
-    private boolean isHorizontalFlingTowardsCurrentEdge(PointF vel) {
-        final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
-        final boolean isFling = PointF.length(vel.x, vel.y) > mFlingAnimationUtils
-                .getMinVelocityPxPerSecond();
-        final boolean towardsCurrentEdge = isOverEdge(true /* left */) && vel.x < 0
-                || isOverEdge(false /* right */) && vel.x > 0;
-        return towardsCurrentEdge && isHorizontal && isFling;
-    }
-
-    /**
-     * @return whether the given bounds are on the left or right edge (depending on
-     *         {@param checkLeft})
-     */
-    private boolean isOverEdge(boolean checkLeft) {
+    private boolean isFlingTowardsEdge(PipTouchState touchState, int edge) {
+        final PointF vel = touchState.getVelocity();
+        final PointF downPos = touchState.getDownTouchPosition();
         final Rect bounds = mMotionHelper.getBounds();
-        if (checkLeft) {
-            return bounds.left <= mMovementBounds.left;
-        } else {
-            return bounds.right >= mMovementBounds.right + bounds.width();
+        final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
+        final boolean isFling =
+                PointF.length(vel.x, vel.y) > mFlingAnimationUtils.getMinVelocityPxPerSecond();
+        if (!isFling) {
+            return false;
         }
+        switch (edge) {
+            case 1: // top
+                return !isHorizontal && vel.y < 0
+                        && downPos.y <= mMovementBounds.top + bounds.height();
+            case 2: // left
+                return isHorizontal && vel.x < 0
+                        && downPos.x <= mMovementBounds.left + bounds.width();
+            case 3: // right
+                return isHorizontal && vel.x > 0
+                        && downPos.x >= mMovementBounds.right;
+            case 4: // bottom
+                return !isHorizontal && vel.y > 0
+                        && downPos.y >= mMovementBounds.bottom;
+        }
+        return false;
     }
 
     /**
@@ -542,9 +619,149 @@
         pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
         pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
         pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
-        pw.println(innerPrefix + "mEnableDragToDismiss=" + ENABLE_DRAG_TO_DISMISS);
+        pw.println(innerPrefix + "mEnableDragToDismiss=" + ENABLE_DISMISS_DRAG_TO_TARGET);
         mSnapAlgorithm.dump(pw, innerPrefix);
         mTouchState.dump(pw, innerPrefix);
         mMotionHelper.dump(pw, innerPrefix);
     }
+
+    private static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo() {
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+        info.setImportantForAccessibility(true);
+        info.setClickable(true);
+        info.setVisibleToUser(true);
+        return info;
+    }
+
+    /**
+     * Expose the touch actions to accessibility as if this object were a window with a single view.
+     * That pseudo-view exposes all of the actions this object can perform.
+     */
+    class AccessibilityInteractionConnection extends IAccessibilityInteractionConnection.Stub {
+        static final long ACCESSIBILITY_NODE_ID = 1;
+        List<AccessibilityNodeInfo> mAccessibilityNodeInfoList;
+
+        @Override
+        public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
+                Region interactiveRegion, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec, Bundle args) {
+            try {
+                callback.setFindAccessibilityNodeInfosResult(
+                        (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID)
+                                ? getNodeList() : null, interactionId);
+            } catch (RemoteException re) {
+                    /* best effort - ignore */
+            }
+        }
+
+        @Override
+        public void performAccessibilityAction(long accessibilityNodeId, int action,
+                Bundle arguments, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid) {
+            // We only support one view. A request for anything else is invalid
+            boolean result = false;
+            if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) {
+                switch (action) {
+                    case AccessibilityNodeInfo.ACTION_CLICK:
+                        mHandler.post(mShowMenuRunnable);
+                        result = true;
+                        break;
+                    case AccessibilityNodeInfo.ACTION_DISMISS:
+                        mMotionHelper.dismissPip();
+                        result = true;
+                        break;
+                    case com.android.internal.R.id.accessibilityActionMoveWindow:
+                        int newX = arguments.getInt(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X);
+                        int newY = arguments.getInt(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y);
+                        Rect pipBounds = new Rect();
+                        pipBounds.set(mMotionHelper.getBounds());
+                        mTmpBounds.offsetTo(newX, newY);
+                        mMotionHelper.movePip(mTmpBounds);
+                        result = true;
+                        break;
+                    case AccessibilityNodeInfo.ACTION_EXPAND:
+                        mMotionHelper.expandPip();
+                        result = true;
+                        break;
+                    default:
+                        // Leave result as false
+                }
+            }
+            try {
+                callback.setPerformAccessibilityActionResult(result, interactionId);
+            } catch (RemoteException re) {
+                    /* best effort - ignore */
+            }
+        }
+
+        @Override
+        public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
+                String viewId, Region interactiveRegion, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            // We have no view with a proper ID
+            try {
+                callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+            } catch (RemoteException re) {
+                /* best effort - ignore */
+            }
+        }
+
+        @Override
+        public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
+                Region interactiveRegion, int interactionId,
+                IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            // We have no view with text
+            try {
+                callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+            } catch (RemoteException re) {
+                /* best effort - ignore */
+            }
+        }
+
+        @Override
+        public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            // We have no view that can take focus
+            try {
+                callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+            } catch (RemoteException re) {
+                /* best effort - ignore */
+            }
+        }
+
+        @Override
+        public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
+                int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+                int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+            // We have no view that can take focus
+            try {
+                callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+            } catch (RemoteException re) {
+                /* best effort - ignore */
+            }
+        }
+
+        private List<AccessibilityNodeInfo> getNodeList() {
+            if (mAccessibilityNodeInfoList == null) {
+                mAccessibilityNodeInfoList = new ArrayList<>(1);
+            }
+            AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo();
+            mAccessibilityNodeInfoList.clear();
+            mAccessibilityNodeInfoList.add(info);
+            return mAccessibilityNodeInfoList;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
index a317dc3..b34a07d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java
@@ -170,6 +170,13 @@
     }
 
     /**
+     * @return the down touch position.
+     */
+    public PointF getDownTouchPosition() {
+        return mDownTouch;
+    }
+
+    /**
      * @return the movement delta between the last handled touch event and the down touch
      *         position.
      */
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 12332fb..47468ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -22,6 +22,7 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 
 import android.annotation.NonNull;
@@ -1057,15 +1058,18 @@
     }
 
     /**
-     * Returns the window rect for the RecentsActivity, based on the dimensions of the home stack.
+     * Returns the window rect for the RecentsActivity, based on the dimensions of the recents stack
      */
     public Rect getWindowRect() {
         Rect windowRect = new Rect();
         if (mIam == null) return windowRect;
 
         try {
-            // Use the home stack bounds
-            ActivityManager.StackInfo stackInfo = mIam.getStackInfo(HOME_STACK_ID);
+            // Use the recents stack bounds, fallback to fullscreen stack if it is null
+            ActivityManager.StackInfo stackInfo = mIam.getStackInfo(RECENTS_STACK_ID);
+            if (stackInfo == null) {
+                stackInfo = mIam.getStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
+            }
             if (stackInfo != null) {
                 windowRect.set(stackInfo.bounds);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index db0c95e..2180ec8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -160,7 +160,10 @@
         EventBus.getDefault().send(new DragStartInitializeDropTargetsEvent(event.task,
                 event.taskView, this));
         if (mDeviceId != -1) {
-            InputDevice.getDevice(mDeviceId).setPointerType(PointerIcon.TYPE_GRABBING);
+            InputDevice device = InputDevice.getDevice(mDeviceId);
+            if (device != null) {
+                device.setPointerType(PointerIcon.TYPE_GRABBING);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 6f59fe2..97506e6 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -746,15 +746,18 @@
             if (mStableInsets.isEmpty()) {
                 SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
             }
+            mMinimizedSnapAlgorithm = null;
+            mDockedStackMinimized = minimized;
+            initializeSnapAlgorithm();
             if (!mIsInMinimizeInteraction && minimized) {
                 mIsInMinimizeInteraction = true;
                 mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
                         isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
                         mDividerSize);
+
+                int position = mMinimizedSnapAlgorithm.getMiddleTarget().position;
+                resizeStack(position, position, mMinimizedSnapAlgorithm.getMiddleTarget());
             }
-            mMinimizedSnapAlgorithm = null;
-            mDockedStackMinimized = minimized;
-            initializeSnapAlgorithm();
         }
     }
 
@@ -1140,7 +1143,7 @@
                         && dockSideBottomRight(mDockSide))) {
             return StackId.DOCKED_STACK_ID;
         } else {
-            return StackId.HOME_STACK_ID;
+            return StackId.RECENTS_STACK_ID;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index fb92a67..dceeb74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -29,6 +29,7 @@
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -39,6 +40,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -49,6 +51,8 @@
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.util.wakelock.SettableWakeLock;
+import com.android.systemui.util.wakelock.WakeLock;
 
 /**
  * Controls the indications and error messages shown on the Keyguard
@@ -68,6 +72,7 @@
     private final KeyguardIndicationTextView mDisclosure;
     private final UserManager mUserManager;
     private final IBatteryStats mBatteryInfo;
+    private final SettableWakeLock mWakeLock;
 
     private final int mSlowThreshold;
     private final int mFastThreshold;
@@ -92,6 +97,13 @@
 
     public KeyguardIndicationController(Context context, ViewGroup indicationArea,
             LockIcon lockIcon) {
+        this(context, indicationArea, lockIcon,
+                WakeLock.createPartial(context, "Doze:KeyguardIndication"));
+    }
+
+    @VisibleForTesting
+    KeyguardIndicationController(Context context, ViewGroup indicationArea, LockIcon lockIcon,
+                WakeLock wakeLock) {
         mContext = context;
         mIndicationArea = indicationArea;
         mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
@@ -99,6 +111,7 @@
         mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mLockIcon = lockIcon;
+        mWakeLock = new SettableWakeLock(wakeLock);
 
         Resources res = context.getResources();
         mSlowThreshold = res.getInteger(R.integer.config_chargingSlowlyThreshold);
@@ -208,6 +221,11 @@
         mTransientIndication = transientIndication;
         mTransientTextColor = textColor;
         mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+        if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
+            // Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
+            mWakeLock.setAcquired(true);
+            hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
+        }
         updateIndication();
     }
 
@@ -223,6 +241,10 @@
     }
 
     private void updateIndication() {
+        if (TextUtils.isEmpty(mTransientIndication)) {
+            mWakeLock.setAcquired(false);
+        }
+
         if (mVisible) {
             // Walk down a precedence-ordered list of what should indication
             // should be shown based on user or device state
@@ -323,9 +345,8 @@
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-            if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
-                mTransientIndication = null;
-                updateIndication();
+            if (msg.what == MSG_HIDE_TRANSIENT) {
+                hideTransientIndication();
             } else if (msg.what == MSG_CLEAR_FP_MSG) {
                 mLockIcon.setTransientFpError(false);
                 hideTransientIndication();
@@ -340,17 +361,27 @@
     }
 
     protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
+        public static final int HIDE_DELAY_MS = 5000;
         private int mLastSuccessiveErrorMessage = -1;
 
         @Override
         public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
             boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
+            boolean wasPluggedIn = mPowerPluggedIn;
             mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
             mPowerCharged = status.isCharged();
             mChargingWattage = status.maxChargingWattage;
             mChargingSpeed = status.getChargingSpeed(mSlowThreshold, mFastThreshold);
             updateIndication();
+            if (mDozing) {
+                if (!wasPluggedIn && mPowerPluggedIn) {
+                    showTransientIndication(computePowerIndication());
+                    hideTransientIndicationDelayed(HIDE_DELAY_MS);
+                } else if (wasPluggedIn && !mPowerPluggedIn) {
+                    hideTransientIndication();
+                }
+            }
         }
 
         @Override
@@ -401,8 +432,7 @@
             } else if (updateMonitor.isDeviceInteractive()) {
                 showTransientIndication(errString, errorColor);
                 // We want to keep this message around in case the screen was off
-                mHandler.removeMessages(MSG_HIDE_TRANSIENT);
-                hideTransientIndicationDelayed(5000);
+                hideTransientIndicationDelayed(HIDE_DELAY_MS);
             } else {
                 mMessageToShowOnScreenOn = errString;
             }
@@ -415,8 +445,7 @@
                 int errorColor = Utils.getColorError(mContext);
                 showTransientIndication(mMessageToShowOnScreenOn, errorColor);
                 // We want to keep this message around in case the screen was off
-                mHandler.removeMessages(MSG_HIDE_TRANSIENT);
-                hideTransientIndicationDelayed(5000);
+                hideTransientIndicationDelayed(HIDE_DELAY_MS);
                 mMessageToShowOnScreenOn = null;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 8f8d966..90e908b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,11 +16,15 @@
 
 package com.android.systemui.statusbar;
 
+import android.app.AppGlobals;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.content.Context;
 import android.graphics.drawable.Icon;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
@@ -31,7 +35,9 @@
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
+import android.Manifest;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.statusbar.notification.InflationException;
@@ -453,13 +459,30 @@
     }
 
     // Q: What kinds of notifications should show during setup?
-    // A: Almost none! Only things coming from the system (package is "android") that also
-    // have special "kind" tags marking them as relevant for setup (see below).
+    // A: Almost none! Only things coming from packages with permission
+    // android.permission.NOTIFICATION_DURING_SETUP that also have special "kind" tags marking them
+    // as relevant for setup (see below).
     public static boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
-        return "android".equals(sbn.getPackageName())
+        return showNotificationEvenIfUnprovisioned(AppGlobals.getPackageManager(), sbn);
+    }
+
+    @VisibleForTesting
+    static boolean showNotificationEvenIfUnprovisioned(IPackageManager packageManager,
+            StatusBarNotification sbn) {
+        return checkUidPermission(packageManager, Manifest.permission.NOTIFICATION_DURING_SETUP,
+                sbn.getUid()) == PackageManager.PERMISSION_GRANTED
                 && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
     }
 
+    private static int checkUidPermission(IPackageManager packageManager, String permission,
+            int uid) {
+        try {
+            return packageManager.checkUidPermission(permission, uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     public void dump(PrintWriter pw, String indent) {
         int N = mSortedAndFiltered.size();
         pw.print(indent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 66703ee..73eecbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -23,19 +23,19 @@
 import android.view.View;
 import android.widget.RemoteViews;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationContentView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.phone.StatusBar;
 
-import java.util.Objects;
-
 /**
  * A utility that inflates the right kind of contentView based on the state
  */
 public class NotificationInflater {
 
-    private static final int FLAG_REINFLATE_ALL = ~0;
+    @VisibleForTesting
+    static final int FLAG_REINFLATE_ALL = ~0;
     private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
     private static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
     private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
@@ -104,115 +104,12 @@
      */
     private void inflateNotificationViews(int reInflateFlags)
             throws InflationException {
-        NotificationData.Entry entry = mRow.getEntry();
-        StatusBarNotification sbn = entry.notification;
-        Context context = mRow.getContext();
-        NotificationContentView privateLayout = mRow.getPrivateLayout();
+        StatusBarNotification sbn = mRow.getEntry().notification;
         try {
             final Notification.Builder recoveredBuilder
-                    = Notification.Builder.recoverBuilder(context, sbn.getNotification());
-            boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
-            if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
-                final RemoteViews newContentView = createContentView(recoveredBuilder,
-                        isLowPriority, mUsesIncreasedHeadsUpHeight);
-                if (!compareRemoteViews(newContentView,
-                        entry.cachedContentView)) {
-                    View contentViewLocal = newContentView.apply(
-                            sbn.getPackageContext(context),
-                            privateLayout,
-                            mRemoteViewClickHandler);
-                    contentViewLocal.setIsRootNamespace(true);
-                    privateLayout.setContractedChild(contentViewLocal);
-                } else {
-                    newContentView.reapply(sbn.getPackageContext(context),
-                            privateLayout.getContractedChild(),
-                            mRemoteViewClickHandler);
-                }
-                entry.cachedContentView = newContentView;
-            }
-
-            if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
-                final RemoteViews newBigContentView = createBigContentView(
-                        recoveredBuilder, isLowPriority);
-                if (newBigContentView != null) {
-                    if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
-                        View bigContentViewLocal = newBigContentView.apply(
-                                sbn.getPackageContext(context),
-                                privateLayout,
-                                mRemoteViewClickHandler);
-                        bigContentViewLocal.setIsRootNamespace(true);
-                        privateLayout.setExpandedChild(bigContentViewLocal);
-                    } else {
-                        newBigContentView.reapply(sbn.getPackageContext(context),
-                                privateLayout.getExpandedChild(),
-                                mRemoteViewClickHandler);
-                    }
-                } else if (entry.cachedBigContentView != null) {
-                    privateLayout.setExpandedChild(null);
-                }
-                entry.cachedBigContentView = newBigContentView;
-                mRow.setExpandable(newBigContentView != null);
-            }
-
-            if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
-                final RemoteViews newHeadsUpContentView =
-                        recoveredBuilder.createHeadsUpContentView(mUsesIncreasedHeight);
-                if (newHeadsUpContentView != null) {
-                    if (!compareRemoteViews(newHeadsUpContentView,
-                            entry.cachedHeadsUpContentView)) {
-                        View headsUpContentViewLocal = newHeadsUpContentView.apply(
-                                sbn.getPackageContext(context),
-                                privateLayout,
-                                mRemoteViewClickHandler);
-                        headsUpContentViewLocal.setIsRootNamespace(true);
-                        privateLayout.setHeadsUpChild(headsUpContentViewLocal);
-                    } else {
-                        newHeadsUpContentView.reapply(sbn.getPackageContext(context),
-                                privateLayout.getHeadsUpChild(),
-                                mRemoteViewClickHandler);
-                    }
-                } else if (entry.cachedHeadsUpContentView != null) {
-                    privateLayout.setHeadsUpChild(null);
-                }
-                entry.cachedHeadsUpContentView = newHeadsUpContentView;
-            }
-
-            if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
-                NotificationContentView publicLayout = mRow.getPublicLayout();
-                final RemoteViews newPublicNotification
-                        = recoveredBuilder.makePublicContentView();
-                if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
-                    View publicContentView = newPublicNotification.apply(
-                            sbn.getPackageContext(context),
-                            publicLayout,
-                            mRemoteViewClickHandler);
-                    publicContentView.setIsRootNamespace(true);
-                    publicLayout.setContractedChild(publicContentView);
-                } else {
-                    newPublicNotification.reapply(sbn.getPackageContext(context),
-                            publicLayout.getContractedChild(),
-                            mRemoteViewClickHandler);
-                }
-                entry.cachedPublicContentView = newPublicNotification;
-            }
-
-            if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
-                final RemoteViews newAmbientNotification
-                        = recoveredBuilder.makeAmbientNotification();
-                if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
-                    View ambientContentView = newAmbientNotification.apply(
-                            sbn.getPackageContext(context),
-                            privateLayout,
-                            mRemoteViewClickHandler);
-                    ambientContentView.setIsRootNamespace(true);
-                    privateLayout.setAmbientChild(ambientContentView);
-                } else {
-                    newAmbientNotification.reapply(sbn.getPackageContext(context),
-                            privateLayout.getAmbientChild(),
-                            mRemoteViewClickHandler);
-                }
-                entry.cachedAmbientContentView = newAmbientNotification;
-            }
+                    = Notification.Builder.recoverBuilder(mRow.getContext(), sbn.getNotification());
+            Context packageContext = sbn.getPackageContext(mRow.getContext());
+            inflateNotificationViews(reInflateFlags, recoveredBuilder, packageContext);
 
         } catch (RuntimeException e) {
             final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
@@ -221,6 +118,115 @@
         }
     }
 
+    @VisibleForTesting
+    void inflateNotificationViews(int reInflateFlags,
+            Notification.Builder builder, Context packageContext) {
+        NotificationData.Entry entry = mRow.getEntry();
+        NotificationContentView privateLayout = mRow.getPrivateLayout();
+        boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
+        if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+            final RemoteViews newContentView = createContentView(builder,
+                    isLowPriority, mUsesIncreasedHeight);
+            if (!compareRemoteViews(newContentView,
+                    entry.cachedContentView)) {
+                View contentViewLocal = newContentView.apply(
+                        packageContext,
+                        privateLayout,
+                        mRemoteViewClickHandler);
+                contentViewLocal.setIsRootNamespace(true);
+                privateLayout.setContractedChild(contentViewLocal);
+            } else {
+                newContentView.reapply(packageContext,
+                        privateLayout.getContractedChild(),
+                        mRemoteViewClickHandler);
+            }
+            entry.cachedContentView = newContentView;
+        }
+
+        if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+            final RemoteViews newBigContentView = createBigContentView(
+                    builder, isLowPriority);
+            if (newBigContentView != null) {
+                if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
+                    View bigContentViewLocal = newBigContentView.apply(
+                            packageContext,
+                            privateLayout,
+                            mRemoteViewClickHandler);
+                    bigContentViewLocal.setIsRootNamespace(true);
+                    privateLayout.setExpandedChild(bigContentViewLocal);
+                } else {
+                    newBigContentView.reapply(packageContext,
+                            privateLayout.getExpandedChild(),
+                            mRemoteViewClickHandler);
+                }
+            } else if (entry.cachedBigContentView != null) {
+                privateLayout.setExpandedChild(null);
+            }
+            entry.cachedBigContentView = newBigContentView;
+            mRow.setExpandable(newBigContentView != null);
+        }
+
+        if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+            final RemoteViews newHeadsUpContentView =
+                    builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight);
+            if (newHeadsUpContentView != null) {
+                if (!compareRemoteViews(newHeadsUpContentView,
+                        entry.cachedHeadsUpContentView)) {
+                    View headsUpContentViewLocal = newHeadsUpContentView.apply(
+                            packageContext,
+                            privateLayout,
+                            mRemoteViewClickHandler);
+                    headsUpContentViewLocal.setIsRootNamespace(true);
+                    privateLayout.setHeadsUpChild(headsUpContentViewLocal);
+                } else {
+                    newHeadsUpContentView.reapply(packageContext,
+                            privateLayout.getHeadsUpChild(),
+                            mRemoteViewClickHandler);
+                }
+            } else if (entry.cachedHeadsUpContentView != null) {
+                privateLayout.setHeadsUpChild(null);
+            }
+            entry.cachedHeadsUpContentView = newHeadsUpContentView;
+        }
+
+        if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+            NotificationContentView publicLayout = mRow.getPublicLayout();
+            final RemoteViews newPublicNotification
+                    = builder.makePublicContentView();
+            if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
+                View publicContentView = newPublicNotification.apply(
+                        packageContext,
+                        publicLayout,
+                        mRemoteViewClickHandler);
+                publicContentView.setIsRootNamespace(true);
+                publicLayout.setContractedChild(publicContentView);
+            } else {
+                newPublicNotification.reapply(packageContext,
+                        publicLayout.getContractedChild(),
+                        mRemoteViewClickHandler);
+            }
+            entry.cachedPublicContentView = newPublicNotification;
+        }
+
+        if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+            final RemoteViews newAmbientNotification
+                    = builder.makeAmbientNotification();
+            if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
+                View ambientContentView = newAmbientNotification.apply(
+                        packageContext,
+                        privateLayout,
+                        mRemoteViewClickHandler);
+                ambientContentView.setIsRootNamespace(true);
+                privateLayout.setAmbientChild(ambientContentView);
+            } else {
+                newAmbientNotification.reapply(packageContext,
+                        privateLayout.getAmbientChild(),
+                        mRemoteViewClickHandler);
+            }
+            entry.cachedAmbientContentView = newAmbientNotification;
+        }
+    }
+
     private RemoteViews createBigContentView(Notification.Builder builder,
             boolean isLowPriority) {
         RemoteViews bigContentView = builder.createBigContentView();
@@ -260,6 +266,7 @@
     public interface InflationExceptionHandler {
         void handleInflationException(StatusBarNotification notification, InflationException e);
     }
+
     public void onDensityOrFontScaleChanged() {
         NotificationData.Entry entry = mRow.getEntry();
         entry.cachedAmbientContentView = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 4a2ec88..7b2e997 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -25,6 +24,7 @@
 import android.util.MathUtils;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.systemui.R;
 
 import java.io.PrintWriter;
@@ -32,14 +32,15 @@
 public class DozeParameters {
     private static final int MAX_DURATION = 60 * 1000;
     public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
-    public static final boolean ALWAYS_ON_AVAILABLE = Build.IS_DEBUGGABLE;
 
     private final Context mContext;
+    private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
 
     private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
 
     public DozeParameters(Context context) {
         mContext = context;
+        mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
     }
 
     public void dump(PrintWriter pw) {
@@ -58,8 +59,7 @@
         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
         pw.print("    getPickupSubtypePerformsProxCheck(): ");pw.println(
                 dumpPickupSubtypePerformsProxCheck());
-        if (ALWAYS_ON_AVAILABLE) {
-            pw.print("    getAlwaysOn(): "); pw.println(getAlwaysOn());
+        if (mAmbientDisplayConfiguration.alwaysOnAvailable()) {
             pw.print("    getSensorsWakeUpFully(): "); pw.println(getSensorsWakeUpFully());
         }
     }
@@ -119,13 +119,11 @@
     }
 
     public boolean getAlwaysOn() {
-        return ALWAYS_ON_AVAILABLE
-                && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT) != 0;
+        return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
     }
 
     public boolean getSensorsWakeUpFully() {
-        return ALWAYS_ON_AVAILABLE
+        return mAmbientDisplayConfiguration.alwaysOnAvailable()
                 && Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 DOZE_SENSORS_WAKE_UP_FULLY, 1, UserHandle.USER_CURRENT) != 0;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
index 83b96bf..b5f56c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -19,6 +19,7 @@
 import android.metrics.LogMaker;
 import android.util.ArrayMap;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.EventLogConstants;
@@ -32,6 +33,7 @@
     private ArrayMap<Integer, Integer> mLegacyMap;
     private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
             .setType(MetricsEvent.TYPE_ACTION);
+    private MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public LockscreenGestureLogger() {
         mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length);
@@ -41,7 +43,7 @@
     }
 
     public void write(int gesture, int length, int velocity) {
-        MetricsLogger.action(mLogMaker.setCategory(gesture)
+        mMetricsLogger.write(mLogMaker.setCategory(gesture)
                 .setType(MetricsEvent.TYPE_ACTION)
                 .addTaggedData(MetricsEvent.FIELD_GESTURE_LENGTH, length)
                 .addTaggedData(MetricsEvent.FIELD_GESTURE_VELOCITY, velocity));
@@ -56,4 +58,9 @@
         }
         return value;
     }
+
+    @VisibleForTesting
+    void setMetricsLogger(MetricsLogger metricsLogger) {
+        mMetricsLogger = metricsLogger;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 6c729dc..2c5bd3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -90,6 +90,7 @@
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
+import android.support.annotation.VisibleForTesting;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -751,6 +752,12 @@
     private NavigationBarFragment mNavigationBar;
     private View mNavigationBarView;
 
+    @VisibleForTesting
+    void setMetricsLogger(MetricsLogger metricsLogger) {
+        mMetricsLogger = metricsLogger;
+        mLockscreenGestureLogger.setMetricsLogger(metricsLogger);
+    }
+
     @Override
     public void start() {
         mNetworkController = Dependency.get(NetworkController.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 48ff1c1..641fe69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -45,7 +45,7 @@
      * has occurred.
      */
     interface BatteryStateChangeCallback {
-        void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
-        void onPowerSaveChanged(boolean isPowerSave);
+        default void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {}
+        default void onPowerSaveChanged(boolean isPowerSave) {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 209b439..e7bce708 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -26,11 +26,11 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginPrefs;
-import com.android.systemui.statusbar.phone.DozeParameters;
 
 public class TunerFragment extends PreferenceFragment {
 
@@ -65,7 +65,7 @@
         if (!PluginPrefs.hasPlugins(getContext())) {
             getPreferenceScreen().removePreference(findPreference(KEY_PLUGINS));
         }
-        if (!DozeParameters.ALWAYS_ON_AVAILABLE) {
+        if (!alwaysOnAvailable()) {
             getPreferenceScreen().removePreference(findPreference(KEY_DOZE));
         }
 
@@ -77,6 +77,10 @@
         }
     }
 
+    private boolean alwaysOnAvailable() {
+        return new AmbientDisplayConfiguration(getContext()).alwaysOnAvailable();
+    }
+
     @Override
     public void onResume() {
         super.onResume();
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 43727e0..cfe16dd 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.Notification.Action;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -35,6 +36,7 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -181,6 +183,11 @@
     }
 
     private void updateMissingPrivateVolumes() {
+        if (isTv()) {
+            // On TV, TvSettings displays a modal full-screen activity in this case.
+            return;
+        }
+
         final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
         for (VolumeRecord rec : recs) {
             if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue;
@@ -210,7 +217,8 @@
                                 .setVisibility(Notification.VISIBILITY_PUBLIC)
                                 .setLocalOnly(true)
                                 .setCategory(Notification.CATEGORY_SYSTEM)
-                                .setDeleteIntent(buildSnoozeIntent(fsUuid));
+                                .setDeleteIntent(buildSnoozeIntent(fsUuid))
+                                .extend(new Notification.TvExtender());
                 SystemUI.overrideNotificationAppName(mContext, builder);
 
                 mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
@@ -237,7 +245,8 @@
                             .setStyle(new Notification.BigTextStyle().bigText(text))
                             .setVisibility(Notification.VISIBILITY_PUBLIC)
                             .setLocalOnly(true)
-                            .setCategory(Notification.CATEGORY_ERROR);
+                            .setCategory(Notification.CATEGORY_ERROR)
+                            .extend(new Notification.TvExtender());
             SystemUI.overrideNotificationAppName(mContext, builder);
 
             mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
@@ -378,7 +387,7 @@
                     .addAction(new Action(R.drawable.ic_eject_24dp,
                             mContext.getString(R.string.ext_media_unmount_action),
                             buildUnmountPendingIntent(vol)))
-                    .setContentIntent(browseIntent)
+                    .setContentIntent(buildUnmountPendingIntent(vol))
                     .setCategory(Notification.CATEGORY_SYSTEM);
             // Non-adoptable disks can't be snoozed.
             if (disk.isAdoptable()) {
@@ -571,15 +580,21 @@
                         .setContentText(text)
                         .setStyle(new Notification.BigTextStyle().bigText(text))
                         .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setLocalOnly(true);
+                        .setLocalOnly(true)
+                        .extend(new Notification.TvExtender());
         overrideNotificationAppName(mContext, builder);
         return builder;
     }
 
     private PendingIntent buildInitPendingIntent(DiskInfo disk) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageWizardInit");
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageWizardInit");
+        }
         intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
 
         final int requestKey = disk.getId().hashCode();
@@ -589,8 +604,13 @@
 
     private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageWizardInit");
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageWizardInit");
+        }
         intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
 
         final int requestKey = vol.getId().hashCode();
@@ -600,13 +620,23 @@
 
     private PendingIntent buildUnmountPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageUnmountReceiver");
-        intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction("com.android.tv.settings.action.UNMOUNT_STORAGE");
+            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
 
-        final int requestKey = vol.getId().hashCode();
-        return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
-                PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
+            final int requestKey = vol.getId().hashCode();
+            return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
+                    PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageUnmountReceiver");
+            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+
+            final int requestKey = vol.getId().hashCode();
+            return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
+                    PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
+        }
     }
 
     private PendingIntent buildBrowsePendingIntent(VolumeInfo vol) {
@@ -619,17 +649,22 @@
 
     private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
         final Intent intent = new Intent();
-        switch (vol.getType()) {
-            case VolumeInfo.TYPE_PRIVATE:
-                intent.setClassName("com.android.settings",
-                        "com.android.settings.Settings$PrivateVolumeSettingsActivity");
-                break;
-            case VolumeInfo.TYPE_PUBLIC:
-                intent.setClassName("com.android.settings",
-                        "com.android.settings.Settings$PublicVolumeSettingsActivity");
-                break;
-            default:
-                return null;
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
+        } else {
+            switch (vol.getType()) {
+                case VolumeInfo.TYPE_PRIVATE:
+                    intent.setClassName("com.android.settings",
+                            "com.android.settings.Settings$PrivateVolumeSettingsActivity");
+                    break;
+                case VolumeInfo.TYPE_PUBLIC:
+                    intent.setClassName("com.android.settings",
+                            "com.android.settings.Settings$PublicVolumeSettingsActivity");
+                    break;
+                default:
+                    return null;
+            }
         }
         intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
 
@@ -648,6 +683,7 @@
     }
 
     private PendingIntent buildForgetPendingIntent(VolumeRecord rec) {
+        // Not used on TV
         final Intent intent = new Intent();
         intent.setClassName("com.android.settings",
                 "com.android.settings.Settings$PrivateVolumeForgetActivity");
@@ -660,8 +696,13 @@
 
     private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction("com.android.tv.settings.action.MIGRATE_STORAGE");
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
+        }
         intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
 
         final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
@@ -674,8 +715,13 @@
 
     private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageWizardMoveProgress");
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction("com.android.tv.settings.action.MOVE_APP");
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageWizardMoveProgress");
+        }
         intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
 
         return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
@@ -684,12 +730,22 @@
 
     private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
         final Intent intent = new Intent();
-        intent.setClassName("com.android.settings",
-                "com.android.settings.deviceinfo.StorageWizardReady");
+        if (isTv()) {
+            intent.setPackage("com.android.tv.settings");
+            intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
+        } else {
+            intent.setClassName("com.android.settings",
+                    "com.android.settings.deviceinfo.StorageWizardReady");
+        }
         intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
 
         final int requestKey = disk.getId().hashCode();
         return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
                 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
     }
+
+    private boolean isTv() {
+        PackageManager packageManager = mContext.getPackageManager();
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 5911766..5df3beb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -18,6 +18,7 @@
 import android.app.NotificationManager;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
@@ -32,6 +33,7 @@
 
     @VisibleForTesting
     static void createAll(Context context) {
+
         final NotificationManager nm = context.getSystemService(NotificationManager.class);
         nm.createNotificationChannels(Arrays.asList(
                 new NotificationChannel(
@@ -49,7 +51,9 @@
                 new NotificationChannel(
                         STORAGE,
                         R.string.notification_channel_storage,
-                        NotificationManager.IMPORTANCE_LOW)
+                        isTv(context)
+                                ? NotificationManager.IMPORTANCE_DEFAULT
+                                : NotificationManager.IMPORTANCE_LOW)
                 ));
     }
 
@@ -57,4 +61,9 @@
     public void start() {
         createAll(mContext);
     }
+
+    private static boolean isTv(Context context) {
+        PackageManager packageManager = context.getPackageManager();
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java
new file mode 100644
index 0000000..f2ed55f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/SettableWakeLock.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util.wakelock;
+
+import android.os.Handler;
+import android.os.PowerManager;
+
+import com.android.internal.util.Preconditions;
+
+public class SettableWakeLock {
+
+    private final WakeLock mInner;
+
+    private boolean mAcquired;
+
+    public SettableWakeLock(WakeLock inner) {
+        Preconditions.checkNotNull(inner, "inner wakelock required");
+
+        mInner = inner;
+    }
+
+    public synchronized boolean isAcquired() {
+        return mAcquired;
+    }
+
+    public synchronized void setAcquired(boolean acquired) {
+        if (mAcquired != acquired) {
+            if (acquired) {
+                mInner.acquire();
+            } else {
+                mInner.release();
+            }
+            mAcquired = acquired;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
new file mode 100644
index 0000000..eea3de3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util.wakelock;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.systemui.plugins.doze.DozeProvider;
+
+/** WakeLock wrapper for testability */
+public interface WakeLock extends DozeProvider.WakeLock {
+
+    static WakeLock createPartial(Context context, String tag) {
+        return wrap(createPartialInner(context, tag));
+    }
+
+    @VisibleForTesting
+    static PowerManager.WakeLock createPartialInner(Context context, String tag) {
+        return context.getSystemService(PowerManager.class)
+                    .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag);
+    }
+
+    static WakeLock wrap(final PowerManager.WakeLock inner) {
+        return new WakeLock() {
+            /** @see PowerManager.WakeLock#acquire() */
+            public void acquire() {
+                inner.acquire();
+            }
+
+            /** @see PowerManager.WakeLock#release() */
+            public void release() {
+                inner.release();
+            }
+
+            /** @see PowerManager.WakeLock#wrap(Runnable) */
+            public Runnable wrap(Runnable runnable) {
+                return inner.wrap(runnable);
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 41b75ff..612a54a 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -36,6 +36,7 @@
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
     <uses-permission android:name="android.permission.CONTROL_VPN" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
new file mode 100644
index 0000000..5477afa8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze;
+
+import static org.junit.Assert.assertFalse;
+
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DozeConfigurationTest extends SysuiTestCase {
+
+    private AmbientDisplayConfiguration mDozeConfig;
+
+    @Before
+    public void setup() {
+        mDozeConfig = new AmbientDisplayConfiguration(mContext);
+    }
+
+    @Test
+    public void alwaysOn_offByDefault() throws Exception {
+        if (!mDozeConfig.alwaysOnAvailable()) {
+            return;
+        }
+
+        mContext.getSettingsProvider().acquireOverridesBuilder(this)
+                .addSetting("secure", Settings.Secure.DOZE_ALWAYS_ON, null)
+                .build();
+
+        assertFalse(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 0cccbe1..ba39671 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -28,8 +28,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -38,12 +39,12 @@
 import static org.mockito.Mockito.when;
 
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.view.Display;
 
 import com.android.systemui.SysUIRunner;
 import com.android.systemui.UiThreadTest;
-import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,17 +59,17 @@
 
     private DozeServiceFake mServiceFake;
     private WakeLockFake mWakeLockFake;
-    private DozeParameters mParamsMock;
+    private AmbientDisplayConfiguration mConfigMock;
     private DozeMachine.Part mPartMock;
 
     @Before
     public void setUp() {
         mServiceFake = new DozeServiceFake();
         mWakeLockFake = new WakeLockFake();
-        mParamsMock = mock(DozeParameters.class);
+        mConfigMock = mock(AmbientDisplayConfiguration.class);
         mPartMock = mock(DozeMachine.Part.class);
 
-        mMachine = new DozeMachine(mServiceFake, mParamsMock, mWakeLockFake);
+        mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake);
 
         mMachine.setParts(new DozeMachine.Part[]{mPartMock});
     }
@@ -82,7 +83,7 @@
 
     @Test
     public void testInitialize_goesToDoze() {
-        when(mParamsMock.getAlwaysOn()).thenReturn(false);
+        when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
 
         mMachine.requestState(INITIALIZED);
 
@@ -92,7 +93,7 @@
 
     @Test
     public void testInitialize_goesToAod() {
-        when(mParamsMock.getAlwaysOn()).thenReturn(true);
+        when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
 
         mMachine.requestState(INITIALIZED);
 
@@ -102,7 +103,7 @@
 
     @Test
     public void testPulseDone_goesToDoze() {
-        when(mParamsMock.getAlwaysOn()).thenReturn(false);
+        when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
         mMachine.requestState(INITIALIZED);
         mMachine.requestState(DOZE_REQUEST_PULSE);
         mMachine.requestState(DOZE_PULSING);
@@ -115,7 +116,7 @@
 
     @Test
     public void testPulseDone_goesToAoD() {
-        when(mParamsMock.getAlwaysOn()).thenReturn(true);
+        when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
         mMachine.requestState(INITIALIZED);
         mMachine.requestState(DOZE_REQUEST_PULSE);
         mMachine.requestState(DOZE_PULSING);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 7335af3..6424a0a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -16,19 +16,26 @@
 
 package com.android.systemui.statusbar;
 
+import static android.support.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.Instrumentation;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
 import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.internal.runner.junit4.statement.UiThreadStatement;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -36,6 +43,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -54,9 +62,13 @@
     private KeyguardIndicationTextView mDisclosure = mock(KeyguardIndicationTextView.class);
 
     private KeyguardIndicationController mController;
+    private WakeLockFake mWakeLock;
+    private Instrumentation mInstrumentation;
 
     @Before
     public void setUp() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
         mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
@@ -65,13 +77,15 @@
 
         when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
                 .thenReturn(mDisclosure);
+
+        mWakeLock = new WakeLockFake();
     }
 
     private void createController() {
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
-        mController = new KeyguardIndicationController(mContext, mIndicationArea, null);
+        mController = new KeyguardIndicationController(mContext, mIndicationArea, null, mWakeLock);
     }
 
     @Test
@@ -139,4 +153,45 @@
         verify(mDisclosure).setVisibility(View.GONE);
         verifyNoMoreInteractions(mDisclosure);
     }
+
+    @Test
+    public void transientIndication_holdsWakeLock_whenDozing() {
+        createController();
+
+        mController.setDozing(true);
+        mController.showTransientIndication("Test");
+
+        assertTrue(mWakeLock.isHeld());
+    }
+
+    @Test
+    public void transientIndication_releasesWakeLock_afterHiding() {
+        createController();
+
+        mController.setDozing(true);
+        mController.showTransientIndication("Test");
+        mController.hideTransientIndication();
+
+        assertFalse(mWakeLock.isHeld());
+    }
+
+    @Test
+    public void transientIndication_releasesWakeLock_afterHidingDelayed() throws Throwable {
+        mInstrumentation.runOnMainSync(() -> {
+            createController();
+
+            mController.setDozing(true);
+            mController.showTransientIndication("Test");
+            mController.hideTransientIndicationDelayed(0);
+        });
+        mInstrumentation.waitForIdleSync();
+
+        boolean[] held = new boolean[2];
+        mInstrumentation.runOnMainSync(() -> {
+            held[0] = mWakeLock.isHeld();
+            held[1] = true;
+        });
+        assertFalse("wake lock still held", held[0]);
+        assertTrue("held was not written yet", held[1]);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
new file mode 100644
index 0000000..08ac9a9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.app.Notification;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.service.notification.StatusBarNotification;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationDataTest extends SysuiTestCase {
+
+    private static final int UID_NORMAL = 123;
+    private static final int UID_ALLOW_DURING_SETUP = 456;
+
+    private final StatusBarNotification mMockStatusBarNotification =
+            mock(StatusBarNotification.class);
+
+    private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
+
+    @Before
+    public void setUp() throws Exception {
+        when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);
+
+        when(mMockPackageManager.checkUidPermission(
+                eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
+                eq(UID_NORMAL)))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        when(mMockPackageManager.checkUidPermission(
+                eq(Manifest.permission.NOTIFICATION_DURING_SETUP),
+                eq(UID_ALLOW_DURING_SETUP)))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+    }
+
+    @Test
+    @UiThreadTest
+    public void testShowNotificationEvenIfUnprovisioned_FalseIfNoExtra() {
+        initStatusBarNotification(false);
+        when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);
+
+        assertFalse(
+                NotificationData.showNotificationEvenIfUnprovisioned(
+                        mMockPackageManager,
+                        mMockStatusBarNotification));
+    }
+
+    @Test
+    @UiThreadTest
+    public void testShowNotificationEvenIfUnprovisioned_FalseIfNoPermission() {
+        initStatusBarNotification(true);
+
+        assertFalse(
+                NotificationData.showNotificationEvenIfUnprovisioned(
+                        mMockPackageManager,
+                        mMockStatusBarNotification));
+    }
+
+    @Test
+    @UiThreadTest
+    public void testShowNotificationEvenIfUnprovisioned_TrueIfHasPermissionAndExtra() {
+        initStatusBarNotification(true);
+        when(mMockStatusBarNotification.getUid()).thenReturn(UID_ALLOW_DURING_SETUP);
+
+        assertTrue(
+                NotificationData.showNotificationEvenIfUnprovisioned(
+                        mMockPackageManager,
+                        mMockStatusBarNotification));
+    }
+
+    private void initStatusBarNotification(boolean allowDuringSetup) {
+        Bundle bundle = new Bundle();
+        bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
+        Notification notification = new Notification.Builder(mContext, "test")
+                .addExtras(bundle)
+                .build();
+        when(mMockStatusBarNotification.getNotification()).thenReturn(notification);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 96dbdb3..c91b269 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -42,12 +42,6 @@
     }
 
     public ExpandableNotificationRow createRow() {
-        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                mContext.LAYOUT_INFLATER_SERVICE);
-        ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate(
-                R.layout.status_bar_notification_row,
-                null, false);
-        row.setGroupManager(mGroupManager);
         Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                 R.drawable.ic_person)
                 .setCustomContentView(new RemoteViews(mContext.getPackageName(),
@@ -59,6 +53,16 @@
                 .setContentText("Text")
                 .setPublicVersion(publicVersion)
                 .build();
+        return createRow(notification);
+    }
+
+    public ExpandableNotificationRow createRow(Notification notification) {
+        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                mContext.LAYOUT_INFLATER_SERVICE);
+        ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate(
+                R.layout.status_bar_notification_row,
+                null, false);
+        row.setGroupManager(mGroupManager);
         UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
         StatusBarNotification sbn = new StatusBarNotification("com.android.systemui",
                 "com.android.systemui", mId++, null, 1000,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java
new file mode 100644
index 0000000..0ec9c10
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification;
+
+import static com.android.systemui.statusbar.notification.NotificationInflater.FLAG_REINFLATE_ALL;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.Notification;
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationinflaterTest {
+
+    private Context mContext;
+    private NotificationInflater mNotificationInflater;
+    private Notification.Builder mBuilder;
+
+    @Before
+    @UiThreadTest
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mBuilder = new Notification.Builder(mContext).setSmallIcon(
+                R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text");
+        ExpandableNotificationRow row = new NotificationTestHelper(mContext).createRow(
+                mBuilder.build());
+        mNotificationInflater = new NotificationInflater(row);
+    }
+
+    @Test
+    public void testIncreasedHeadsUpBeingUsed() {
+        mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
+        Notification.Builder builder = spy(mBuilder);
+        mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+        verify(builder).createHeadsUpContentView(true);
+    }
+
+    @Test
+    public void testIncreasedHeightBeingUsed() {
+        mNotificationInflater.setUsesIncreasedHeight(true);
+        Notification.Builder builder = spy(mBuilder);
+        mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+        verify(builder).createContentView(true);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 09f6b55..f48af75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -23,7 +23,6 @@
 import static org.mockito.Mockito.when;
 
 import android.metrics.LogMaker;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.metricshelper.MetricsAsserts;
 import android.support.test.runner.AndroidJUnit4;
@@ -40,7 +39,6 @@
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -65,7 +63,8 @@
         mStackScroller = mock(NotificationStackScrollLayout.class);
         mMetricsLogger = new FakeMetricsLogger();
         mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
-                mKeyguardIndicationController, mStackScroller, mMetricsLogger);
+                mKeyguardIndicationController, mStackScroller);
+        mStatusBar.setMetricsLogger(mMetricsLogger);
 
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -106,8 +105,6 @@
         mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void lockscreenStateMetrics_notShowing() {
         // uninteresting state, except that fingerprint must be non-zero
@@ -126,8 +123,6 @@
                         .setSubtype(0));
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void lockscreenStateMetrics_notShowing_secure() {
         // uninteresting state, except that fingerprint must be non-zero
@@ -147,8 +142,6 @@
                         .setSubtype(1));
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void lockscreenStateMetrics_isShowing() {
         // uninteresting state, except that fingerprint must be non-zero
@@ -168,8 +161,6 @@
                         .setSubtype(0));
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void lockscreenStateMetrics_isShowing_secure() {
         // uninteresting state, except that fingerprint must be non-zero
@@ -189,8 +180,6 @@
                         .setSubtype(1));
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void lockscreenStateMetrics_isShowingBouncer() {
         // uninteresting state, except that fingerprint must be non-zero
@@ -210,8 +199,6 @@
                         .setSubtype(1));
     }
 
-    @Ignore("flaky test")
-    @FlakyTest
     @Test
     public void onActivatedMetrics() {
         ActivatableNotificationView view =  mock(ActivatableNotificationView.class);
@@ -226,12 +213,11 @@
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
-                NotificationStackScrollLayout stack, MetricsLogger logger) {
+                NotificationStackScrollLayout stack) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
             mKeyguardIndicationController = key;
             mStackScroller = stack;
-            mMetricsLogger = logger;
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/SettableWakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/SettableWakeLockTest.java
new file mode 100644
index 0000000..f6692eb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/SettableWakeLockTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util.wakelock;
+
+import static junit.framework.TestCase.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SettableWakeLockTest {
+
+    private WakeLockFake mFake;
+    private SettableWakeLock mSettable;
+
+    @Before
+    public void setup() {
+        mFake = new WakeLockFake();
+        mSettable = new SettableWakeLock(mFake);
+    }
+
+    @Test
+    public void setAcquire_true_acquires() throws Exception {
+        mSettable.setAcquired(true);
+        assertTrue(mFake.isHeld());
+        assertEquals(mFake.isHeld(), mSettable.isAcquired());
+    }
+
+    @Test
+    public void setAcquire_false_releases() throws Exception {
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(false);
+        assertFalse(mFake.isHeld());
+        assertEquals(mFake.isHeld(), mSettable.isAcquired());
+    }
+
+    @Test
+    public void setAcquire_true_multipleTimes_isIdempotent() throws Exception {
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(false);
+        assertFalse(mFake.isHeld());
+        assertEquals(mFake.isHeld(), mSettable.isAcquired());
+    }
+
+    @Test
+    public void setAcquire_false_multipleTimes_idempotent() throws Exception {
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(false);
+        mSettable.setAcquired(false);
+        assertFalse(mFake.isHeld());
+        assertEquals(mFake.isHeld(), mSettable.isAcquired());
+    }
+
+    @Test
+    public void setAcquire_false_multipleTimes_idempotent_again() throws Exception {
+        mSettable.setAcquired(true);
+        mSettable.setAcquired(false);
+        mSettable.setAcquired(false);
+        mSettable.setAcquired(true);
+        assertTrue(mFake.isHeld());
+        assertEquals(mFake.isHeld(), mSettable.isAcquired());
+    }
+
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/WakeLockFake.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java
similarity index 82%
rename from packages/SystemUI/tests/src/com/android/systemui/doze/WakeLockFake.java
rename to packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java
index 7c04fe2..4cefb99 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/WakeLockFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockFake.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -11,21 +11,17 @@
  * 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.
+ * limitations under the License
  */
 
-package com.android.systemui.doze;
+package com.android.systemui.util.wakelock;
 
 import com.android.internal.util.Preconditions;
 
-public class WakeLockFake extends DozeFactory.WakeLock {
+public class WakeLockFake implements WakeLock {
 
     private int mAcquired = 0;
 
-    public WakeLockFake() {
-        super(null);
-    }
-
     @Override
     public void acquire() {
         mAcquired++;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
new file mode 100644
index 0000000..5394499
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util.wakelock;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WakeLockTest {
+
+    WakeLock mWakeLock;
+    PowerManager.WakeLock mInner;
+
+    @Before
+    public void setUp() {
+        Context context = InstrumentationRegistry.getContext();
+
+        mInner = WakeLock.createPartialInner(context, WakeLockTest.class.getName());
+        mWakeLock = WakeLock.wrap(mInner);
+    }
+
+    @After
+    public void tearDown() {
+        mInner.setReferenceCounted(false);
+        mInner.release();
+    }
+
+    @Test
+    public void createPartialInner_notHeldYet() {
+        assertFalse(mInner.isHeld());
+    }
+
+    @Test
+    public void wakeLock_acquire() {
+        mWakeLock.acquire();
+        assertTrue(mInner.isHeld());
+    }
+
+    @Test
+    public void wakeLock_release() {
+        mWakeLock.acquire();
+        mWakeLock.release();
+        assertFalse(mInner.isHeld());
+    }
+
+    @Test
+    public void wakeLock_refCounted() {
+        mWakeLock.acquire();
+        mWakeLock.acquire();
+        mWakeLock.release();
+        assertTrue(mInner.isHeld());
+    }
+
+    @Test
+    public void wakeLock_wrap() {
+        boolean[] ran = new boolean[1];
+
+        Runnable wrapped = mWakeLock.wrap(() -> {
+            ran[0] = true;
+        });
+
+        assertTrue(mInner.isHeld());
+        assertFalse(ran[0]);
+
+        wrapped.run();
+
+        assertTrue(ran[0]);
+        assertFalse(mInner.isHeld());
+    }
+}
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index c45de0d..42446d1 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3175,7 +3175,7 @@
     DIALOG_SUPPORT_SYSTEM_INFORMATION = 756;
 
     // These values should never appear in log outputs - they are reserved for
-    // internal Tron use.
+    // internal platform metrics use.
     RESERVED_FOR_LOGBUILDER_CATEGORY = 757;
     RESERVED_FOR_LOGBUILDER_TYPE = 758;
     RESERVED_FOR_LOGBUILDER_SUBTYPE = 759;
@@ -3282,7 +3282,7 @@
     DEFAULT_AUTOFILL_PICKER = 792;
 
     // These values should never appear in log outputs - they are reserved for
-    // internal Tron use.
+    // internal platform metrics use.
     NOTIFICATION_SINCE_CREATE_MILLIS = 793;
     NOTIFICATION_SINCE_VISIBLE_MILLIS = 794;
     NOTIFICATION_SINCE_UPDATE_MILLIS = 795;
@@ -3297,7 +3297,7 @@
     QS_NFC = 800;
 
     // These values should never appear in log outputs - they are reserved for
-    // internal Tron use.
+    // internal platform metrics use.
     RESERVED_FOR_LOGBUILDER_BUCKET = 801;
     RESERVED_FOR_LOGBUILDER_VALUE = 802;
     RESERVED_FOR_LOGBUILDER_COUNTER = 803;
@@ -3540,6 +3540,10 @@
     // OS: N
     ACTION_GET_CONTACT = 864;
 
+    // This values should never appear in log outputs - it is reserved for
+    // internal platform metrics use.
+    RESERVED_FOR_LOGBUILDER_PID = 865;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index 447a47d..4040db3 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -5,6 +5,7 @@
     android_renderscript_RenderScript.cpp
 
 LOCAL_SHARED_LIBRARIES := \
+    libandroid \
     libandroid_runtime \
     libandroidfw \
     libnativehelper \
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 2300da3..b4630ef 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -34,6 +34,8 @@
 #include "android_runtime/android_view_Surface.h"
 #include "android_runtime/android_util_AssetManager.h"
 #include "android/graphics/GraphicsJNI.h"
+#include "android/native_window.h"
+#include "android/native_window_jni.h"
 
 #include <rsEnv.h>
 #include <rsApiStubs.h>
@@ -1264,10 +1266,10 @@
         ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
     }
 
-    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con,
-                                                                                 (RsAllocation)a);
-    sp<IGraphicBufferProducer> bp = v;
-    v->decStrong(nullptr);
+    ANativeWindow *anw = (ANativeWindow *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
+
+    sp<Surface> surface(static_cast<Surface*>(anw));
+    sp<IGraphicBufferProducer> bp = surface->getIGraphicBufferProducer();
 
     jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
     return o;
@@ -1281,13 +1283,12 @@
               (RsAllocation)alloc, (Surface *)sur);
     }
 
-    sp<Surface> s;
+    ANativeWindow *anw = nullptr;
     if (sur != 0) {
-        s = android_view_Surface_getSurface(_env, sur);
+        anw = ANativeWindow_fromSurface(_env, sur);
     }
 
-    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc,
-                           static_cast<ANativeWindow *>(s.get()));
+    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, anw);
 }
 
 static void
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 44afe1d..e0d7806 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -82,6 +82,7 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
+import android.view.View;
 import android.view.WindowInfo;
 import android.view.WindowManager;
 import android.view.WindowManagerInternal;
@@ -97,6 +98,7 @@
 import android.view.accessibility.IAccessibilityManagerClient;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.server.LocalServices;
@@ -149,6 +151,9 @@
 
     private static final String GET_WINDOW_TOKEN = "getWindowToken";
 
+    private static final String SET_PIP_ACTION_REPLACEMENT =
+            "setPictureInPictureActionReplacingConnection";
+
     private static final ComponentName sFakeAccessibilityServiceComponentName =
             new ComponentName("foo.bar", "FakeService");
 
@@ -158,8 +163,6 @@
 
     private static final int OWN_PROCESS_ID = android.os.Process.myPid();
 
-    private static final int WINDOW_ID_UNKNOWN = -1;
-
     // Each service has an ID. Also provide one for magnification gesture handling
     public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0;
 
@@ -220,6 +223,8 @@
     private final SparseArray<AccessibilityConnectionWrapper> mGlobalInteractionConnections =
             new SparseArray<>();
 
+    private AccessibilityConnectionWrapper mPictureInPictureActionReplacingConnection;
+
     private final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<>();
 
     private final SparseArray<UserState> mUserStates = new SparseArray<>();
@@ -465,6 +470,25 @@
         boolean dispatchEvent = false;
 
         synchronized (mLock) {
+            if (event.getWindowId() ==
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID) {
+                // The replacer window isn't shown to services. Move its events into the pip.
+                AccessibilityWindowInfo pip = mSecurityPolicy.getPictureInPictureWindow();
+                if (pip != null) {
+                    int pipId = pip.getId();
+                    event.setWindowId(pipId);
+                    event.setSealed(true);
+                    AccessibilityNodeInfo info = event.getSource();
+                    info.setSealed(false);
+                    event.setSealed(false);
+                    if (info != null) {
+                        info.setSourceNodeId(info.getSourceNodeId(), pipId);
+                        event.setSource(info);
+                        info.recycle();
+                    }
+                }
+            }
+
             // We treat calls from a profile as if made by its parent as profiles
             // share the accessibility state of the parent. The call below
             // performs the current profile parent resolution..
@@ -694,6 +718,27 @@
     }
 
     @Override
+    public void setPictureInPictureActionReplacingConnection(
+            IAccessibilityInteractionConnection connection) throws RemoteException {
+        mSecurityPolicy.enforceCallingPermission(Manifest.permission.MODIFY_ACCESSIBILITY_DATA,
+                SET_PIP_ACTION_REPLACEMENT);
+        synchronized (mLock) {
+            if (mPictureInPictureActionReplacingConnection != null) {
+                mPictureInPictureActionReplacingConnection.unlinkToDeath();
+                mPictureInPictureActionReplacingConnection = null;
+            }
+            if (connection != null) {
+                AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
+                        AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID,
+                        connection, UserHandle.USER_ALL);
+                mPictureInPictureActionReplacingConnection = wrapper;
+                wrapper.linkToDeath();
+            }
+            mSecurityPolicy.notifyWindowsChanged();
+        }
+    }
+
+    @Override
     public void registerUiTestAutomationService(IBinder owner,
             IAccessibilityServiceClient serviceClient,
             AccessibilityServiceInfo accessibilityServiceInfo,
@@ -1293,9 +1338,10 @@
             return false;
         }
 
-        if (event.getWindowId() != WINDOW_ID_UNKNOWN && !event.isImportantForAccessibility()
-                && (service.mFetchFlags
-                        & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) == 0) {
+        if ((event.getWindowId() != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
+                && !event.isImportantForAccessibility()
+                && (service.mFetchFlags & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS)
+                        == 0) {
             return false;
         }
 
@@ -2035,6 +2081,7 @@
         }
     }
 
+    @GuardedBy("mLock")
     private MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId) {
         IBinder windowToken = mGlobalWindowTokens.get(windowId);
         if (windowToken == null) {
@@ -2846,6 +2893,7 @@
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
             Region partialInteractiveRegion = Region.obtain();
+            MagnificationSpec spec;
             synchronized (mLock) {
                 mUsesAccessibilityCache = true;
                 if (!isCalledForCurrentUserLocked()) {
@@ -2867,10 +2915,12 @@
                     partialInteractiveRegion.recycle();
                     partialInteractiveRegion = null;
                 }
+                spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             }
             final int interrogatingPid = Binder.getCallingPid();
+            callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
+                    interrogatingPid, interrogatingTid);
             final long identityToken = Binder.clearCallingIdentity();
-            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
                         partialInteractiveRegion, interactionId, callback, mFetchFlags,
@@ -2898,6 +2948,7 @@
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
             Region partialInteractiveRegion = Region.obtain();
+            MagnificationSpec spec;
             synchronized (mLock) {
                 mUsesAccessibilityCache = true;
                 if (!isCalledForCurrentUserLocked()) {
@@ -2919,10 +2970,12 @@
                     partialInteractiveRegion.recycle();
                     partialInteractiveRegion = null;
                 }
+                spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             }
             final int interrogatingPid = Binder.getCallingPid();
+            callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
+                    interrogatingPid, interrogatingTid);
             final long identityToken = Binder.clearCallingIdentity();
-            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
                         partialInteractiveRegion, interactionId, callback, mFetchFlags,
@@ -2950,6 +3003,7 @@
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
             Region partialInteractiveRegion = Region.obtain();
+            MagnificationSpec spec;
             synchronized (mLock) {
                 mUsesAccessibilityCache = true;
                 if (!isCalledForCurrentUserLocked()) {
@@ -2971,10 +3025,12 @@
                     partialInteractiveRegion.recycle();
                     partialInteractiveRegion = null;
                 }
+                spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             }
             final int interrogatingPid = Binder.getCallingPid();
+            callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
+                    interrogatingPid, interrogatingTid);
             final long identityToken = Binder.clearCallingIdentity();
-            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
                         partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
@@ -3002,6 +3058,7 @@
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
             Region partialInteractiveRegion = Region.obtain();
+            MagnificationSpec spec;
             synchronized (mLock) {
                 if (!isCalledForCurrentUserLocked()) {
                     return false;
@@ -3023,10 +3080,12 @@
                     partialInteractiveRegion.recycle();
                     partialInteractiveRegion = null;
                 }
+                spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             }
             final int interrogatingPid = Binder.getCallingPid();
+            callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
+                    interrogatingPid, interrogatingTid);
             final long identityToken = Binder.clearCallingIdentity();
-            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion,
                         interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
@@ -3054,6 +3113,7 @@
             final int resolvedWindowId;
             IAccessibilityInteractionConnection connection = null;
             Region partialInteractiveRegion = Region.obtain();
+            MagnificationSpec spec;
             synchronized (mLock) {
                 if (!isCalledForCurrentUserLocked()) {
                     return false;
@@ -3074,10 +3134,12 @@
                     partialInteractiveRegion.recycle();
                     partialInteractiveRegion = null;
                 }
+                spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             }
             final int interrogatingPid = Binder.getCallingPid();
+            callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
+                    interrogatingPid, interrogatingTid);
             final long identityToken = Binder.clearCallingIdentity();
-            MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
             try {
                 connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion,
                         interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
@@ -3149,6 +3211,18 @@
                     if (connection == null) {
                         return false;
                     }
+                    AccessibilityWindowInfo windowInfo =
+                            mSecurityPolicy.findWindowById(resolvedWindowId);
+                    if ((windowInfo != null) && windowInfo.inPictureInPicture()) {
+                        boolean isA11yFocusAction =
+                                (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS)
+                                || (action ==
+                                        AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+                        if ((mPictureInPictureActionReplacingConnection != null)
+                                && !isA11yFocusAction) {
+                            connection = mPictureInPictureActionReplacingConnection.mConnection;
+                        }
+                    }
                 }
             }
             final int interrogatingPid = Binder.getCallingPid();
@@ -3562,7 +3636,7 @@
                 if (mSecurityPolicy.canRetrieveWindowContentLocked(this)) {
                     event.setConnectionId(mId);
                 } else {
-                    event.setSource(null);
+                    event.setSource((View) null);
                 }
                 event.setSealed(true);
             }
@@ -3790,17 +3864,17 @@
         }
 
         private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
-            if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
+            if (accessibilityWindowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
                 return mSecurityPolicy.getActiveWindowId();
             }
             return accessibilityWindowId;
         }
 
         private int resolveAccessibilityWindowIdForFindFocusLocked(int windowId, int focusType) {
-            if (windowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
+            if (windowId == AccessibilityWindowInfo.ACTIVE_WINDOW_ID) {
                 return mSecurityPolicy.mActiveWindowId;
             }
-            if (windowId == AccessibilityNodeInfo.ANY_WINDOW_ID) {
+            if (windowId == AccessibilityWindowInfo.ANY_WINDOW_ID) {
                 if (focusType == AccessibilityNodeInfo.FOCUS_INPUT) {
                     return mSecurityPolicy.mFocusedWindowId;
                 } else if (focusType == AccessibilityNodeInfo.FOCUS_ACCESSIBILITY) {
@@ -3810,6 +3884,20 @@
             return windowId;
         }
 
+        private IAccessibilityInteractionConnectionCallback replaceCallbackIfNeeded(
+                IAccessibilityInteractionConnectionCallback originalCallback,
+                int resolvedWindowId, int interactionId, int interrogatingPid,
+                long interrogatingTid) {
+            AccessibilityWindowInfo windowInfo = mSecurityPolicy.findWindowById(resolvedWindowId);
+            if ((windowInfo == null) || !windowInfo.inPictureInPicture()
+                    || (mPictureInPictureActionReplacingConnection == null)) {
+                return originalCallback;
+            }
+            return new ActionReplacingCallback(originalCallback,
+                    mPictureInPictureActionReplacingConnection.mConnection, interactionId,
+                    interrogatingPid, interrogatingTid);
+        }
+
         private final class InvocationHandler extends Handler {
             public static final int MSG_ON_GESTURE = 1;
             public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 2;
@@ -3960,6 +4048,7 @@
             reportedWindow.setBoundsInScreen(window.boundsInScreen);
             reportedWindow.setTitle(window.title);
             reportedWindow.setAnchorId(window.accessibilityIdOfAnchor);
+            reportedWindow.setPictureInPicture(window.inPictureInPicture);
 
             final int parentId = findWindowIdLocked(window.parentToken);
             if (parentId >= 0) {
@@ -4157,7 +4246,9 @@
             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
             | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
 
+        // In Z order
         public List<AccessibilityWindowInfo> mWindows;
+        public SparseArray<AccessibilityWindowInfo> mWindowsById = new SparseArray<>();
 
         public int mActiveWindowId = INVALID_WINDOW_ID;
         public int mFocusedWindowId = INVALID_WINDOW_ID;
@@ -4217,6 +4308,7 @@
             for (int i = oldWindowCount - 1; i >= 0; i--) {
                 mWindows.remove(i).recycle();
             }
+            mWindowsById.clear();
 
             mFocusedWindowId = INVALID_WINDOW_ID;
             if (!mTouchInteractionInProgress) {
@@ -4245,6 +4337,7 @@
                         }
                     }
                     mWindows.add(window);
+                    mWindowsById.put(windowId, window);
                 }
 
                 if (mTouchInteractionInProgress && activeWindowGone) {
@@ -4306,7 +4399,7 @@
 
         public void updateEventSourceLocked(AccessibilityEvent event) {
             if ((event.getEventType() & RETRIEVAL_ALLOWING_EVENT_TYPES) == 0) {
-                event.setSource(null);
+                event.setSource((View) null);
             }
         }
 
@@ -4446,7 +4539,7 @@
             }
         }
 
-        private void notifyWindowsChanged() {
+        public void notifyWindowsChanged() {
             if (mWindowsForAccessibilityCallback == null) {
                 return;
             }
@@ -4560,11 +4653,15 @@
         }
 
         private AccessibilityWindowInfo findWindowById(int windowId) {
+            return mWindowsById.get(windowId);
+        }
+
+        private AccessibilityWindowInfo getPictureInPictureWindow() {
             if (mWindows != null) {
                 final int windowCount = mWindows.size();
                 for (int i = 0; i < windowCount; i++) {
                     AccessibilityWindowInfo window = mWindows.get(i);
-                    if (window.getId() == windowId) {
+                    if (window.inPictureInPicture()) {
                         return window;
                     }
                 }
diff --git a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
new file mode 100644
index 0000000..0e30fb2
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.MagnificationSpec;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * If we are stripping and/or replacing the actions from a window, we need to intercept the
+ * nodes heading back to the service and swap out the actions.
+ */
+public class ActionReplacingCallback extends IAccessibilityInteractionConnectionCallback.Stub {
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = "ActionReplacingCallback";
+
+    private final IAccessibilityInteractionConnectionCallback mServiceCallback;
+    private final IAccessibilityInteractionConnection mConnectionWithReplacementActions;
+    private final int mInteractionId;
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    List<AccessibilityNodeInfo> mNodesWithReplacementActions;
+
+    @GuardedBy("mLock")
+    List<AccessibilityNodeInfo> mNodesFromOriginalWindow;
+
+    @GuardedBy("mLock")
+    AccessibilityNodeInfo mNodeFromOriginalWindow;
+
+    // Keep track of whether or not we've been called back for a single node
+    @GuardedBy("mLock")
+    boolean mSingleNodeCallbackHappened;
+
+    // Keep track of whether or not we've been called back for multiple node
+    @GuardedBy("mLock")
+    boolean mMultiNodeCallbackHappened;
+
+    // We shouldn't get any more callbacks after we've called back the original service, but
+    // keep track to make sure we catch such strange things
+    @GuardedBy("mLock")
+    boolean mDone;
+
+    public ActionReplacingCallback(IAccessibilityInteractionConnectionCallback serviceCallback,
+            IAccessibilityInteractionConnection connectionWithReplacementActions,
+            int interactionId, int interrogatingPid, long interrogatingTid) {
+        mServiceCallback = serviceCallback;
+        mConnectionWithReplacementActions = connectionWithReplacementActions;
+        mInteractionId = interactionId;
+
+        // Request the root node of the replacing window
+        final long identityToken = Binder.clearCallingIdentity();
+        try {
+            mConnectionWithReplacementActions.findAccessibilityNodeInfoByAccessibilityId(
+                    AccessibilityNodeInfo.ROOT_NODE_ID, null, interactionId + 1, this, 0,
+                    interrogatingPid, interrogatingTid, null, null);
+        } catch (RemoteException re) {
+            if (DEBUG) {
+                Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
+            }
+            // Pretend we already got a (null) list of replacement nodes
+            mMultiNodeCallbackHappened = true;
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+    }
+
+    @Override
+    public void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info, int interactionId) {
+        boolean readyForCallback;
+        synchronized(mLock) {
+            if (interactionId == mInteractionId) {
+                mNodeFromOriginalWindow = info;
+            } else {
+                Slog.e(LOG_TAG, "Callback with unexpected interactionId");
+                throw new RuntimeException("Callback with unexpected interactionId"); // Remove
+            }
+
+            mSingleNodeCallbackHappened = true;
+            readyForCallback = mMultiNodeCallbackHappened;
+        }
+        if (readyForCallback) {
+            replaceInfoActionsAndCallService();
+        }
+    }
+
+    @Override
+    public void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos,
+            int interactionId) {
+        boolean callbackForSingleNode;
+        boolean callbackForMultipleNodes;
+        synchronized(mLock) {
+            if (interactionId == mInteractionId) {
+                mNodesFromOriginalWindow = infos;
+            } else if (interactionId == mInteractionId + 1) {
+                mNodesWithReplacementActions = infos;
+            } else {
+                Slog.e(LOG_TAG, "Callback with unexpected interactionId");
+                throw new RuntimeException("Callback with unexpected interactionId"); // Remove
+            }
+            callbackForSingleNode = mSingleNodeCallbackHappened;
+            callbackForMultipleNodes = mMultiNodeCallbackHappened;
+            mMultiNodeCallbackHappened = true;
+        }
+        if (callbackForSingleNode) {
+            replaceInfoActionsAndCallService();
+        }
+        if (callbackForMultipleNodes) {
+            replaceInfosActionsAndCallService();
+        }
+    }
+
+    @Override
+    public void setPerformAccessibilityActionResult(boolean succeeded, int interactionId)
+            throws RemoteException {
+        // There's no reason to use this class when performing actions. Do something reasonable.
+        mServiceCallback.setPerformAccessibilityActionResult(succeeded, interactionId);
+    }
+
+    private void replaceInfoActionsAndCallService() {
+        final AccessibilityNodeInfo nodeToReturn;
+        synchronized (mLock) {
+            if (mDone) {
+                if (DEBUG) {
+                    Slog.e(LOG_TAG, "Extra callback");
+                }
+                throw new RuntimeException("Extra callback"); // Replace with return before submit
+            }
+            if (mNodeFromOriginalWindow != null) {
+                replaceActionsOnInfoLocked(mNodeFromOriginalWindow);
+            }
+            recycleReplaceActionNodesLocked();
+            nodeToReturn = mNodeFromOriginalWindow;
+            mDone = true;
+        }
+        try {
+            mServiceCallback.setFindAccessibilityNodeInfoResult(nodeToReturn, mInteractionId);
+        } catch (RemoteException re) {
+            if (DEBUG) {
+                Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfoResult");
+            }
+        }
+    }
+
+    private void replaceInfosActionsAndCallService() {
+        final List<AccessibilityNodeInfo> nodesToReturn;
+        synchronized (mLock) {
+            if (mDone) {
+                if (DEBUG) {
+                    Slog.e(LOG_TAG, "Extra callback");
+                }
+                throw new RuntimeException("Extra callback"); // Replace with return before submit
+            }
+            if (mNodesFromOriginalWindow != null) {
+                for (int i = 0; i < mNodesFromOriginalWindow.size(); i++) {
+                    replaceActionsOnInfoLocked(mNodesFromOriginalWindow.get(i));
+                }
+            }
+            recycleReplaceActionNodesLocked();
+            nodesToReturn = mNodesFromOriginalWindow;
+            mDone = true;
+        }
+        try {
+            mServiceCallback.setFindAccessibilityNodeInfosResult(nodesToReturn, mInteractionId);
+        } catch (RemoteException re) {
+            if (DEBUG) {
+                Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfosResult");
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void replaceActionsOnInfoLocked(AccessibilityNodeInfo info) {
+        info.removeAllActions();
+        // We currently only replace actions for the root node
+        if ((info.getSourceNodeId() == AccessibilityNodeInfo.ROOT_NODE_ID)
+                && mNodesWithReplacementActions != null) {
+            // This list should always contain a single node with the root ID
+            for (int i = 0; i < mNodesWithReplacementActions.size(); i++) {
+                AccessibilityNodeInfo nodeWithReplacementActions =
+                        mNodesWithReplacementActions.get(i);
+                if (nodeWithReplacementActions.getSourceNodeId()
+                        == AccessibilityNodeInfo.ROOT_NODE_ID) {
+                    List<AccessibilityAction> actions = nodeWithReplacementActions.getActionList();
+                    if (actions != null) {
+                        for (int j = 0; j < actions.size(); j++) {
+                            info.addAction(actions.get(j));
+                        }
+                        // The PIP needs to be able to take accessibility focus
+                        info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
+                        info.addAction(AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+                    }
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void recycleReplaceActionNodesLocked() {
+        for (int i = mNodesWithReplacementActions.size() - 1; i >= 0; i--) {
+            AccessibilityNodeInfo nodeWithReplacementAction = mNodesWithReplacementActions.get(i);
+            nodeWithReplacementAction.recycle();
+        }
+        mNodesWithReplacementActions = null;
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index e943c4c..b90a2a2 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -17,7 +17,7 @@
 package com.android.server.autofill;
 
 import static android.Manifest.permission.MANAGE_AUTO_FILL;
-import static android.content.Context.AUTO_FILL_MANAGER_SERVICE;
+import static android.content.Context.AUTOFILL_MANAGER_SERVICE;
 import static com.android.server.autofill.Helper.VERBOSE;
 
 import android.Manifest;
@@ -45,8 +45,8 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 import android.view.autofill.IAutoFillManager;
 import android.view.autofill.IAutoFillManagerClient;
@@ -64,7 +64,7 @@
 import java.util.List;
 
 /**
- * Entry point service for auto-fill management.
+ * Entry point service for autofill management.
  *
  * <p>This service provides the {@link IAutoFillManager} implementation and keeps a list of
  * {@link AutoFillManagerServiceImpl} per user; the real work is done by
@@ -91,8 +91,8 @@
      * <p>
      * Entries on this cache are added on demand and removed when:
      * <ol>
-     *   <li>An auto-fill service app is removed.
-     *   <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.\
+     *   <li>An autofill service app is removed.
+     *   <li>The {@link android.provider.Settings.Secure#AUTOFILL_SERVICE} for an user change.
      * </ol>
      */
     // TODO(b/33197203): Update the above comment
@@ -128,7 +128,7 @@
 
     @Override
     public void onStart() {
-        publishBinderService(AUTO_FILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
+        publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
     }
 
     @Override
@@ -314,20 +314,20 @@
 
         @Override
         public void startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
-                AutoFillId autoFillId, Rect bounds, AutoFillValue value, int userId,
+                AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
                 boolean hasCallback) {
             // TODO(b/33197203): make sure it's called by resumed / focused activity
 
             synchronized (mLock) {
                 final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, windowToken, appCallback,
-                        autoFillId, bounds, value, hasCallback);
+                        autofillId, bounds, value, hasCallback);
             }
         }
 
         @Override
-        public void updateSession(IBinder activityToken, AutoFillId id, Rect bounds,
-                AutoFillValue value, int flags, int userId) {
+        public void updateSession(IBinder activityToken, AutofillId id, Rect bounds,
+                AutofillValue value, int flags, int userId) {
             synchronized (mLock) {
                 final AutoFillManagerServiceImpl service = mServicesCache.get(
                         UserHandle.getCallingUserId());
@@ -389,7 +389,7 @@
             super(handler);
             ContentResolver resolver = mContext.getContentResolver();
             resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.AUTO_FILL_SERVICE), false, this, UserHandle.USER_ALL);
+                    Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL);
         }
 
         @Override
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index aa0840c..e691623 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -16,13 +16,13 @@
 
 package com.android.server.autofill;
 
-import static android.service.autofill.AutoFillService.EXTRA_ACTIVITY_TOKEN;
+import static android.service.autofill.AutofillService.EXTRA_ACTIVITY_TOKEN;
 import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
 import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
-import static android.view.autofill.AutoFillManager.FLAG_FOCUS_GAINED;
-import static android.view.autofill.AutoFillManager.FLAG_FOCUS_LOST;
-import static android.view.autofill.AutoFillManager.FLAG_START_SESSION;
-import static android.view.autofill.AutoFillManager.FLAG_VALUE_CHANGED;
+import static android.view.autofill.AutofillManager.FLAG_FOCUS_GAINED;
+import static android.view.autofill.AutofillManager.FLAG_FOCUS_LOST;
+import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
+import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
 
 import static com.android.server.autofill.Helper.DEBUG;
 import static com.android.server.autofill.Helper.VERBOSE;
@@ -51,8 +51,8 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.provider.Settings;
-import android.service.autofill.AutoFillService;
-import android.service.autofill.AutoFillServiceInfo;
+import android.service.autofill.AutofillService;
+import android.service.autofill.AutofillServiceInfo;
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
@@ -62,10 +62,9 @@
 import android.util.LocalLog;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillManager;
-import android.view.autofill.AutoFillValue;
-
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.HandlerCaller;
@@ -94,7 +93,7 @@
     private final AutoFillUI mUi;
 
     private RemoteCallbackList<IAutoFillManagerClient> mClients;
-    private AutoFillServiceInfo mInfo;
+    private AutofillServiceInfo mInfo;
 
     private final LocalLog mRequestsHistory;
 
@@ -114,7 +113,7 @@
     /**
      * Cache of pending {@link Session}s, keyed by {@code activityToken}.
      *
-     * <p>They're kept until the {@link AutoFillService} finished handling a request, an error
+     * <p>They're kept until the {@link AutofillService} finished handling a request, an error
      * occurs, or the session times out.
      */
     // TODO(b/33197203): need to make sure service is bound while callback is pending and/or
@@ -205,21 +204,21 @@
         ComponentName serviceComponent = null;
         ServiceInfo serviceInfo = null;
         final String componentName = Settings.Secure.getStringForUser(
-                mContext.getContentResolver(), Settings.Secure.AUTO_FILL_SERVICE, mUserId);
+                mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
         if (!TextUtils.isEmpty(componentName)) {
             try {
                 serviceComponent = ComponentName.unflattenFromString(componentName);
                 serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
                         0, mUserId);
             } catch (RuntimeException | RemoteException e) {
-                Slog.e(TAG, "Bad auto-fill service name " + componentName + ": " + e);
+                Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
                 return;
             }
         }
         try {
             final boolean hadService = hasService();
             if (serviceInfo != null) {
-                mInfo = new AutoFillServiceInfo(mContext.getPackageManager(),
+                mInfo = new AutofillServiceInfo(mContext.getPackageManager(),
                         serviceComponent, mUserId);
             } else {
                 mInfo = null;
@@ -236,7 +235,7 @@
                 sendStateToClients();
             }
         } catch (PackageManager.NameNotFoundException e) {
-            Slog.e(TAG, "Bad auto-fill service name " + componentName + ": " + e);
+            Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
         }
     }
 
@@ -285,14 +284,15 @@
     }
 
     void startSessionLocked(IBinder activityToken, IBinder windowToken, IBinder appCallbackToken,
-            AutoFillId autoFillId,  Rect bounds, AutoFillValue value, boolean hasCallback) {
+            AutofillId autofillId,  Rect bounds, AutofillValue value, boolean hasCallback) {
         if (!hasService()) {
             return;
         }
 
         final String historyItem = "s=" + mInfo.getServiceInfo().packageName
                 + " u=" + mUserId + " a=" + activityToken
-                + " i=" + autoFillId + " b=" + bounds + " hc=" + hasCallback;
+
+                + " i=" + autofillId + " b=" + bounds + " hc=" + hasCallback;
         mRequestsHistory.log(historyItem);
 
         // TODO(b/33197203): Handle partitioning
@@ -304,7 +304,7 @@
 
         final Session newSession = createSessionByTokenLocked(activityToken,
                 windowToken, appCallbackToken, hasCallback);
-        newSession.updateLocked(autoFillId, bounds, value, FLAG_START_SESSION);
+        newSession.updateLocked(autofillId, bounds, value, FLAG_START_SESSION);
     }
 
     void finishSessionLocked(IBinder activityToken) {
@@ -340,9 +340,9 @@
             receiverExtras.putBinder(EXTRA_ACTIVITY_TOKEN, activityToken);
             final long identity = Binder.clearCallingIdentity();
             try {
-                if (!ActivityManager.getService().requestAutoFillData(mAssistReceiver,
+                if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
                         receiverExtras, activityToken)) {
-                    Slog.w(TAG, "failed to request auto-fill data for " + activityToken);
+                    Slog.w(TAG, "failed to request autofill data for " + activityToken);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -353,8 +353,8 @@
         return newSession;
     }
 
-    void updateSessionLocked(IBinder activityToken, AutoFillId autoFillId, Rect bounds,
-            AutoFillValue value, int flags) {
+    void updateSessionLocked(IBinder activityToken, AutofillId autofillId, Rect bounds,
+            AutofillValue value, int flags) {
         // TODO(b/33197203): add MetricsLogger call
         final Session session = mSessions.get(activityToken);
         if (session == null) {
@@ -364,7 +364,7 @@
             return;
         }
 
-        session.updateLocked(autoFillId, bounds, value, flags);
+        session.updateLocked(autofillId, bounds, value, flags);
     }
 
     private void handleSessionSave(IBinder activityToken) {
@@ -463,7 +463,7 @@
     }
 
     /**
-     * State for a given view with a AutoFillId.
+     * State for a given view with a AutofillId.
      *
      * <p>This class holds state about a view and calls its listener when the fill UI is ready to
      * be displayed for the view.
@@ -474,10 +474,10 @@
              * Called when the fill UI is ready to be shown for this view.
              */
             void onFillReady(ViewState viewState, FillResponse fillResponse, Rect bounds,
-                    AutoFillId focusedId, @Nullable AutoFillValue value);
+                    AutofillId focusedId, @Nullable AutofillValue value);
         }
 
-        final AutoFillId mId;
+        final AutofillId mId;
         private final Listener mListener;
         // TODO(b/33197203): would not need a reference to response and session if it was an inner
         // class of Session...
@@ -486,12 +486,12 @@
         FillResponse mResponse;
         Intent mAuthIntent;
 
-        private AutoFillValue mAutoFillValue;
+        private AutofillValue mAutofillValue;
         private Rect mBounds;
 
         private boolean mValueUpdated;
 
-        ViewState(Session session, AutoFillId id, Listener listener) {
+        ViewState(Session session, AutofillId id, Listener listener) {
             mSession = session;
             mId = id;
             mListener = listener;
@@ -520,9 +520,9 @@
         // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
         // it can change  the value and update the UI; similarly, should replace code that
         // directly sets mAutoFilLValue to use encapsulation.
-        void update(@Nullable AutoFillValue autoFillValue, @Nullable Rect bounds) {
-            if (autoFillValue != null) {
-                mAutoFillValue = autoFillValue;
+        void update(@Nullable AutofillValue autofillValue, @Nullable Rect bounds) {
+            if (autofillValue != null) {
+                mAutofillValue = autofillValue;
             }
             if (bounds != null) {
                 mBounds = bounds;
@@ -533,25 +533,25 @@
 
         /**
          * Calls {@link
-         * Listener#onFillReady(ViewState, FillResponse, Rect, AutoFillId, AutoFillValue)} if the
+         * Listener#onFillReady(ViewState, FillResponse, Rect, AutofillId, AutofillValue)} if the
          * fill UI is ready to be displayed (i.e. when response and bounds are set).
          */
         void maybeCallOnFillReady() {
             if (mResponse != null && (mResponse.getAuthentication() != null
                     || mResponse.getDatasets() != null) && mBounds != null) {
-                mListener.onFillReady(this, mResponse, mBounds, mId, mAutoFillValue);
+                mListener.onFillReady(this, mResponse, mBounds, mId, mAutofillValue);
             }
         }
 
         @Override
         public String toString() {
-            return "ViewState: [id=" + mId + ", value=" + mAutoFillValue + ", bounds=" + mBounds
+            return "ViewState: [id=" + mId + ", value=" + mAutofillValue + ", bounds=" + mBounds
                     + ", updated = " + mValueUpdated + "]";
         }
 
         void dump(String prefix, PrintWriter pw) {
             pw.print(prefix); pw.print("id:" ); pw.println(mId);
-            pw.print(prefix); pw.print("value:" ); pw.println(mAutoFillValue);
+            pw.print(prefix); pw.print("value:" ); pw.println(mAutofillValue);
             pw.print(prefix); pw.print("updated:" ); pw.println(mValueUpdated);
             pw.print(prefix); pw.print("bounds:" ); pw.println(mBounds);
             pw.print(prefix); pw.print("authIntent:" ); pw.println(mAuthIntent);
@@ -564,7 +564,7 @@
      * <p>This class manages the multiple {@link ViewState}s for each view it has, and keeps track
      * of the current {@link ViewState} to display the appropriate UI.
      *
-     * <p>Although the auto-fill requests and callbacks are stateless from the service's point of
+     * <p>Although the autofill requests and callbacks are stateless from the service's point of
      * view, we need to keep state in the framework side for cases such as authentication. For
      * example, when service return a {@link FillResponse} that contains all the fields needed
      * to fill the activity but it requires authentication first, that response need to be held
@@ -580,7 +580,7 @@
         private final IBinder mWindowToken;
 
         @GuardedBy("mLock")
-        private final Map<AutoFillId, ViewState> mViewStates = new ArrayMap<>();
+        private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>();
 
         @GuardedBy("mLock")
         @Nullable
@@ -604,7 +604,7 @@
 
         /**
          * Assist structure sent by the app; it will be updated (sanitized, change values for save)
-         * before sent to {@link AutoFillService}.
+         * before sent to {@link AutofillService}.
          */
         @GuardedBy("mLock")
         private AssistStructure mStructure;
@@ -692,11 +692,11 @@
             try {
                 final String autoFillService = Settings.Secure.getStringForUser(
                         mContext.getContentResolver(),
-                        Settings.Secure.AUTO_FILL_SERVICE, mUserId);
+                        Settings.Secure.AUTOFILL_SERVICE, mUserId);
                 if (mInfo.getServiceInfo().getComponentName().equals(
                         ComponentName.unflattenFromString(autoFillService))) {
                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                            Settings.Secure.AUTO_FILL_SERVICE, null, mUserId);
+                            Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -738,7 +738,7 @@
 
         // AutoFillUiCallback
         @Override
-        public void onEvent(AutoFillId id, int event) {
+        public void onEvent(AutofillId id, int event) {
             mHandlerCaller.getHandler().post(() -> {
                 notifyChangeToClient(id, event);
             });
@@ -749,7 +749,7 @@
                 removeSelf();
             } else {
                 Parcelable result = data.getParcelable(
-                        AutoFillManager.EXTRA_AUTHENTICATION_RESULT);
+                        AutofillManager.EXTRA_AUTHENTICATION_RESULT);
                 if (result instanceof FillResponse) {
                     mCurrentResponse = (FillResponse) result;
                     processResponseLocked(mCurrentResponse);
@@ -777,7 +777,7 @@
             }
             if (mCurrentResponse == null) {
                 // Happens when the activity / session was finished before the service replied, or
-                // when the service cannot auto-fill it (and returned a null response).
+                // when the service cannot autofill it (and returned a null response).
                 if (DEBUG) {
                     Slog.d(TAG, "showSaveLocked(): no mCurrentResponse");
                 }
@@ -795,16 +795,16 @@
 
             final int size = saveInfo.getSavableIds().size();
             for (int i = 0; i < size; i++) {
-                final AutoFillId id = saveInfo.getSavableIds().valueAt(i);
+                final AutofillId id = saveInfo.getSavableIds().valueAt(i);
                 final ViewState state = mViewStates.get(id);
                 if (state != null && state.mValueUpdated) {
-                    final AutoFillValue filledValue = findValue(mAutoFilledDataset, id);
-                    if (state.mAutoFillValue == null || state.mAutoFillValue.equals(filledValue)) {
+                    final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
+                    if (state.mAutofillValue == null || state.mAutofillValue.equals(filledValue)) {
                         continue;
                     }
                     if (DEBUG) {
                         Slog.d(TAG, "finishSessionLocked(): found a change on " + id + ": "
-                                + state.mAutoFillValue);
+                                + state.mAutofillValue);
                     }
                     getUiForShowing().showSaveUi(
                             mInfo.getServiceInfo().loadLabel(mContext.getPackageManager()),
@@ -829,15 +829,15 @@
 
             final Bundle extras = this.mCurrentResponse.getExtras();
 
-            for (Entry<AutoFillId, ViewState> entry : mViewStates.entrySet()) {
-                final AutoFillValue value = entry.getValue().mAutoFillValue;
+            for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
+                final AutofillValue value = entry.getValue().mAutofillValue;
                 if (value == null) {
                     if (VERBOSE) {
                         Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
                     }
                     continue;
                 }
-                final AutoFillId id = entry.getKey();
+                final AutofillId id = entry.getKey();
                 final ViewNode node = findViewNodeByIdLocked(id);
                 if (node == null) {
                     Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
@@ -847,7 +847,7 @@
                     Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
                 }
 
-                node.updateAutoFillValue(value);
+                node.updateAutofillValue(value);
             }
 
             // Sanitize structure before it's sent to service.
@@ -861,10 +861,10 @@
             mRemoteFillService.onSaveRequest(mStructure, extras);
         }
 
-        void updateLocked(AutoFillId id, Rect bounds, AutoFillValue value, int flags) {
+        void updateLocked(AutofillId id, Rect bounds, AutofillValue value, int flags) {
             if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) {
                 // TODO(b/33197203): ignoring because we don't support partitions yet
-                Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was auto-filled");
+                Slog.d(TAG, "updateLocked(): ignoring " + flags + " after app was autofilled");
                 return;
             }
 
@@ -875,28 +875,28 @@
             }
 
             if ((flags & FLAG_START_SESSION) != 0) {
-                // View is triggering auto-fill.
+                // View is triggering autofill.
                 mCurrentViewState = viewState;
                 viewState.update(value, bounds);
                 return;
             }
 
             if ((flags & FLAG_VALUE_CHANGED) != 0) {
-                if (value != null && !value.equals(viewState.mAutoFillValue)) {
+                if (value != null && !value.equals(viewState.mAutofillValue)) {
                     viewState.mValueUpdated = true;
 
-                    // Must check if this update was caused by auto-filling the view, in which
+                    // Must check if this update was caused by autofilling the view, in which
                     // case we just update the value, but not the UI.
                     if (mAutoFilledDataset != null) {
-                        final AutoFillValue filledValue = findValue(mAutoFilledDataset, id);
+                        final AutofillValue filledValue = findValue(mAutoFilledDataset, id);
                         if (value.equals(filledValue)) {
-                            viewState.mAutoFillValue = value;
+                            viewState.mAutofillValue = value;
                             return;
                         }
                     }
 
                     // Change value
-                    viewState.mAutoFillValue = value;
+                    viewState.mAutofillValue = value;
 
                     // Update the chooser UI
                     getUiForShowing().filterFillUi(value.coerceToString());
@@ -936,10 +936,10 @@
 
         @Override
         public void onFillReady(ViewState viewState, FillResponse response, Rect bounds,
-                AutoFillId filledId, @Nullable AutoFillValue value) {
+                AutofillId filledId, @Nullable AutofillValue value) {
             String filterText = "";
             if (value != null) {
-                // TODO(b/33197203): Handle other AutoFillValue types
+                // TODO(b/33197203): Handle other AutofillValue types
                 final CharSequence text = value.getTextValue();
                 if (text != null) {
                     filterText = text.toString();
@@ -949,7 +949,7 @@
             getUiForShowing().showFillUi(filledId, response, bounds, filterText);
         }
 
-        private void notifyChangeToClient(AutoFillId id, int event) {
+        private void notifyChangeToClient(AutofillId id, int event) {
             if (!mHasCallback) return;
             try {
                 mClient.onAutofillEvent(mWindowToken, id, event);
@@ -1006,7 +1006,7 @@
 
         private Intent createAuthFillInIntent(AssistStructure structure) {
             Intent fillInIntent = new Intent();
-            fillInIntent.putExtra(AutoFillManager.EXTRA_ASSIST_STRUCTURE, structure);
+            fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
             return fillInIntent;
         }
 
@@ -1025,7 +1025,7 @@
             pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState);
             pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size());
             final String prefix2 = prefix + "  ";
-            for (Map.Entry<AutoFillId, ViewState> entry : mViewStates.entrySet()) {
+            for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
                 pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
                 entry.getValue().dump(prefix2, pw);
             }
@@ -1049,9 +1049,9 @@
                     if (DEBUG) {
                         Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
                     }
-                    mClient.autoFill(dataset.getFieldIds(), dataset.getFieldValues());
+                    mClient.autofill(dataset.getFieldIds(), dataset.getFieldValues());
                 } catch (RemoteException e) {
-                    Slog.w(TAG, "Error auto-filling activity: " + e);
+                    Slog.w(TAG, "Error autofilling activity: " + e);
                 }
             }
         }
@@ -1063,12 +1063,12 @@
             }
         }
 
-        private ViewNode findViewNodeByIdLocked(AutoFillId id) {
+        private ViewNode findViewNodeByIdLocked(AutofillId id) {
             final int size = mStructure.getWindowNodeCount();
             for (int i = 0; i < size; i++) {
                 final WindowNode window = mStructure.getWindowNodeAt(i);
                 final ViewNode root = window.getRootViewNode();
-                if (id.equals(root.getAutoFillId())) {
+                if (id.equals(root.getAutofillId())) {
                     return root;
                 }
                 final ViewNode child = findViewNodeByIdLocked(root, id);
@@ -1079,16 +1079,16 @@
             return null;
         }
 
-        private ViewNode findViewNodeByIdLocked(ViewNode parent, AutoFillId id) {
+        private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
             final int childrenSize = parent.getChildCount();
             if (childrenSize > 0) {
                 for (int i = 0; i < childrenSize; i++) {
                     final ViewNode child = parent.getChildAt(i);
-                    if (id.equals(child.getAutoFillId())) {
+                    if (id.equals(child.getAutofillId())) {
                         return child;
                     }
                     final ViewNode grandChild = findViewNodeByIdLocked(child, id);
-                    if (grandChild != null && id.equals(grandChild.getAutoFillId())) {
+                    if (grandChild != null && id.equals(grandChild.getAutofillId())) {
                         return grandChild;
                     }
                 }
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 2f600c2..090cf91 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -19,8 +19,8 @@
 import android.annotation.Nullable;
 import android.os.Bundle;
 import android.service.autofill.Dataset;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -61,9 +61,9 @@
      * Gets the value of a {@link Dataset} field by its id, or {@code null} if not found.
      */
     @Nullable
-    static AutoFillValue findValue(Dataset dataset, AutoFillId id) {
+    static AutofillValue findValue(Dataset dataset, AutofillId id) {
         if (dataset != null) {
-            final ArrayList<AutoFillId> ids = dataset.getFieldIds();
+            final ArrayList<AutofillId> ids = dataset.getFieldIds();
             final int size = ids.size();
             for (int i = 0; i < size; i++) {
                 if (id.equals(ids.get(i))) {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index d9f9721..76385b1 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -30,7 +30,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.service.autofill.AutoFillService;
+import android.service.autofill.AutofillService;
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.service.autofill.IAutoFillServiceConnection;
@@ -100,8 +100,7 @@
         mContext = context;
         mCallbacks = callbacks;
         mComponentName = componentName;
-        mIntent = new Intent(AutoFillService.SERVICE_INTERFACE)
-                .setComponent(mComponentName);
+        mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
         mUserId = userId;
         mHandler = new MyHandler(context);
     }
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 599bbfe..3eefa7c 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -15,8 +15,8 @@
  */
 package com.android.server.autofill.ui;
 
-import static android.view.autofill.AutoFillManager.AutofillCallback.EVENT_INPUT_HIDDEN;
-import static android.view.autofill.AutoFillManager.AutofillCallback.EVENT_INPUT_SHOWN;
+import static android.view.autofill.AutofillManager.AutofillCallback.EVENT_INPUT_HIDDEN;
+import static android.view.autofill.AutofillManager.AutofillCallback.EVENT_INPUT_SHOWN;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -31,7 +31,7 @@
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.Slog;
-import android.view.autofill.AutoFillId;
+import android.view.autofill.AutofillId;
 import android.widget.Toast;
 
 import com.android.server.UiThread;
@@ -39,7 +39,7 @@
 import java.io.PrintWriter;
 
 /**
- * Handles all auto-fill related UI tasks. The UI has two components:
+ * Handles all autofill related UI tasks. The UI has two components:
  * fill UI that shows a popup style window anchored at the focused
  * input field for choosing a dataset to fill or trigger the response
  * authentication flow; save UI that shows a toast style window for
@@ -66,7 +66,7 @@
         void fill(@NonNull Dataset dataset);
         void save();
         void cancelSave();
-        void onEvent(AutoFillId id, int event);
+        void onEvent(AutofillId id, int event);
     }
 
     public AutoFillUI(@NonNull Context context) {
@@ -102,7 +102,7 @@
     /**
      * Hides the fill UI.
      */
-    public void hideFillUi(AutoFillId id) {
+    public void hideFillUi(AutofillId id) {
         mHandler.post(() -> {
             hideFillUiUiThread();
             if (mCallback != null) {
@@ -153,7 +153,7 @@
      * @param anchorBounds bounds of the focused view
      * @param filterText text of the view to be filled
      */
-    public void showFillUi(@NonNull AutoFillId focusedId, @NonNull FillResponse response,
+    public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
             @NonNull Rect anchorBounds, @Nullable String filterText) {
         mHandler.post(() -> {
             if (!hasCallback()) {
@@ -190,7 +190,7 @@
     }
 
     /**
-     * Shows the UI asking the user to save for auto-fill.
+     * Shows the UI asking the user to save for autofill.
      */
     public void showSaveUi(@NonNull CharSequence providerLabel, @NonNull SaveInfo info) {
         mHandler.post(() -> {
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 0d5fbbe..4a380c5 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -32,12 +32,11 @@
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 import com.android.internal.R;
-import com.android.internal.R;
 import libcore.util.Objects;
 
 import java.util.ArrayList;
@@ -67,7 +66,7 @@
     private boolean mDestroyed;
 
     FillUi(@NonNull Context context, @NonNull FillResponse response,
-            @NonNull AutoFillId focusedViewId, @NonNull IBinder windowToken,
+            @NonNull AutofillId focusedViewId, @NonNull IBinder windowToken,
             @NonNull Rect anchorBounds, @Nullable String filterText,
             @NonNull Callback callback) {
         mAnchorBounds.set(anchorBounds);
@@ -101,7 +100,7 @@
                 final Dataset dataset = response.getDatasets().get(i);
                 final int index = dataset.getFieldIds().indexOf(focusedViewId);
                 if (index >= 0) {
-                    AutoFillValue value = dataset.getFieldValues().get(index);
+                    final AutofillValue value = dataset.getFieldValues().get(index);
                     final View view;
                     try {
                         view = dataset.getPresentation().apply(context, null);
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 0d438cb..179b3d0 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2839,7 +2839,8 @@
     }
 
     final class UidObserver extends IUidObserver.Stub {
-        @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState,
+                long procStateSeq) throws RemoteException {
         }
 
         @Override public void onUidGone(int uid, boolean disabled) throws RemoteException {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0a65cab..fef7b51 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -127,10 +127,11 @@
 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
-import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -533,8 +534,8 @@
     // on getting this result before starting to launch its UI).
     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
 
-    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
-    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
+    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
+    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
 
     // Maximum number of persisted Uri grants a package is allowed
     static final int MAX_PERSISTED_URI_GRANTS = 128;
@@ -702,6 +703,7 @@
 
     public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
+        public boolean isHome;
         public final Bundle extras;
         public final Intent intent;
         public final String hint;
@@ -723,6 +725,7 @@
             receiverExtras = _receiverExtras;
             userHandle = _userHandle;
         }
+
         @Override
         public void run() {
             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
@@ -2625,11 +2628,11 @@
     }
 
     @VisibleForTesting
-    public ActivityManagerService() {
+    public ActivityManagerService(AppOpsService appOpsService) {
         GL_ES_VERSION = 0;
         mActivityStarter = null;
         mAppErrors = null;
-        mAppOpsService = null;
+        mAppOpsService = appOpsService;
         mBatteryStatsService = null;
         mCompatModePackages = null;
         mConstants = null;
@@ -4255,7 +4258,8 @@
         mProcessObservers.finishBroadcast();
     }
 
-    private void dispatchUidsChanged() {
+    @VisibleForTesting
+    void dispatchUidsChanged() {
         int N;
         synchronized (this) {
             N = mPendingUidChanges.size();
@@ -4278,104 +4282,105 @@
         int i = mUidObservers.beginBroadcast();
         while (i > 0) {
             i--;
-            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
-            final UidObserverRegistration reg = (UidObserverRegistration)
-                    mUidObservers.getBroadcastCookie(i);
-            if (observer != null) {
-                try {
-                    for (int j=0; j<N; j++) {
-                        UidRecord.ChangeItem item = mActiveUidChanges[j];
-                        final int change = item.change;
-                        UidRecord validateUid = null;
-                        if (VALIDATE_UID_STATES && i == 0) {
-                            validateUid = mValidateUids.get(item.uid);
-                            if (validateUid == null && change != UidRecord.CHANGE_GONE
-                                    && change != UidRecord.CHANGE_GONE_IDLE) {
-                                validateUid = new UidRecord(item.uid);
-                                mValidateUids.put(item.uid, validateUid);
-                            }
-                        }
-                        if (change == UidRecord.CHANGE_IDLE
-                                || change == UidRecord.CHANGE_GONE_IDLE) {
-                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
-                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                                        "UID idle uid=" + item.uid);
-                                observer.onUidIdle(item.uid, item.ephemeral);
-                            }
-                            if (VALIDATE_UID_STATES && i == 0) {
-                                if (validateUid != null) {
-                                    validateUid.idle = true;
-                                }
-                            }
-                        } else if (change == UidRecord.CHANGE_ACTIVE) {
-                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
-                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                                        "UID active uid=" + item.uid);
-                                observer.onUidActive(item.uid);
-                            }
-                            if (VALIDATE_UID_STATES && i == 0) {
-                                validateUid.idle = false;
-                            }
-                        }
-                        if (change == UidRecord.CHANGE_GONE
-                                || change == UidRecord.CHANGE_GONE_IDLE) {
-                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
-                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                                        "UID gone uid=" + item.uid);
-                                observer.onUidGone(item.uid, item.ephemeral);
-                            }
-                            if (reg.lastProcStates != null) {
-                                reg.lastProcStates.delete(item.uid);
-                            }
-                            if (VALIDATE_UID_STATES && i == 0) {
-                                if (validateUid != null) {
-                                    mValidateUids.remove(item.uid);
-                                }
-                            }
-                        } else {
-                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
-                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                                        "UID CHANGED uid=" + item.uid
-                                                + ": " + item.processState);
-                                boolean doReport = true;
-                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
-                                    final int lastState = reg.lastProcStates.get(item.uid,
-                                            ActivityManager.PROCESS_STATE_UNKNOWN);
-                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
-                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
-                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
-                                        doReport = lastAboveCut != newAboveCut;
-                                    } else {
-                                        doReport = item.processState
-                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
-                                    }
-                                }
-                                if (doReport) {
-                                    if (reg.lastProcStates != null) {
-                                        reg.lastProcStates.put(item.uid, item.processState);
-                                    }
-                                    observer.onUidStateChanged(item.uid, item.processState);
-                                }
-                            }
-                            if (VALIDATE_UID_STATES && i == 0) {
-                                validateUid.curProcState = validateUid.setProcState
-                                        = item.processState;
-                            }
-                        }
-                    }
-                } catch (RemoteException e) {
-                }
-            }
+            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
+                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
         }
         mUidObservers.finishBroadcast();
 
+        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
+            for (int j = 0; j < N; ++j) {
+                final UidRecord.ChangeItem item = mActiveUidChanges[j];
+                if (item.change == UidRecord.CHANGE_GONE
+                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
+                    mValidateUids.remove(item.uid);
+                } else {
+                    UidRecord validateUid = mValidateUids.get(item.uid);
+                    if (validateUid == null) {
+                        validateUid = new UidRecord(item.uid);
+                        mValidateUids.put(item.uid, validateUid);
+                    }
+                    if (item.change == UidRecord.CHANGE_IDLE) {
+                        validateUid.idle = true;
+                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
+                        validateUid.idle = false;
+                    }
+                    validateUid.curProcState = validateUid.setProcState = item.processState;
+                }
+            }
+        }
+
         synchronized (this) {
-            for (int j=0; j<N; j++) {
+            for (int j = 0; j < N; j++) {
                 mAvailUidChanges.add(mActiveUidChanges[j]);
             }
         }
     }
 
+    private void dispatchUidsChangedForObserver(IUidObserver observer,
+            UidObserverRegistration reg, int changesSize) {
+        if (observer == null) {
+            return;
+        }
+        try {
+            for (int j = 0; j < changesSize; j++) {
+                UidRecord.ChangeItem item = mActiveUidChanges[j];
+                final int change = item.change;
+                if (change == UidRecord.CHANGE_IDLE
+                        || change == UidRecord.CHANGE_GONE_IDLE) {
+                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID idle uid=" + item.uid);
+                        observer.onUidIdle(item.uid, item.ephemeral);
+                    }
+                } else if (change == UidRecord.CHANGE_ACTIVE) {
+                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID active uid=" + item.uid);
+                        observer.onUidActive(item.uid);
+                    }
+                }
+                if (change == UidRecord.CHANGE_GONE
+                        || change == UidRecord.CHANGE_GONE_IDLE) {
+                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID gone uid=" + item.uid);
+                        observer.onUidGone(item.uid, item.ephemeral);
+                    }
+                    if (reg.lastProcStates != null) {
+                        reg.lastProcStates.delete(item.uid);
+                    }
+                } else {
+                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
+                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                                "UID CHANGED uid=" + item.uid
+                                        + ": " + item.processState);
+                        boolean doReport = true;
+                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
+                            final int lastState = reg.lastProcStates.get(item.uid,
+                                    ActivityManager.PROCESS_STATE_UNKNOWN);
+                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
+                                final boolean lastAboveCut = lastState <= reg.cutpoint;
+                                final boolean newAboveCut = item.processState <= reg.cutpoint;
+                                doReport = lastAboveCut != newAboveCut;
+                            } else {
+                                doReport = item.processState
+                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
+                            }
+                        }
+                        if (doReport) {
+                            if (reg.lastProcStates != null) {
+                                reg.lastProcStates.put(item.uid, item.processState);
+                            }
+                            observer.onUidStateChanged(item.uid, item.processState,
+                                    item.procStateSeq);
+                        }
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+        }
+    }
+
     @Override
     public final int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
@@ -9650,7 +9655,7 @@
             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                     "getTaskThumbnail()");
             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
-                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
             if (tr != null) {
                 return tr.getTaskThumbnailLocked();
             }
@@ -9663,8 +9668,8 @@
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                     "getTaskDescription()");
-            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
-                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
+                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
             if (tr != null) {
                 return tr.lastTaskDescription;
             }
@@ -9776,7 +9781,7 @@
     public void setTaskResizeable(int taskId, int resizeableMode) {
         synchronized (this) {
             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
-                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
             if (task == null) {
                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
                 return;
@@ -9838,8 +9843,8 @@
         Rect rect = new Rect();
         try {
             synchronized (this) {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
-                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
                 if (task == null) {
                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
                     return rect;
@@ -9870,8 +9875,8 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
-                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
                 if (task == null) {
                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
                     return;
@@ -9889,8 +9894,8 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
-                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
                 if (task == null) {
                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
                     return;
@@ -9909,8 +9914,8 @@
         try {
             final TaskRecord task;
             synchronized (this) {
-                task = mStackSupervisor.anyTaskForIdLocked(
-                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
                 if (task == null) {
                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
                     return null;
@@ -12646,16 +12651,16 @@
     }
 
     @Override
-    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
+    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
             IBinder activityToken) {
         // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
         // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
-        // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
+        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
         // requests use flags in the future as well (since their flags value might collide with the
-        // auto-fill flag values).
-        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTO_FILL, null, null,
+        // autofill flag values).
+        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
-                null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT) != null;
+                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
     }
 
     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
@@ -12702,6 +12707,7 @@
 
             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
                     userHandle);
+            pae.isHome = activity.isHomeActivity();
 
             // Increment the sessionId if necessary
             if (newSessionId) {
@@ -12748,6 +12754,8 @@
         }
     }
 
+    /** Called from an app when assist data is ready. */
+    @Override
     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
             AssistContent content, Uri referrer) {
         PendingAssistExtras pae = (PendingAssistExtras)token;
@@ -12758,6 +12766,9 @@
             if (referrer != null) {
                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
             }
+            if (structure != null) {
+                structure.setHomeActivity(pae.isHome);
+            }
             pae.haveResult = true;
             pae.notifyAll();
             if (pae.intent == null && pae.receiver == null) {
@@ -19890,14 +19901,11 @@
     /** Helper method that requests bounds from WM and applies them to stack. */
     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
         final Rect newStackBounds = new Rect();
-        final Rect newTempTaskBounds = new Rect();
-        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds,
-                newTempTaskBounds);
+        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
         mStackSupervisor.resizeStackLocked(
                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
-                !newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */,
-                null /* tempTaskInsetBounds */, false /* preserveWindows */,
-                false /* allowResizeInDockedMode */, deferResume);
+                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
     }
 
     /**
@@ -21477,6 +21485,7 @@
         pendingChange.processState = uidRec != null
                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
         pendingChange.ephemeral = uidRec.ephemeral;
+        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
 
         // Directly update the power manager, since we sit on top of it and it is critical
         // it be kept in sync (so wake locks will be held as soon as appropriate).
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 15a9efc..2d91cad 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -120,6 +120,7 @@
 import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
 import com.android.server.wm.StackWindowController;
 import com.android.server.wm.StackWindowListener;
+import com.android.server.wm.TaskStack;
 import com.android.server.wm.WindowManagerService;
 
 import java.io.FileDescriptor;
@@ -544,10 +545,13 @@
         mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
     }
 
-    void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds, Rect outTempInsetBounds,
-            boolean ignoreVisibility) {
-        mWindowContainerController.getStackDockedModeBounds(outBounds, outTempBounds,
-                outTempInsetBounds, ignoreVisibility);
+    /**
+     * @see ActivityStack.getStackDockedModeBounds(Rect, Rect, Rect, boolean)
+     */
+    void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
+            Rect outTempTaskBounds, boolean ignoreVisibility) {
+        mWindowContainerController.getStackDockedModeBounds(currentTempTaskBounds,
+                outStackBounds, outTempTaskBounds, ignoreVisibility);
     }
 
     void prepareFreezingTaskBounds() {
@@ -562,8 +566,8 @@
         outBounds.setEmpty();
     }
 
-    void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
-        mWindowContainerController.getBoundsForNewConfiguration(outBounds, outTempBounds);
+    void getBoundsForNewConfiguration(Rect outBounds) {
+        mWindowContainerController.getBoundsForNewConfiguration(outBounds);
     }
 
     void positionChildWindowContainerAtTop(TaskRecord child) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 59f58d7..2ae815e30 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -21,8 +21,6 @@
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.ActivityManager.RESIZE_MODE_FORCED;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
@@ -97,6 +95,7 @@
 import static java.lang.Integer.MAX_VALUE;
 
 import android.Manifest;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.Activity;
@@ -105,7 +104,6 @@
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityOptions;
-import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityContainerCallback;
 import android.app.ProfilerInfo;
@@ -179,10 +177,11 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 
 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
@@ -248,15 +247,31 @@
     // Force the focus to change to the stack we are moving a task to..
     static final boolean FORCE_FOCUS = true;
 
-    // Restore task from the saved recents if it can't be found in any live stack.
-    static final boolean RESTORE_FROM_RECENTS = true;
-
     // Don't execute any calls to resume.
     static final boolean DEFER_RESUME = true;
 
     // Used to indicate that a task is removed it should also be removed from recents.
     static final boolean REMOVE_FROM_RECENTS = true;
 
+    /**
+     * The modes which affect which tasks are returned when calling
+     * {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            MATCH_TASK_IN_STACKS_ONLY,
+            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
+            MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
+    })
+    public @interface AnyTaskForIdMatchTaskMode {}
+    // Match only tasks in the current stacks
+    static final int MATCH_TASK_IN_STACKS_ONLY = 0;
+    // Match either tasks in the current stacks, or in the recent tasks if not found in the stacks
+    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS = 1;
+    // Match either tasks in the current stacks, or in the recent tasks, restoring it to the
+    // provided stack id
+    static final int MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE = 2;
+
     // Activity actions an app cannot start if it uses a permission which is not granted.
     private static final ArrayMap<String, String> ACTION_TO_RUNTIME_PERMISSION =
             new ArrayMap<>();
@@ -713,18 +728,26 @@
     }
 
     TaskRecord anyTaskForIdLocked(int id) {
-        return anyTaskForIdLocked(id, RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+        return anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
+                INVALID_STACK_ID);
     }
 
     /**
      * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
      * @param id Id of the task we would like returned.
-     * @param restoreFromRecents If the id was not in the active list, but was found in recents,
-     *                           restore the task from recents to the active list.
+     * @param matchMode The mode to match the given task id in.
      * @param stackId The stack to restore the task to (default launch stack will be used if
-     *                stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}).
+     *                stackId is {@link android.app.ActivityManager.StackId#INVALID_STACK_ID}). Only
+     *                valid if the matchMode is
+     *                {@link #MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE}.
      */
-    TaskRecord anyTaskForIdLocked(int id, boolean restoreFromRecents, int stackId) {
+    TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, int stackId) {
+        // If there is a stack id set, ensure that we are attempting to actually restore a task
+        if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE &&
+                stackId != INVALID_STACK_ID) {
+            throw new IllegalArgumentException("Should not specify stackId for non-restore lookup");
+        }
+
         int numDisplays = mActivityDisplays.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -737,18 +760,23 @@
             }
         }
 
-        // Don't give up! Look in recents.
-        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
-        TaskRecord task = mRecentTasks.taskForIdLocked(id);
-        if (task == null) {
-            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
+        // If we are matching stack tasks only, return now
+        if (matchMode == MATCH_TASK_IN_STACKS_ONLY) {
             return null;
         }
 
-        if (!restoreFromRecents) {
+        // Otherwise, check the recent tasks and return if we find it there and we are not restoring
+        // the task from recents
+        if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
+        TaskRecord task = mRecentTasks.taskForIdLocked(id);
+        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
+            if (DEBUG_RECENTS && task == null) {
+                Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
+            }
             return task;
         }
 
+        // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE
         if (!restoreRecentTaskLocked(task, stackId)) {
             if (DEBUG_RECENTS) Slog.w(TAG_RECENTS,
                     "Couldn't restore task id=" + id + " found in recents");
@@ -844,7 +872,7 @@
         // was 10, user 0 could only have taskIds 0 to 9, user 1: 10 to 19, user 2: 20 to 29, so on.
         int candidateTaskId = nextTaskIdForUser(currentTaskId, userId);
         while (mRecentTasks.taskIdTakenForUserLocked(candidateTaskId, userId)
-                || anyTaskForIdLocked(candidateTaskId, !RESTORE_FROM_RECENTS,
+                || anyTaskForIdLocked(candidateTaskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
                         INVALID_STACK_ID) != null) {
             candidateTaskId = nextTaskIdForUser(candidateTaskId, userId);
             if (candidateTaskId == currentTaskId) {
@@ -2249,7 +2277,7 @@
         for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
             final int taskId = mResizingTasksDuringAnimation.valueAt(i);
             final TaskRecord task =
-                    anyTaskForIdLocked(taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+                    anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
             if (task != null) {
                 task.setTaskDockedResizing(false);
             }
@@ -2375,19 +2403,19 @@
                 // static stacks need to be adjusted so they don't overlap with the docked stack.
                 // We get the bounds to use from window manager which has been adjusted for any
                 // screen controls and is also the same for all stacks.
-                final Rect tempOtherTaskRect = new Rect();
-                final Rect tempOtherTaskInsetRect = new Rect();
+                final Rect otherTaskRect = new Rect();
                 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
                     final ActivityStack current = getStack(i);
                     if (current != null && StackId.isResizeableByDockedStack(i)) {
-                        current.getStackDockedModeBounds(tempRect, tempOtherTaskRect,
-                                tempOtherTaskInsetRect, true /* ignoreVisibility */);
+                        current.getStackDockedModeBounds(
+                                tempOtherTaskBounds /* currentTempTaskBounds */,
+                                tempRect /* outStackBounds */,
+                                otherTaskRect /* outTempTaskBounds */, true /* ignoreVisibility */);
+
                         resizeStackLocked(i, tempRect,
-                                !tempOtherTaskRect.isEmpty() ? tempOtherTaskRect :
-                                        tempOtherTaskBounds,
-                                !tempOtherTaskInsetRect.isEmpty() ? tempOtherTaskInsetRect :
-                                        tempOtherTaskInsetBounds,
-                                preserveWindows, true /* allowResizeInDockedMode */, deferResume);
+                                !otherTaskRect.isEmpty() ? otherTaskRect : tempOtherTaskBounds,
+                                tempOtherTaskInsetBounds, preserveWindows,
+                                true /* allowResizeInDockedMode */, deferResume);
                     }
                 }
             }
@@ -2493,7 +2521,8 @@
      * @return Returns true if the given task was found and removed.
      */
     boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents) {
-        final TaskRecord tr = anyTaskForIdLocked(taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
+        final TaskRecord tr = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
+                INVALID_STACK_ID);
         if (tr != null) {
             tr.removeTaskActivitiesLocked();
             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
@@ -4784,7 +4813,8 @@
             mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
         }
 
-        task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
+        task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
+                launchStackId);
         if (task == null) {
             continueUpdateBounds(HOME_STACK_ID);
             mWindowManager.executeAppTransition();
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 33889ba..2bbfc21 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1562,9 +1562,14 @@
             // activity. Well that should not be too hard...
             // Note: we must persist the {@link TaskRecord} first as intentActivity could be
             // removed from calling performClearTaskLocked (For example, if it is being brought out
-            // of history or if it is finished immediately), thus disassociating the task.
-            mReuseTask = intentActivity.task;
-            mReuseTask.performClearTaskLocked();
+            // of history or if it is finished immediately), thus disassociating the task. Also note
+            // that mReuseTask is reset as a result of {@link TaskRecord#performClearTaskLocked}
+            // launching another activity.
+            // TODO(b/36119896):  We shouldn't trigger activity launches in this path since we are
+            // already launching one.
+            final TaskRecord task = intentActivity.task;
+            task.performClearTaskLocked();
+            mReuseTask = task;
             mReuseTask.setIntent(mStartActivity);
 
             // When we clear the task - focus will be adjusted, which will bring another task
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 9dde39e..9deabb3 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -55,6 +55,9 @@
 import java.util.List;
 
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
 
 public class TaskPersister {
     static final String TAG = "TaskPersister";
@@ -452,7 +455,8 @@
 
                                 final int taskId = task.taskId;
                                 if (mStackSupervisor.anyTaskForIdLocked(taskId,
-                                        /* restoreFromRecents= */ false, HOME_STACK_ID) != null) {
+                                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS,
+                                        INVALID_STACK_ID) != null) {
                                     // Should not happen.
                                     Slog.wtf(TAG, "Existing task with taskId " + taskId + "found");
                                 } else if (userId != task.userId) {
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index f15543a..cf6c1e1 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -53,6 +53,7 @@
         int change;
         int processState;
         boolean ephemeral;
+        long procStateSeq;
     }
 
     ChangeItem pendingChange;
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index c973911..b316a3b 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -518,7 +518,8 @@
     }
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
-        @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState,
+                long procStateSeq) throws RemoteException {
             updateUidState(uid, procState);
         }
 
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 258fb6d..0a15db6 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -93,6 +93,8 @@
     public int registerCallback(IContextHubCallback callback) throws RemoteException {
         checkPermissions();
         mCallbacksList.register(callback);
+        Log.d(TAG, "Added callback, total callbacks " +
+              mCallbacksList.getRegisteredCallbackCount());
         return 0;
     }
 
@@ -101,6 +103,7 @@
         checkPermissions();
         int[] returnArray = new int[mContextHubInfo.length];
 
+        Log.d(TAG, "System supports " + returnArray.length + " hubs");
         for (int i = 0; i < returnArray.length; ++i) {
             returnArray[i] = i;
             Log.d(TAG, String.format("Hub %s is mapped to %d",
@@ -114,6 +117,7 @@
     public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
         checkPermissions();
         if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
+            Log.e(TAG, "Invalid context hub handle " + contextHubHandle);
             return null; // null means fail
         }
 
@@ -129,6 +133,7 @@
             return -1;
         }
         if (app == null) {
+            Log.e(TAG, "Invalid null app");
             return -1;
         }
 
@@ -158,6 +163,7 @@
         checkPermissions();
         NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
         if (info == null) {
+            Log.e(TAG, "Cannot find app with handle " + nanoAppInstanceHandle);
             return -1; //means failed
         }
 
@@ -171,6 +177,7 @@
         byte msg[] = new byte[0];
 
         if (nativeSendMessage(msgHeader, msg) != 0) {
+            Log.e(TAG, "native send message fails");
             return -1;
         }
 
@@ -187,6 +194,7 @@
         if (mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
             return mNanoAppHash.get(nanoAppInstanceHandle);
         } else {
+            Log.e(TAG, "Could not find nanoApp with handle " + nanoAppInstanceHandle);
             return null;
         }
     }
@@ -209,6 +217,7 @@
             retArray[i] = foundInstances.get(i).intValue();
         }
 
+        Log.w(TAG, "Found " + retArray.length + " apps on hub handle " + hubHandle);
         return retArray;
     }
 
@@ -265,22 +274,26 @@
         if (header == null || data == null || header.length < MSG_HEADER_SIZE) {
             return  -1;
         }
+
         int callbacksCount = mCallbacksList.beginBroadcast();
+        int msgType = header[HEADER_FIELD_MSG_TYPE];
+        int msgVersion = header[HEADER_FIELD_MSG_VERSION];
+        int hubHandle = header[HEADER_FIELD_HUB_HANDLE];
+        int appInstance = header[HEADER_FIELD_APP_INSTANCE];
+
+        Log.d(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle " +
+              hubHandle + ", appInstance " + appInstance + ", callBackCount " + callbacksCount);
+
         if (callbacksCount < 1) {
             Log.v(TAG, "No message callbacks registered.");
             return 0;
         }
 
-        ContextHubMessage msg = new ContextHubMessage(header[HEADER_FIELD_MSG_TYPE],
-                                                      header[HEADER_FIELD_MSG_VERSION],
-                                                      data);
+        ContextHubMessage msg = new ContextHubMessage(msgType, msgVersion, data);
         for (int i = 0; i < callbacksCount; ++i) {
             IContextHubCallback callback = mCallbacksList.getBroadcastItem(i);
             try {
-                callback.onMessageReceipt(
-                        header[HEADER_FIELD_HUB_HANDLE],
-                        header[HEADER_FIELD_APP_INSTANCE],
-                        msg);
+                callback.onMessageReceipt(hubHandle, appInstance, msg);
             } catch (RemoteException e) {
                 Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
                 continue;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 4e9d838..9d93cc7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -719,7 +719,8 @@
     }
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
-        @Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
+        @Override public void onUidStateChanged(int uid, int procState,
+                long procStateSeq) throws RemoteException {
             Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
             try {
                 synchronized (mUidRulesFirstLock) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1aaec1a..8998212 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -476,7 +476,8 @@
 
     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
         @Override
-        public void onUidStateChanged(int uid, int procState) throws RemoteException {
+        public void onUidStateChanged(int uid, int procState, long procStateSeq)
+                throws RemoteException {
             handleOnUidStateChanged(uid, procState);
         }
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4f1754a..8a59726 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -26,7 +26,7 @@
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
-import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.res.Configuration.EMPTY;
@@ -416,6 +416,7 @@
     BurnInProtectionHelper mBurnInProtectionHelper;
     AppOpsManager mAppOpsManager;
     private boolean mHasFeatureWatch;
+    private boolean mHasFeatureLeanback;
 
     // Assigned on main thread, accessed on UI thread
     volatile VrManagerInternal mVrManagerInternal;
@@ -767,6 +768,12 @@
     private boolean mScreenshotChordPowerKeyTriggered;
     private long mScreenshotChordPowerKeyTime;
 
+    private static final long BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS = 1000;
+
+    private boolean mBugreportTvKey1Pressed;
+    private boolean mBugreportTvKey2Pressed;
+    private boolean mBugreportTvScheduled;
+
     /* The number of steps between min and max brightness */
     private static final int BRIGHTNESS_STEPS = 10;
 
@@ -810,6 +817,7 @@
     private static final int MSG_DISPOSE_INPUT_CONSUMER = 19;
     private static final int MSG_BACK_DELAYED_PRESS = 20;
     private static final int MSG_ACCESSIBILITY_SHORTCUT = 21;
+    private static final int MSG_BUGREPORT_TV = 22;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -888,6 +896,9 @@
                 case MSG_ACCESSIBILITY_SHORTCUT:
                     accessibilityShortcutActivated();
                     break;
+                case MSG_BUGREPORT_TV:
+                    takeBugreport();
+                    break;
             }
         }
     }
@@ -1753,6 +1764,7 @@
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
+        mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
         mAccessibilityShortcutController =
                 new AccessibilityShortcutController(mContext, new Handler());
         // Init display burn-in protection
@@ -3482,6 +3494,8 @@
         } else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) {
             // Pass through keyboard navigation keys.
             return 0;
+        } else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) {
+            return -1;
         }
 
         // Toggle Caps Lock on META-ALT.
@@ -3674,6 +3688,45 @@
         return 0;
     }
 
+    /**
+     * TV only: recognizes a remote control gesture for capturing a bug report.
+     */
+    private boolean interceptBugreportGestureTv(int keyCode, boolean down) {
+        // The bugreport capture chord is a long press on DPAD CENTER and BACK simultaneously.
+        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
+            mBugreportTvKey1Pressed = down;
+        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
+            mBugreportTvKey2Pressed = down;
+        }
+
+        if (mBugreportTvKey1Pressed && mBugreportTvKey2Pressed) {
+            if (!mBugreportTvScheduled) {
+                mBugreportTvScheduled = true;
+                Message msg = Message.obtain(mHandler, MSG_BUGREPORT_TV);
+                msg.setAsynchronous(true);
+                mHandler.sendMessageDelayed(msg, BUGREPORT_TV_GESTURE_TIMEOUT_MILLIS);
+            }
+        } else if (mBugreportTvScheduled) {
+            mHandler.removeMessages(MSG_BUGREPORT_TV);
+            mBugreportTvScheduled = false;
+        }
+
+        return mBugreportTvScheduled;
+    }
+
+    private void takeBugreport() {
+        if ("1".equals(SystemProperties.get("ro.debuggable"))
+                || Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) {
+            try {
+                ActivityManager.getService()
+                        .requestBugReport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Error taking bugreport", e);
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
@@ -7083,7 +7136,7 @@
             @Override public void run() {
                 if (mBootMsgDialog == null) {
                     int theme;
-                    if (mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)) {
+                    if (mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK)) {
                         theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert;
                     } else {
                         theme = 0;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c58b527..24f6f89 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -72,6 +72,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
+import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.EventLogTags;
@@ -194,6 +195,7 @@
     private final Context mContext;
     private final ServiceThread mHandlerThread;
     private final PowerManagerHandler mHandler;
+    private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
     private final BatterySaverPolicy mBatterySaverPolicy;
 
     private LightsManager mLightsManager;
@@ -516,6 +518,9 @@
     // True if theater mode is enabled
     private boolean mTheaterModeEnabled;
 
+    // True if always on display is enabled
+    private boolean mAlwaysOnEnabled;
+
     // True if double tap to wake is enabled
     private boolean mDoubleTapWakeEnabled;
 
@@ -608,6 +613,7 @@
         mHandlerThread.start();
         mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
         mConstants = new Constants(mHandler);
+        mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
         mBatterySaverPolicy = new BatterySaverPolicy(mHandler);
 
         synchronized (mLock) {
@@ -640,6 +646,7 @@
         mHandlerThread.start();
         mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
         mConstants = new Constants(mHandler);
+        mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
         mDisplaySuspendBlocker = null;
         mWakeLockSuspendBlocker = null;
     }
@@ -766,6 +773,9 @@
                 Settings.Global.THEATER_MODE_ON),
                 false, mSettingsObserver, UserHandle.USER_ALL);
         resolver.registerContentObserver(Settings.Secure.getUriFor(
+                Settings.Secure.DOZE_ALWAYS_ON),
+                false, mSettingsObserver, UserHandle.USER_ALL);
+        resolver.registerContentObserver(Settings.Secure.getUriFor(
                 Settings.Secure.DOUBLE_TAP_TO_WAKE),
                 false, mSettingsObserver, UserHandle.USER_ALL);
         IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
@@ -863,6 +873,7 @@
                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
         mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.THEATER_MODE_ON, 0) == 1;
+        mAlwaysOnEnabled = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
 
         if (mSupportsDoubleTapWakeConfig) {
             boolean doubleTapWakeEnabled = Settings.Secure.getIntForUser(resolver,
@@ -1702,6 +1713,11 @@
             return false;
         }
 
+        // On Always On Display, SystemUI shows the charging indicator
+        if (mAlwaysOnEnabled && mWakefulness == WAKEFULNESS_DOZING) {
+            return false;
+        }
+
         // Otherwise wake up!
         return true;
     }
diff --git a/services/core/java/com/android/server/storage/AppCollector.java b/services/core/java/com/android/server/storage/AppCollector.java
index 25880fb..a77d33f 100644
--- a/services/core/java/com/android/server/storage/AppCollector.java
+++ b/services/core/java/com/android/server/storage/AppCollector.java
@@ -116,33 +116,33 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_START_LOADING_SIZES: {
-                    final List<ApplicationInfo> apps = mPm.getInstalledApplications(
-                            PackageManager.GET_UNINSTALLED_PACKAGES
-                                    | PackageManager.GET_DISABLED_COMPONENTS);
-
-                    final List<ApplicationInfo> volumeApps = new ArrayList<>();
-                    for (ApplicationInfo app : apps) {
-                        if (Objects.equals(app.volumeUuid, mVolume.getFsUuid())) {
-                            volumeApps.add(app);
-                        }
-                    }
-
-                    List<UserInfo> users = mUm.getUsers();
-                    final int count = users.size() * volumeApps.size();
-                    if (count == 0) {
-                        mStats.complete(new ArrayList<>());
-                    }
-
                     List<PackageStats> stats = new ArrayList<>();
-                    for (UserInfo user : users) {
-                        for (ApplicationInfo app : volumeApps) {
-                            PackageStats packageStats = new PackageStats(app.packageName, user.id);
-                            StorageStats storageStats = mStorageStatsManager.queryStatsForPackage(
-                                    app.volumeUuid, app.packageName, user.getUserHandle());
-                            packageStats.cacheSize = storageStats.getCacheBytes();
-                            packageStats.codeSize = storageStats.getCodeBytes();
-                            packageStats.dataSize = storageStats.getDataBytes();
-                            stats.add(packageStats);
+                    List<UserInfo> users = mUm.getUsers();
+                    for (int userCount = 0, userSize = users.size();
+                            userCount < userSize; userCount++) {
+                        UserInfo user = users.get(userCount);
+                        final List<ApplicationInfo> apps = mPm.getInstalledApplicationsAsUser(
+                                PackageManager.MATCH_DISABLED_COMPONENTS, user.id);
+
+                        for (int appCount = 0, size = apps.size(); appCount < size; appCount++) {
+                            ApplicationInfo app = apps.get(appCount);
+                            if (!Objects.equals(app.volumeUuid, mVolume.getFsUuid())) {
+                                continue;
+                            }
+
+                            try {
+                                StorageStats storageStats =
+                                        mStorageStatsManager.queryStatsForPackage(app.volumeUuid,
+                                                app.packageName, user.getUserHandle());
+                                PackageStats packageStats = new PackageStats(app.packageName,
+                                        user.id);
+                                packageStats.cacheSize = storageStats.getCacheBytes();
+                                packageStats.codeSize = storageStats.getCodeBytes();
+                                packageStats.dataSize = storageStats.getDataBytes();
+                                stats.add(packageStats);
+                            } catch (IllegalStateException e) {
+                                Log.e(TAG, "An exception occurred while fetching app size", e);
+                            }
                         }
                     }
 
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
index c54fd9a..5e17daa 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
@@ -156,7 +156,7 @@
 
             mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display", WIDTH, HEIGHT,
                     DPI, null /* Surface */, 0 /* flags */);
-            if (mSurface != null && mSurface.isValid()) {
+            if (mVirtualDisplay != null && mSurface != null && mSurface.isValid()) {
               // TODO: Need to protect all setSurface calls with a lock.
               mVirtualDisplay.setSurface(mSurface);
             }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 83e77ec..9e95eec 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -625,26 +625,52 @@
             return v1 >= v2;
         }
 
-        /**
-         * Returns whether this provider is valid for use as a WebView provider.
-         */
-        public boolean isValidProvider(WebViewProviderInfo configInfo,
-                PackageInfo packageInfo) {
+        private final static int VALIDITY_OK = 0;
+        private final static int VALIDITY_INCORRECT_SDK_VERSION = 1;
+        private final static int VALIDITY_INCORRECT_VERSION_CODE = 2;
+        private final static int VALIDITY_INCORRECT_SIGNATURE = 3;
+        private final static int VALIDITY_NO_LIBRARY_FLAG = 4;
+
+        private static String getInvalidityReason(int invalidityReason) {
+            switch (invalidityReason) {
+                case VALIDITY_INCORRECT_SDK_VERSION:
+                    return "SDK version too low";
+                case VALIDITY_INCORRECT_VERSION_CODE:
+                    return "Version code too low";
+                case VALIDITY_INCORRECT_SIGNATURE:
+                    return "Incorrect signature";
+                case VALIDITY_NO_LIBRARY_FLAG:
+                    return "No WebView-library manifest flag";
+                default:
+                    return "Unexcepted validity-reason";
+            }
+        }
+
+        private int validityResult(WebViewProviderInfo configInfo, PackageInfo packageInfo) {
             // Ensure the provider targets this framework release (or a later one).
             if (!UserPackage.hasCorrectTargetSdkVersion(packageInfo)) {
-                return false;
+                return VALIDITY_INCORRECT_SDK_VERSION;
             }
             if (!versionCodeGE(packageInfo.versionCode, getMinimumVersionCode())
                     && !mSystemInterface.systemIsDebuggable()) {
                 // Webview providers may be downgraded arbitrarily low, prevent that by enforcing
                 // minimum version code. This check is only enforced for user builds.
-                return false;
+                return VALIDITY_INCORRECT_VERSION_CODE;
             }
-            if (providerHasValidSignature(configInfo, packageInfo, mSystemInterface) &&
-                    WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) {
-                return true;
+            if (!providerHasValidSignature(configInfo, packageInfo, mSystemInterface)) {
+                return VALIDITY_INCORRECT_SIGNATURE;
             }
-            return false;
+            if (WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) == null) {
+                return VALIDITY_NO_LIBRARY_FLAG;
+            }
+            return VALIDITY_OK;
+        }
+
+        /**
+         * Returns whether this provider is valid for use as a WebView provider.
+         */
+        public boolean isValidProvider(WebViewProviderInfo configInfo, PackageInfo packageInfo) {
+            return VALIDITY_OK == validityResult(configInfo, packageInfo);
         }
 
         /**
@@ -699,6 +725,53 @@
                 pw.println(String.format("  WebView package dirty: %b", mWebViewPackageDirty));
                 pw.println(String.format("  Any WebView package installed: %b",
                         mAnyWebViewInstalled));
+
+                try {
+                    PackageInfo preferredWebViewPackage = findPreferredWebViewPackage();
+                    pw.println(String.format(
+                            "  Preferred WebView package (name, version): (%s, %s)",
+                            preferredWebViewPackage.packageName,
+                            preferredWebViewPackage.versionName));
+                } catch (WebViewPackageMissingException e) {
+                    pw.println(String.format("  Preferred WebView package: none"));
+                }
+
+                dumpAllPackageInformationLocked(pw);
+            }
+        }
+
+        private void dumpAllPackageInformationLocked(PrintWriter pw) {
+            WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
+            pw.println("  WebView packages:");
+            for (WebViewProviderInfo provider : allProviders) {
+                List<UserPackage> userPackages =
+                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider);
+                PackageInfo systemUserPackageInfo =
+                        userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo();
+                if (systemUserPackageInfo == null) {
+                    continue;
+                }
+
+                int validity = validityResult(provider, systemUserPackageInfo);
+                String packageDetails = String.format(
+                        "versionName: %s, versionCode: %d, targetSdkVersion: %d",
+                        systemUserPackageInfo.versionName,
+                        systemUserPackageInfo.versionCode,
+                        systemUserPackageInfo.applicationInfo.targetSdkVersion);
+                if (validity == VALIDITY_OK) {
+                    boolean installedForAllUsers = isInstalledAndEnabledForAllUsers(
+                            mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider));
+                    pw.println(String.format(
+                            "    Valid package %s (%s) is %s installed/enabled for all users",
+                            systemUserPackageInfo.packageName,
+                            packageDetails,
+                            installedForAllUsers ? "" : "NOT"));
+                } else {
+                    pw.println(String.format("    Invalid package %s (%s), reason: %s",
+                            systemUserPackageInfo.packageName,
+                            packageDetails,
+                            getInvalidityReason(validity)));
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index b7b419b..efc92cf 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -19,9 +19,9 @@
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
 import static android.content.Context.NOTIFICATION_SERVICE;
-import static android.content.Intent.EXTRA_PACKAGE_NAME;
-import static android.content.Intent.EXTRA_UID;
-import static com.android.server.wm.WindowManagerService.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;
 
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -35,6 +35,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 
+import android.net.Uri;
 import com.android.internal.R;
 import com.android.server.policy.IconUtilities;
 
@@ -49,14 +50,12 @@
     private String mNotificationTag;
     private final NotificationManager mNotificationManager;
     private final String mPackageName;
-    private final int mUid;
     private boolean mCancelled;
     private IconUtilities mIconUtilities;
 
-    AlertWindowNotification(WindowManagerService service, String packageName, int uid) {
+    AlertWindowNotification(WindowManagerService service, String packageName) {
         mService = service;
         mPackageName = packageName;
-        mUid = uid;
         mNotificationManager =
                 (NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
         mNotificationTag = CHANNEL_PREFIX + mPackageName;
@@ -96,7 +95,8 @@
 
         createNotificationChannelIfNeeded(context, appName);
 
-        final String message = context.getString(R.string.alert_windows_notification_message);
+        final String message = context.getString(R.string.alert_windows_notification_message,
+                appName);
         final Notification.Builder builder = new Notification.Builder(context, mNotificationTag)
                 .setOngoing(true)
                 .setContentTitle(
@@ -106,7 +106,7 @@
                 .setColor(context.getColor(R.color.system_notification_accent_color))
                 .setStyle(new Notification.BigTextStyle().bigText(message))
                 .setLocalOnly(true)
-                .addAction(getTurnOffAction(context, mPackageName, mUid));
+                .setContentIntent(getContentIntent(context, mPackageName));
 
         if (aInfo != null) {
             final Drawable drawable = pm.getApplicationIcon(aInfo);
@@ -119,17 +119,12 @@
         mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
     }
 
-    private Notification.Action getTurnOffAction(Context context, String packageName, int uid) {
-        final Intent intent = new Intent(ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION);
-        intent.putExtra(EXTRA_PACKAGE_NAME, packageName);
-        intent.putExtra(EXTRA_UID, uid);
+    private PendingIntent getContentIntent(Context context, String packageName) {
+        final Intent intent = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION,
+                Uri.fromParts("package", packageName, null));
+        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
         // Calls into activity manager...
-        final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, mRequestCode,
-                intent, FLAG_CANCEL_CURRENT);
-        return new Notification.Action.Builder(R.drawable.alert_window_layer,
-                context.getString(R.string.alert_windows_notification_turn_off_action),
-                pendingIntent).build();
-
+        return PendingIntent.getActivity(context, mRequestCode, intent, FLAG_CANCEL_CURRENT);
     }
 
     private void createNotificationChannelIfNeeded(Context context, String appName) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 647adbf..4aa013a 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -785,6 +785,16 @@
         if (canFreezeBounds()) {
             freezeBounds();
         }
+
+        // In the process of tearing down before relaunching, the app will
+        // try and clean up it's child surfaces. We need to prevent this from
+        // happening, so we sever the children, transfering their ownership
+        // from the client it-self to the parent surface (owned by us).
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = mChildren.get(i);
+            w.mWinAnimator.detachChildren();
+        }
+
         mPendingRelaunchCount++;
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 461c3fa..5486aa8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1584,24 +1584,9 @@
         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
         // same display. Or even when the current IME/target are not on the same screen as the next
         // IME/target. For now only look for input windows on the main screen.
+        mUpdateImeTarget = updateImeTarget;
+        WindowState target = getWindow(mComputeImeTargetPredicate);
 
-        // The target candidate provided by the IME tells us which window token, but not which
-        // window within the token (e.g. child windows...). So, we use the token to look-up the
-        // best target window.
-        // TODO: Have the input method service report the right window with the token vs. just the
-        // base window of the token.
-        final WindowState baseWin = mService.getWindow(mService.mInputMethodTargetCandidate);
-        final WindowToken targetToken = baseWin != null ? baseWin.mToken : null;
-        WindowState target = targetToken != null ?
-                targetToken.getWindow(mComputeImeTargetPredicate) : null;
-        // If there isn't a better candidate in the token (maybe because they are not visible), then
-        // fall back to targeting the base window of the token, so the IME can still maintain the
-        // right z-order based on the last person that set it vs. changing its z-order to the very
-        // up since there if target is null.
-        // TODO: Consider z-ordering IME to bottom instead of top if there is no visible target.
-        // Also, consider tying the visible the visibility of the IME to the current target. I.e if
-        // target isn't visible, then IME shouldn't be visible.
-        target = target == null ? baseWin : target;
 
         // Yet more tricksyness!  If this window is a "starting" window, we do actually want
         // to be on top of it, but it is not -really- where input will go. So look down below
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index aa8e377..fc37797 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -109,7 +109,6 @@
     private final Rect mTmpRect2 = new Rect();
     private final Rect mTmpRect3 = new Rect();
     private final Rect mLastRect = new Rect();
-    private final Rect mMiddlePositionDockedStackRect = new Rect();
     private boolean mLastVisibility = false;
     private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
             = new RemoteCallbackList<>();
@@ -186,16 +185,6 @@
         return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
     }
 
-    /**
-     * The middlePositionDockedStackRect is half the screen area that sits at the top (portrait) or
-     * left (landscape).
-     *
-     * @return fixed rect for temp stack
-     */
-    Rect getMiddlePositionDockedStackRect() {
-        return mMinimizedDock && isHomeStackResizable() ? mMiddlePositionDockedStackRect : null;
-    }
-
     void getHomeStackBoundsInDockedMode(Rect outBounds) {
         final DisplayInfo di = mDisplayContent.getDisplayInfo();
         mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
@@ -264,29 +253,8 @@
         initSnapAlgorithmForRotations();
     }
 
-    /**
-     * Calculates the constant rects {@link mMiddlePositionDockedStackRect} based on orientation,
-     * stable insets and display size.
-     */
-    private void updateConstantRects() {
-        final DisplayInfo di = mDisplayContent.getDisplayInfo();
-        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
-                mTmpRect);
-        int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
-        Configuration configuration = mDisplayContent.getConfiguration();
-        boolean isHorizontal = configuration.orientation == Configuration.ORIENTATION_PORTRAIT;
-        int middlePosition = DockedDividerUtils.calculateMiddlePosition(isHorizontal, mTmpRect,
-                di.logicalWidth, di.logicalHeight, dividerSize);
-        if (isHorizontal) {
-            mMiddlePositionDockedStackRect.set(0, 0, di.logicalWidth, middlePosition);
-        } else {
-            mMiddlePositionDockedStackRect.set(0, 0, middlePosition, di.logicalHeight);
-        }
-    }
-
     void onConfigurationChanged() {
         loadDimens();
-        updateConstantRects();
     }
 
     boolean isResizing() {
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 1d50d0d..0e6b1b6 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -108,6 +108,7 @@
     private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
     private final Rect mTmpInsets = new Rect();
     private final Rect mTmpRect = new Rect();
+    private final Rect mTmpAnimatingBoundsRect = new Rect();
     private final Point mTmpDisplaySize = new Point();
 
     /**
@@ -359,7 +360,7 @@
                 if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
                     transformBoundsToAspectRatio(normalBounds, mAspectRatio);
                 }
-                final Rect animatingBounds = mTmpRect;
+                final Rect animatingBounds = mTmpAnimatingBoundsRect;
                 final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
                 if (pinnedStack != null) {
                     pinnedStack.getAnimatingBounds(animatingBounds);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 720a454..b7a9e66 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -601,8 +601,7 @@
                 if (mAlertWindowSurfaces.isEmpty()) {
                     cancelAlertWindowNotification();
                 } else if (mAlertWindowNotification == null){
-                    mAlertWindowNotification = new AlertWindowNotification(
-                            mService, mPackageName, mUid);
+                    mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index b0e115b..8186d30 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -199,17 +199,19 @@
         }
     }
 
-    public void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds,
-            Rect outTempInsetBounds, boolean ignoreVisibility) {
+    /**
+     * @see TaskStack.getStackDockedModeBoundsLocked(Rect, Rect, Rect, boolean)
+     */
+   public void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
+           Rect outTempTaskBounds, boolean ignoreVisibility) {
         synchronized (mWindowMap) {
             if (mContainer != null) {
-                mContainer.getStackDockedModeBoundsLocked(outBounds, outTempBounds,
-                        outTempInsetBounds, ignoreVisibility);
+                mContainer.getStackDockedModeBoundsLocked(currentTempTaskBounds, outStackBounds,
+                        outTempTaskBounds, ignoreVisibility);
                 return;
             }
-            outBounds.setEmpty();
-            outTempBounds.setEmpty();
-            outTempInsetBounds.setEmpty();
+            outStackBounds.setEmpty();
+            outTempTaskBounds.setEmpty();
         }
     }
 
@@ -241,9 +243,9 @@
         }
     }
 
-    public void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
+    public void getBoundsForNewConfiguration(Rect outBounds) {
         synchronized(mWindowMap) {
-            mContainer.getBoundsForNewConfiguration(outBounds, outTempBounds);
+            mContainer.getBoundsForNewConfiguration(outBounds);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 9f34bd7..76fb522 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -151,21 +151,7 @@
     }
 
     private void drawSnapshot(GraphicBuffer snapshot) {
-
-        // TODO: Just wrap the buffer here without any copying.
-        final Canvas c = mSurface.lockHardwareCanvas();
-        final Bitmap b = Bitmap.createHardwareBitmap(snapshot);
-        fillEmptyBackground(c, b);
-        c.drawBitmap(b, 0, 0, null);
-        mSurface.unlockCanvasAndPost(c);
-        final boolean reportNextDraw;
-        synchronized (mService.mWindowMap) {
-            mHasDrawn = true;
-            reportNextDraw = mReportNextDraw;
-        }
-        if (reportNextDraw) {
-            reportDrawn();
-        }
+        mSurface.attachAndQueueBuffer(snapshot);
         mSurface.release();
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 7588b71..442cd54 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -429,18 +429,9 @@
         return true;
     }
 
-    void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
+    void getBoundsForNewConfiguration(Rect outBounds) {
         outBounds.set(mBoundsAfterRotation);
         mBoundsAfterRotation.setEmpty();
-        final DockedStackDividerController controller = getDisplayContent()
-                .mDividerControllerLocked;
-        if (mStackId == DOCKED_STACK_ID) {
-            final Rect dockedStackRect = controller.getMiddlePositionDockedStackRect();
-
-            if (dockedStackRect != null) {
-                outTempBounds.set(dockedStackRect);
-            }
-        }
     }
 
     /**
@@ -686,21 +677,42 @@
         super.onDisplayChanged(dc);
     }
 
-    void getStackDockedModeBoundsLocked(Rect outBounds, Rect outTempBounds,
-            Rect outTempInsetBounds, boolean ignoreVisibility) {
+    /**
+     * Determines the stack and task bounds of the other stack when in docked mode. The current task
+     * bounds is passed in but depending on the stack, the task and stack must match. Only in
+     * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
+     * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
+     * is calculated and is also used for its task bounds.
+     * If any of the out bounds are empty, it represents default bounds
+     *
+     * @param currentTempTaskBounds the current task bounds of the other stack
+     * @param outStackBounds the calculated stack bounds of the other stack
+     * @param outTempTaskBounds the calculated task bounds of the other stack
+     * @param ignoreVisibility ignore visibility in getting the stack bounds
+     */
+    void getStackDockedModeBoundsLocked(Rect currentTempTaskBounds, Rect outStackBounds,
+            Rect outTempTaskBounds, boolean ignoreVisibility) {
+        outTempTaskBounds.setEmpty();
+
+        // When the home stack is resizable, should always have the same stack and task bounds
         if (mStackId == HOME_STACK_ID && findHomeTask().isResizeable()) {
             // Calculate the home stack bounds when in docked mode
             getDisplayContent().mDividerControllerLocked
-                    .getHomeStackBoundsInDockedMode(outTempBounds);
-            outTempInsetBounds.set(outTempBounds);
-        } else {
-            outTempBounds.setEmpty();
-            outTempInsetBounds.setEmpty();
+                    .getHomeStackBoundsInDockedMode(outStackBounds);
+            outTempTaskBounds.set(outStackBounds);
+            return;
+        }
+
+        // When minimized state, the stack bounds for all non-home and docked stack bounds should
+        // match the passed task bounds
+        if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
+            outStackBounds.set(currentTempTaskBounds);
+            return;
         }
 
         if ((mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId))
                 || mDisplayContent == null) {
-            outBounds.set(mBounds);
+            outStackBounds.set(mBounds);
             return;
         }
 
@@ -714,7 +726,7 @@
             // The docked stack is being dismissed, but we caught before it finished being
             // dismissed. In that case we want to treat it as if it is not occupying any space and
             // let others occupy the whole display.
-            mDisplayContent.getLogicalDisplayRect(outBounds);
+            mDisplayContent.getLogicalDisplayRect(outStackBounds);
             return;
         }
 
@@ -722,14 +734,14 @@
         if (dockedSide == DOCKED_INVALID) {
             // Not sure how you got here...Only thing we can do is return current bounds.
             Slog.e(TAG_WM, "Failed to get valid docked side for docked stack=" + dockedStack);
-            outBounds.set(mBounds);
+            outStackBounds.set(mBounds);
             return;
         }
 
         mDisplayContent.getLogicalDisplayRect(mTmpRect);
         dockedStack.getRawBounds(mTmpRect2);
         final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
-        getStackDockedModeBounds(mTmpRect, outBounds, mStackId, mTmpRect2,
+        getStackDockedModeBounds(mTmpRect, outStackBounds, mStackId, mTmpRect2,
                 mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
 
     }
@@ -812,8 +824,8 @@
 
         final Rect bounds = new Rect();
         final Rect tempBounds = new Rect();
-        final Rect tempInsetBounds = new Rect();
-        getStackDockedModeBoundsLocked(bounds, tempBounds, tempInsetBounds, true /*ignoreVisibility*/);
+        getStackDockedModeBoundsLocked(null /* currentTempTaskBounds */, bounds, tempBounds,
+                true /*ignoreVisibility*/);
         getController().requestResize(bounds);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8b859d1..c0cc923 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
@@ -29,6 +30,7 @@
 import static android.content.Intent.EXTRA_UID;
 import static android.content.Intent.EXTRA_USER_HANDLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.UserHandle.USER_NULL;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -67,6 +69,8 @@
 import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -108,6 +112,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -346,9 +351,6 @@
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
 
-    static final String ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION =
-            "com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION";
-
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -364,16 +366,6 @@
                         }
                     }
                     break;
-                case ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION:
-                    final String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
-                    final int uid = intent.getIntExtra(EXTRA_UID, -1);
-                    if (packageName != null && uid != -1) {
-                        synchronized (mWindowMap) {
-                            // Revoke permission.
-                            mAppOps.setMode(OP_SYSTEM_ALERT_WINDOW, uid, packageName, MODE_IGNORED);
-                        }
-                    }
-                    break;
             }
         }
     };
@@ -623,14 +615,9 @@
     WindowState mCurrentFocus = null;
     WindowState mLastFocus = null;
 
-    // TODO: All the IME window tracking should be moved to DisplayContent and tracked per display.
-    // This just indicates the window the input method is on top of, not necessarily the window its
-    // input is going to.
+    /** This just indicates the window the input method is on top of, not
+     * necessarily the window its input is going to. */
     WindowState mInputMethodTarget = null;
-    // The binder token currently using the IME as determined by the input method service.
-    // Window manager uses this to determine the final input method target
-    // (almost always this candidate) for z-ordering.
-    IBinder mInputMethodTargetCandidate = null;
 
     /** If true hold off on modifying the animation layer of mInputMethodTarget */
     boolean mInputMethodTargetWaitingAnim;
@@ -1070,7 +1057,6 @@
         filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         // Listen to user removal broadcasts so that we can remove the user-specific data.
         filter.addAction(Intent.ACTION_USER_REMOVED);
-        filter.addAction(ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION);
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
         mSettingsObserver = new SettingsObserver();
@@ -2212,6 +2198,15 @@
         if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
             mAccessibilityController.onWindowTransitionLocked(win, transit);
         }
+
+        // When we start the exit animation we take the Surface from the client
+        // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger
+        // side child surfaces, so they will remain preserved in their current state
+        // (rather than be cleaned up immediately by the app code).
+        SurfaceControl.openTransaction();
+        winAnimator.detachChildren();
+        SurfaceControl.closeTransaction();
+
         return focusMayChange;
     }
 
@@ -6964,9 +6959,8 @@
             pw.print("  mLastFocus="); pw.println(mLastFocus);
         }
         pw.print("  mFocusedApp="); pw.println(mFocusedApp);
-        if (mInputMethodTarget != null || mInputMethodTargetCandidate != null) {
-            pw.println("  mInputMethodTarget=" + mInputMethodTarget
-                    + " mInputMethodTargetCandidate=" + getWindow(mInputMethodTargetCandidate));
+        if (mInputMethodTarget != null) {
+            pw.print("  mInputMethodTarget="); pw.println(mInputMethodTarget);
         }
         pw.print("  mInTouchMode="); pw.print(mInTouchMode);
                 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
@@ -7833,28 +7827,11 @@
         @Override
         public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
                 boolean imeWindowVisible, @Nullable IBinder targetWindowToken) {
-            synchronized (mWindowMap) {
-                final WindowState newTargetWin = getWindow(targetWindowToken);
-                final WindowState currentTargetWin = getWindow(mInputMethodTargetCandidate);
-
-                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken="
-                        + imeToken + " imeWindowVisible=" + imeWindowVisible
-                        + " targetWindowToken=" + targetWindowToken
-                        + " newTargetWin=" + newTargetWin
-                        + " currentTargetWin=" + currentTargetWin);
-
-                if (newTargetWin == currentTargetWin) {
-                    return;
-                }
-
-                final DisplayContent dc = newTargetWin != null
-                        ? newTargetWin.getDisplayContent() : currentTargetWin.getDisplayContent();
-
-                // It is possible the window for the target candidate isn't added yet, so we
-                // remember the token instead and use it to look-up the window each time we compute
-                // the ime target.
-                mInputMethodTargetCandidate = targetWindowToken;
-                dc.computeImeTarget(true /* updateImeTarget */);
+            // TODO (b/34628091): Use this method to address the window animation issue.
+            if (DEBUG_INPUT_METHOD) {
+                Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken
+                        + " imeWindowVisible=" + imeWindowVisible
+                        + " targetWindowToken=" + targetWindowToken);
             }
         }
 
@@ -7900,10 +7877,6 @@
         }
     }
 
-    WindowState getWindow(IBinder binder) {
-        return binder == null ? null : mWindowMap.get(binder);
-    }
-
     void registerAppFreezeListener(AppFreezeListener listener) {
         if (!mAppFreezeListeners.contains(listener)) {
             mAppFreezeListeners.add(listener);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6d572d7..7825903 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -74,7 +74,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
@@ -82,7 +81,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -1532,6 +1530,13 @@
             return changed;
         }
 
+        // Next up we will notify the client that it's visibility has changed.
+        // We need to prevent it from destroying child surfaces until
+        // the animation has finished.
+        if (!visible && isVisibleNow()) {
+            mWinAnimator.detachChildren();
+        }
+
         if (visible != isVisibleNow()) {
             if (!runningAppAnimation) {
                 final AccessibilityController accessibilityController =
@@ -3832,6 +3837,8 @@
         windowInfo.title = mAttrs.accessibilityTitle;
         windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
         windowInfo.focused = isFocused();
+        Task task = getTask();
+        windowInfo.inPictureInPicture = (task != null) && task.inPinnedWorkspace();
 
         if (mIsChildWindow) {
             windowInfo.parentToken = getParentWindow().mClient.asBinder();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 98598e1..4b71338 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -566,6 +566,20 @@
         if (!mDestroyPreservedSurfaceUponRedraw) {
             return;
         }
+        if (mSurfaceController != null) {
+            if (mPendingDestroySurface != null) {
+                // If we are preserving a surface but we aren't relaunching that means
+                // we are just doing an in-place switch. In that case any SurfaceFlinger side
+                // child layers need to be reparented to the new surface to make this
+                // transparent to the app.
+                if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
+                    SurfaceControl.openTransaction();
+                    mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
+                    SurfaceControl.closeTransaction();
+                }
+            }
+        }
+
         destroyDeferredSurfaceLocked();
         mDestroyPreservedSurfaceUponRedraw = false;
     }
@@ -1965,4 +1979,10 @@
         }
         return mForceScaleUntilResize;
     }
+
+    void detachChildren() {
+        if (mSurfaceController != null) {
+            mSurfaceController.detachChildren();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f8e7428..f7d3343 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -135,6 +135,20 @@
         }
     }
 
+    void reparentChildrenInTransaction(WindowSurfaceController other) {
+        if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
+        if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
+            mSurfaceControl.reparentChildren(other.getHandle());
+        }
+    }
+
+    void detachChildren() {
+        if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
+        if (mSurfaceControl != null) {
+            mSurfaceControl.detachChildren();
+        }
+    }
+
     void hideInTransaction(String reason) {
         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
         mHiddenForOtherReasons = true;
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
index ad64e4e..e6e2cb3 100644
--- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -141,7 +141,7 @@
     }
 
     private ServiceConnection getServiceConnection(
-            final AssociationRequest<?> request,
+            final AssociationRequest request,
             final IFindDeviceCallback findDeviceCallback,
             final String callingPackage) {
         return new ServiceConnection() {
diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk
index bc37fef..de9553a 100644
--- a/services/tests/notification/Android.mk
+++ b/services/tests/notification/Android.mk
@@ -27,6 +27,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
+LOCAL_JACK_FLAGS := --multi-dex native
+
 LOCAL_PACKAGE_NAME := FrameworksNotificationTests
 
 LOCAL_CERTIFICATE := platform
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 3f34d4f..a9b2ae5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -594,19 +594,19 @@
     @Test
     public void testUidForeground() throws Exception {
         // push all uids into background
-        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE);
-        mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE);
+        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
+        mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
         assertFalse(mService.isUidForeground(UID_A));
         assertFalse(mService.isUidForeground(UID_B));
 
         // push one of the uids into foreground
-        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP);
+        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
         assertTrue(mService.isUidForeground(UID_A));
         assertFalse(mService.isUidForeground(UID_B));
 
         // and swap another uid into foreground
-        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE);
-        mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP);
+        mUidObserver.onUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
+        mUidObserver.onUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
         assertFalse(mService.isUidForeground(UID_A));
         assertTrue(mService.isUidForeground(UID_B));
     }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 38c6b0d..6cca771 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -314,8 +314,8 @@
         final Bundle bundle = new Bundle();
         bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
         doAnswer(invocation -> {
-            bundle.putInt(EXTRA_SEQUENCE, invocation.getArgumentAt(2, int.class));
-            invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
+            bundle.putInt(EXTRA_SEQUENCE, invocation.getArgument(2));
+            invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
             return null;
         }).when(mRecommendationProvider)
                 .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
@@ -379,7 +379,7 @@
         injectProvider();
         final Bundle bundle = new Bundle();
         doAnswer(invocation -> {
-            invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
+            invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
             return null;
         }).when(mRecommendationProvider)
                 .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
@@ -956,7 +956,7 @@
                 IBinder mockBinder = mock(IBinder.class);
                 when(mockBinder.queryLocalInterface(anyString()))
                         .thenReturn(mRecommendationProvider);
-                invocation.getArgumentAt(1, ServiceConnection.class)
+                invocation.<ServiceConnection>getArgument(1)
                         .onServiceConnected(NEW_SCORER.getRecommendationServiceComponent(),
                                 mockBinder);
                 return true;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index 64f176a..e8663a2 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -50,10 +50,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -77,7 +77,7 @@
         when(mMockContext.getPackageManager()).thenReturn(mMockPm);
         when(mMockPm.queryIntentServices(Mockito.argThat(new ArgumentMatcher<Intent>() {
             @Override
-            public boolean matches(Object object) {
+            public boolean matchesObject(Object object) {
                 Intent intent = (Intent) object;
                 return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS.equals(intent.getAction());
             }
@@ -395,7 +395,7 @@
         when(mMockPm.resolveService(
                 Mockito.argThat(new ArgumentMatcher<Intent>() {
                     @Override
-                    public boolean matches(Object object) {
+                    public boolean matchesObject(Object object) {
                         Intent intent = (Intent) object;
                         return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS
                                 .equals(intent.getAction())
@@ -416,7 +416,7 @@
         when(mMockPm.resolveActivity(
                 Mockito.argThat(new ArgumentMatcher<Intent>() {
                     @Override
-                    public boolean matches(Object object) {
+                    public boolean matchesObject(Object object) {
                         Intent intent = (Intent) object;
                         return NetworkScoreManager.ACTION_CUSTOM_ENABLE.equals(intent.getAction())
                                 && useOpenWifiComp.getPackageName().equals(intent.getPackage());
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
new file mode 100644
index 0000000..8afe853
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ActionReplacingCallbackTest.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility;
+
+import android.graphics.Region;
+import android.os.RemoteException;
+import android.view.MagnificationSpec;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction.ACTION_CONTEXT_CLICK;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+/**
+ * Tests for ActionReplacingCallback
+ */
+public class ActionReplacingCallbackTest {
+    private static final int INTERACTION_ID = 0xBEEF;
+    private static final int INTERROGATING_PID = 0xFEED;
+    private static final int APP_WINDOW_ID = 0xACE;
+    private static final int NON_ROOT_NODE_ID = 0xAAAA5555;
+    private static final long INTERROGATING_TID = 0x1234FACE;
+
+    private static final AccessibilityAction[] ACTIONS_FROM_REPLACER =
+            {ACTION_CLICK, ACTION_EXPAND};
+    private static final AccessibilityAction[] A11Y_FOCUS_ACTIONS =
+            {ACTION_ACCESSIBILITY_FOCUS, ACTION_CLEAR_ACCESSIBILITY_FOCUS};
+    // We expect both the replacer actions and a11y focus actions to appear
+    private static final AccessibilityAction[] REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE =
+            {ACTION_CLICK, ACTION_EXPAND, ACTION_ACCESSIBILITY_FOCUS,
+                    ACTION_CLEAR_ACCESSIBILITY_FOCUS};
+
+    @Mock IAccessibilityInteractionConnectionCallback mMockServiceCallback;
+    @Mock IAccessibilityInteractionConnection mMockReplacerConnection;
+
+    @Captor private ArgumentCaptor<Integer> mInteractionIdCaptor;
+    @Captor private ArgumentCaptor<AccessibilityNodeInfo> mInfoCaptor;
+    @Captor private ArgumentCaptor<List<AccessibilityNodeInfo>> mInfoListCaptor;
+
+    private ActionReplacingCallback mActionReplacingCallback;
+    private int mReplacerInteractionId;
+
+    @Before
+    public void setUp() throws RemoteException {
+        initMocks(this);
+        mActionReplacingCallback = new ActionReplacingCallback(
+                mMockServiceCallback, mMockReplacerConnection, INTERACTION_ID, INTERROGATING_PID,
+                INTERROGATING_TID);
+        verify(mMockReplacerConnection).findAccessibilityNodeInfoByAccessibilityId(
+                eq(AccessibilityNodeInfo.ROOT_NODE_ID), (Region) anyObject(),
+                mInteractionIdCaptor.capture(), eq(mActionReplacingCallback), eq(0),
+                eq(INTERROGATING_PID), eq(INTERROGATING_TID), (MagnificationSpec) anyObject(),
+                eq(null));
+        mReplacerInteractionId = mInteractionIdCaptor.getValue().intValue();
+    }
+
+    @Test
+    public void testConstructor_registersToGetRootNodeOfActionReplacer() throws RemoteException {
+        assertNotEquals(INTERACTION_ID, mReplacerInteractionId);
+        verifyNoMoreInteractions(mMockServiceCallback);
+    }
+
+    @Test
+    public void testCallbacks_singleRootNodeThenReplacer_returnsNodeWithReplacedActions()
+            throws RemoteException {
+        AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
+        infoFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, APP_WINDOW_ID);
+        infoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        mActionReplacingCallback.setFindAccessibilityNodeInfoResult(infoFromApp, INTERACTION_ID);
+        verifyNoMoreInteractions(mMockServiceCallback);
+
+        mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
+                mReplacerInteractionId);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfoResult(mInfoCaptor.capture(),
+                eq(INTERACTION_ID));
+        AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
+        assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
+        assertInfoHasExactlyTheseActions(infoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+    }
+
+    public void testCallbacks_singleNonrootNodeThenReplacer_returnsNodeWithNoActions()
+            throws RemoteException {
+        AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
+        infoFromApp.setSourceNodeId(NON_ROOT_NODE_ID, APP_WINDOW_ID);
+        infoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        mActionReplacingCallback.setFindAccessibilityNodeInfoResult(infoFromApp, INTERACTION_ID);
+        verifyNoMoreInteractions(mMockServiceCallback);
+
+        mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
+                mReplacerInteractionId);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfoResult(mInfoCaptor.capture(),
+                eq(INTERACTION_ID));
+        AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
+        assertEquals(NON_ROOT_NODE_ID, infoSentToService.getSourceNodeId());
+        assertTrue(infoSentToService.getActionList().isEmpty());
+    }
+
+    public void testCallbacks_replacerThenSingleRootNode_returnsNodeWithReplacedActions()
+            throws RemoteException {
+        mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
+                mReplacerInteractionId);
+        verifyNoMoreInteractions(mMockServiceCallback);
+
+        AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
+        infoFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, APP_WINDOW_ID);
+        infoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        mActionReplacingCallback.setFindAccessibilityNodeInfoResult(infoFromApp, INTERACTION_ID);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfoResult(mInfoCaptor.capture(),
+                eq(INTERACTION_ID));
+        AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
+        assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
+        assertInfoHasExactlyTheseActions(infoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+    }
+
+    public void testCallbacks_multipleNodesThenReplacer_clearsActionsAndAddsSomeToRoot()
+            throws RemoteException {
+        mActionReplacingCallback
+                .setFindAccessibilityNodeInfosResult(getAppNodeList(), INTERACTION_ID);
+        verifyNoMoreInteractions(mMockServiceCallback);
+
+        mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
+                mReplacerInteractionId);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfosResult(mInfoListCaptor.capture(),
+                eq(INTERACTION_ID));
+        assertEquals(2, mInfoListCaptor.getValue().size());
+        AccessibilityNodeInfo rootInfoSentToService = getNodeWithIdFromList(
+                mInfoListCaptor.getValue(), AccessibilityNodeInfo.ROOT_NODE_ID);
+        AccessibilityNodeInfo otherInfoSentToService = getNodeWithIdFromList(
+                mInfoListCaptor.getValue(), NON_ROOT_NODE_ID);
+        assertInfoHasExactlyTheseActions(
+                rootInfoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+        assertTrue(otherInfoSentToService.getActionList().isEmpty());
+    }
+
+    public void testCallbacks_replacerThenMultipleNodes_clearsActionsAndAddsSomeToRoot()
+            throws RemoteException {
+        mActionReplacingCallback.setFindAccessibilityNodeInfosResult(getReplacerNodes(),
+                mReplacerInteractionId);
+        verifyNoMoreInteractions(mMockServiceCallback);
+
+        mActionReplacingCallback
+                .setFindAccessibilityNodeInfosResult(getAppNodeList(), INTERACTION_ID);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfosResult(mInfoListCaptor.capture(),
+                eq(INTERACTION_ID));
+        assertEquals(2, mInfoListCaptor.getValue().size());
+        AccessibilityNodeInfo rootInfoSentToService = getNodeWithIdFromList(
+                mInfoListCaptor.getValue(), AccessibilityNodeInfo.ROOT_NODE_ID);
+        AccessibilityNodeInfo otherInfoSentToService = getNodeWithIdFromList(
+                mInfoListCaptor.getValue(), NON_ROOT_NODE_ID);
+        assertInfoHasExactlyTheseActions(
+                rootInfoSentToService, REQUIRED_ACTIONS_ON_ROOT_TO_SERVICE);
+        assertTrue(otherInfoSentToService.getActionList().isEmpty());
+    }
+
+    public void testConstructor_actionReplacerThrowsException_passesDataToService()
+            throws RemoteException {
+        doThrow(RemoteException.class).when(mMockReplacerConnection)
+                .findAccessibilityNodeInfoByAccessibilityId(eq(AccessibilityNodeInfo.ROOT_NODE_ID),
+                        (Region) anyObject(), mInteractionIdCaptor.capture(),
+                        eq(mActionReplacingCallback), eq(0), eq(INTERROGATING_PID),
+                        eq(INTERROGATING_TID), (MagnificationSpec) anyObject(), eq(null));
+        ActionReplacingCallback actionReplacingCallback = new ActionReplacingCallback(
+                mMockServiceCallback, mMockReplacerConnection, INTERACTION_ID, INTERROGATING_PID,
+                INTERROGATING_TID);
+
+        verifyNoMoreInteractions(mMockServiceCallback);
+        AccessibilityNodeInfo infoFromApp = AccessibilityNodeInfo.obtain();
+        infoFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, APP_WINDOW_ID);
+        infoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        actionReplacingCallback.setFindAccessibilityNodeInfoResult(infoFromApp, INTERACTION_ID);
+
+        verify(mMockServiceCallback).setFindAccessibilityNodeInfoResult(mInfoCaptor.capture(),
+                eq(INTERACTION_ID));
+        AccessibilityNodeInfo infoSentToService = mInfoCaptor.getValue();
+        assertEquals(AccessibilityNodeInfo.ROOT_NODE_ID, infoSentToService.getSourceNodeId());
+        assertEquals(1, infoSentToService.getActionList().size());
+        assertEquals(ACTION_CONTEXT_CLICK, infoSentToService.getActionList().get(0));
+    }
+
+    public void testSetPerformAccessibilityActionResult_actsAsPassThrough() throws RemoteException {
+        mActionReplacingCallback.setPerformAccessibilityActionResult(true, INTERACTION_ID);
+        verify(mMockServiceCallback).setPerformAccessibilityActionResult(true, INTERACTION_ID);
+        mActionReplacingCallback.setPerformAccessibilityActionResult(false, INTERACTION_ID);
+        verify(mMockServiceCallback).setPerformAccessibilityActionResult(false, INTERACTION_ID);
+    }
+
+
+    private List<AccessibilityNodeInfo> getReplacerNodes() {
+        AccessibilityNodeInfo root = AccessibilityNodeInfo.obtain();
+        root.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        for (AccessibilityAction action : ACTIONS_FROM_REPLACER) {
+            root.addAction(action);
+        }
+
+        // Second node should have no effect
+        AccessibilityNodeInfo other = AccessibilityNodeInfo.obtain();
+        other.setSourceNodeId(NON_ROOT_NODE_ID,
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        other.addAction(ACTION_COLLAPSE);
+
+        return Arrays.asList(root, other);
+    }
+
+    private void assertInfoHasExactlyTheseActions(
+            AccessibilityNodeInfo info, AccessibilityAction[] actions) {
+        List<AccessibilityAction> nodeActions = info.getActionList();
+        assertEquals(new HashSet<AccessibilityAction>(nodeActions),
+                new HashSet<AccessibilityAction>(Arrays.asList(actions)));
+    }
+
+    private AccessibilityNodeInfo getNodeWithIdFromList(
+            List<AccessibilityNodeInfo> infos, long id) {
+        for (AccessibilityNodeInfo info : infos) {
+            if (info.getSourceNodeId() == id) {
+                return info;
+            }
+        }
+        assertTrue("Didn't find node", false);
+        return null;
+    }
+
+    private List<AccessibilityNodeInfo> getAppNodeList() {
+        AccessibilityNodeInfo rootInfoFromApp = AccessibilityNodeInfo.obtain();
+        rootInfoFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, APP_WINDOW_ID);
+        rootInfoFromApp.addAction(ACTION_CONTEXT_CLICK);
+        AccessibilityNodeInfo otherInfoFromApp = AccessibilityNodeInfo.obtain();
+        otherInfoFromApp.setSourceNodeId(NON_ROOT_NODE_ID, APP_WINDOW_ID);
+        otherInfoFromApp.addAction(ACTION_CLICK);
+        return Arrays.asList(rootInfoFromApp, otherInfoFromApp);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java b/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
index 0ab91a1..fc12edc 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
@@ -22,13 +22,13 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -46,12 +46,13 @@
 import android.view.KeyEvent;
 import android.view.WindowManagerPolicy;
 import com.android.server.accessibility.KeyEventDispatcher.KeyEventFilter;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 
 /**
  * Tests for KeyEventDispatcher
@@ -558,7 +559,7 @@
                 .matches(mInputEventsHander.timedMessages.get(1).obj));
     }
 
-    private class KeyEventMatcher extends ArgumentMatcher<KeyEvent> {
+    private class KeyEventMatcher extends TypeSafeMatcher<KeyEvent> {
         private KeyEvent mEventToMatch;
 
         KeyEventMatcher(KeyEvent eventToMatch) {
@@ -566,14 +567,15 @@
         }
 
         @Override
-        public boolean matches(Object event) {
-            if (!(event instanceof KeyEvent)) {
-                return false;
-            }
-            KeyEvent keyEvent = (KeyEvent) event;
+        public boolean matchesSafely(KeyEvent keyEvent) {
             return (mEventToMatch.getAction() == keyEvent.getAction())
                     && (mEventToMatch.getKeyCode() == keyEvent.getKeyCode());
         }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Key event matcher");
+        }
     }
 
     private class MessageCapturingHandler extends Handler {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
index cb5e8bb..d44c1ca 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -30,6 +29,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 import android.animation.ValueAnimator;
 import android.content.BroadcastReceiver;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index 73344e0..ec99a9a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -28,7 +28,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -36,6 +35,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 import android.accessibilityservice.GestureDescription.GestureStep;
 import android.accessibilityservice.GestureDescription.TouchPoint;
@@ -65,7 +65,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
+import org.mockito.compat.ArgumentMatcher;
 
 /**
  * Tests for MotionEventInjector
@@ -396,7 +396,7 @@
                 hasEventTime(downTime + CONTINUED_LINE_INTERVAL)));
         // Timing will restart when the gesture continues
         long secondSequenceStart = events.get(2).getEventTime();
-        assertTrue(secondSequenceStart > events.get(1).getEventTime());
+        assertTrue(secondSequenceStart >= events.get(1).getEventTime());
         assertThat(events.get(2), allOf(isAtPoint(CONTINUED_LINE_MID2), IS_ACTION_MOVE));
         assertThat(events.get(3), allOf(isAtPoint(CONTINUED_LINE_END), IS_ACTION_MOVE,
                 hasEventTime(secondSequenceStart + CONTINUED_LINE_INTERVAL)));
@@ -738,7 +738,7 @@
         return next;
     }
 
-    static class MotionEventMatcher extends ArgumentMatcher<MotionEvent> {
+    static class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> {
         long mDownTime;
         long mEventTime;
         long mActionMasked;
@@ -764,8 +764,7 @@
         }
 
         @Override
-        public boolean matches(Object o) {
-            MotionEvent event = (MotionEvent) o;
+        public boolean matchesSafely(MotionEvent event) {
             if ((event.getDownTime() == mDownTime) && (event.getEventTime() == mEventTime)
                     && (event.getActionMasked() == mActionMasked) && ((int) event.getX() == mX)
                     && ((int) event.getY() == mY)) {
@@ -782,6 +781,11 @@
             Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY);
             return false;
         }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Motion event matcher");
+        }
     }
 
     private static class MotionEventActionMatcher extends TypeSafeMatcher<MotionEvent> {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index cc2f7d5..556b218 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -31,15 +31,35 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.IUidObserver;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import com.android.server.AppOpsService;
+
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.function.Function;
 
 /**
@@ -62,9 +82,16 @@
 public class ActivityManagerServiceTest {
     private static final int TEST_UID = 111;
 
+    @Mock private AppOpsService mAppOpsService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
     @Test
     public void testIncrementProcStateSeqIfNeeded() {
-        final ActivityManagerService ams = new ActivityManagerService();
+        final ActivityManagerService ams = new ActivityManagerService(mAppOpsService);
         final UidRecord uidRec = new UidRecord(TEST_UID);
 
         assertEquals("Initially global seq counter should be 0", 0, ams.mProcStateSeqCounter);
@@ -104,7 +131,7 @@
 
     @Test
     public void testShouldIncrementProcStateSeq() {
-        final ActivityManagerService ams = new ActivityManagerService();
+        final ActivityManagerService ams = new ActivityManagerService(mAppOpsService);
         final UidRecord uidRec = new UidRecord(TEST_UID);
 
         final String error1 = "Seq should be incremented: prevState: %s, curState: %s";
@@ -145,4 +172,286 @@
         uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
         assertTrue(errorMsg.apply(error1), ams.shouldIncrementProcStateSeq(uidRec));
     }
+
+    /**
+     * This test verifies that process state changes are dispatched to observers based on the
+     * changes they wanted to listen (this is specified when registering the observer).
+     */
+    @Test
+    public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
+        final ActivityManagerService ams = new ActivityManagerService(mAppOpsService);
+        when(mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null))
+                .thenReturn(AppOpsManager.MODE_ALLOWED);
+
+        final int[] changesToObserve = {
+            ActivityManager.UID_OBSERVER_PROCSTATE,
+            ActivityManager.UID_OBSERVER_GONE,
+            ActivityManager.UID_OBSERVER_IDLE,
+            ActivityManager.UID_OBSERVER_ACTIVE,
+            ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
+                    | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
+        };
+        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
+        for (int i = 0; i < observers.length; ++i) {
+            observers[i] = Mockito.mock(IUidObserver.Stub.class);
+            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
+            ams.registerUidObserver(observers[i], changesToObserve[i] /* which */,
+                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
+
+            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
+            // mock in RemoteCallbackList class. We don't want to test those interactions and
+            // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
+            // So, resetting the mock here.
+            Mockito.reset(observers[i]);
+        }
+
+        // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_*
+        final int[] changesForPendingUidRecords = {
+            UidRecord.CHANGE_PROCSTATE,
+            UidRecord.CHANGE_GONE,
+            UidRecord.CHANGE_GONE_IDLE,
+            UidRecord.CHANGE_IDLE,
+            UidRecord.CHANGE_ACTIVE
+        };
+        final int[] procStatesForPendingUidRecords = {
+            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+            ActivityManager.PROCESS_STATE_NONEXISTENT,
+            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+            ActivityManager.PROCESS_STATE_TOP
+        };
+        final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>();
+        for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
+            final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem();
+            pendingChange.change = changesForPendingUidRecords[i];
+            pendingChange.uid = i;
+            pendingChange.processState = procStatesForPendingUidRecords[i];
+            pendingChange.procStateSeq = i;
+            changeItems.put(changesForPendingUidRecords[i], pendingChange);
+            ams.mPendingUidChanges.add(pendingChange);
+        }
+
+        ams.dispatchUidsChanged();
+        // Verify the required changes have been dispatched to observers.
+        for (int i = 0; i < observers.length; ++i) {
+            final int changeToObserve = changesToObserve[i];
+            final IUidObserver observerToTest = observers[i];
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) {
+                // Observer listens to uid idle changes, so change items corresponding to
+                // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be
+                // delivered to this observer.
+                final int[] changesToVerify = {
+                    UidRecord.CHANGE_IDLE,
+                    UidRecord.CHANGE_GONE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
+                // Observer listens to uid active changes, so change items corresponding to
+                // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer.
+                final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidActive(changeItem.uid);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) {
+                // Observer listens to uid gone changes, so change items corresponding to
+                // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be
+                // delivered to this observer.
+                final int[] changesToVerify = {
+                        UidRecord.CHANGE_GONE,
+                        UidRecord.CHANGE_GONE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
+                // Observer listens to uid procState changes, so change items corresponding to
+                // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
+                // needs to be delivered to this observer.
+                final int[] changesToVerify = {
+                        UidRecord.CHANGE_PROCSTATE,
+                        UidRecord.CHANGE_ACTIVE,
+                        UidRecord.CHANGE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidStateChanged(changeItem.uid,
+                                    changeItem.processState, changeItem.procStateSeq);
+                        });
+            }
+            // Verify there are no other callbacks for this observer.
+            verifyNoMoreInteractions(observerToTest);
+        }
+    }
+
+    private interface ObserverChangesVerifier {
+        void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException;
+    }
+
+    private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify,
+            Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier)
+            throws RemoteException {
+        for (int change : changesToVerify) {
+            final UidRecord.ChangeItem changeItem = changeItems.get(change);
+            verifier.verify(observer, changeItem);
+        }
+    }
+
+    /**
+     * This test verifies that process state changes are dispatched to observers only when they
+     * change across the cutpoint (this is specified when registering the observer).
+     */
+    @Test
+    public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
+        final ActivityManagerService ams = new ActivityManagerService(mAppOpsService);
+        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
+
+        when(observer.asBinder()).thenReturn((IBinder) observer);
+        ams.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
+                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
+        // When we invoke AMS.registerUidObserver, there are some interactions with observer
+        // mock in RemoteCallbackList class. We don't want to test those interactions and
+        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
+        // So, resetting the mock here.
+        Mockito.reset(observer);
+
+        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
+        changeItem.uid = TEST_UID;
+        changeItem.change = UidRecord.CHANGE_PROCSTATE;
+        changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+        changeItem.procStateSeq = 111;
+        ams.mPendingUidChanges.add(changeItem);
+        ams.dispatchUidsChanged();
+        // First process state message is always delivered regardless of whether the process state
+        // change is above or below the cutpoint (PROCESS_STATE_SERVICE).
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
+        ams.mPendingUidChanges.add(changeItem);
+        ams.dispatchUidsChanged();
+        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is also below cutpoint, so no callback will be invoked.
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+        ams.mPendingUidChanges.add(changeItem);
+        ams.dispatchUidsChanged();
+        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is above cutpoint, so callback will be invoked with the
+        // current process state change.
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
+        ams.mPendingUidChanges.add(changeItem);
+        ams.dispatchUidsChanged();
+        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is also above cutpoint, so no callback will be invoked.
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+        ams.mPendingUidChanges.add(changeItem);
+        ams.dispatchUidsChanged();
+        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is below cutpoint, so callback will be invoked with the
+        // current process state change.
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+    }
+
+    /**
+     * This test verifies that {@link ActivityManagerService#mValidateUids} which is a
+     * part of dumpsys is correctly updated.
+     */
+    @Test
+    public void testDispatchUidChanges_validateUidsUpdated() {
+        final ActivityManagerService ams = new ActivityManagerService(mAppOpsService);
+
+        final int[] changesForPendingItems = {
+            UidRecord.CHANGE_PROCSTATE,
+            UidRecord.CHANGE_GONE,
+            UidRecord.CHANGE_GONE_IDLE,
+            UidRecord.CHANGE_IDLE,
+            UidRecord.CHANGE_ACTIVE
+        };
+        final int[] procStatesForPendingItems = {
+            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+            ActivityManager.PROCESS_STATE_SERVICE,
+            ActivityManager.PROCESS_STATE_RECEIVER
+        };
+        final ArrayList<UidRecord.ChangeItem> pendingItemsForUids
+                = new ArrayList<>(changesForPendingItems.length);
+        for (int i = 0; i < changesForPendingItems.length; ++i) {
+            final UidRecord.ChangeItem item = new UidRecord.ChangeItem();
+            item.uid = i;
+            item.change = changesForPendingItems[i];
+            item.processState = procStatesForPendingItems[i];
+            pendingItemsForUids.add(i, item);
+        }
+
+        // Verify that when there no observers listening to uid state changes, then there will
+        // be no changes to validateUids.
+        ams.mPendingUidChanges.addAll(pendingItemsForUids);
+        ams.dispatchUidsChanged();
+        assertEquals("No observers registered, so validateUids should be empty",
+                0, ams.mValidateUids.size());
+
+        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
+        when(observer.asBinder()).thenReturn((IBinder) observer);
+        ams.registerUidObserver(observer, 0, 0, null);
+        // Verify that when observers are registered, then validateUids is correctly updated.
+        ams.mPendingUidChanges.addAll(pendingItemsForUids);
+        ams.dispatchUidsChanged();
+        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
+            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
+            final UidRecord validateUidRecord = ams.mValidateUids.get(item.uid);
+            if (item.change == UidRecord.CHANGE_GONE || item.change == UidRecord.CHANGE_GONE_IDLE) {
+                assertNull("validateUidRecord should be null since the change is either "
+                        + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
+            } else {
+                assertNotNull("validateUidRecord should not be null since the change is neither "
+                        + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
+                assertEquals("processState: " + item.processState + " curProcState: "
+                        + validateUidRecord.curProcState + " should have been equal",
+                        item.processState, validateUidRecord.curProcState);
+                assertEquals("processState: " + item.processState + " setProcState: "
+                        + validateUidRecord.curProcState + " should have been equal",
+                        item.processState, validateUidRecord.setProcState);
+                if (item.change == UidRecord.CHANGE_IDLE) {
+                    assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
+                            validateUidRecord.idle);
+                } else if (item.change == UidRecord.CHANGE_ACTIVE) {
+                    assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE",
+                            validateUidRecord.idle);
+                }
+            }
+        }
+
+        // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
+        // will be removed from validateUids.
+        assertNotEquals("validateUids should not be empty", 0, ams.mValidateUids.size());
+        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
+            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
+            // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
+            // distribution for this assignment.
+            item.change = (i % 2) == 0 ? UidRecord.CHANGE_GONE_IDLE : UidRecord.CHANGE_GONE;
+        }
+        ams.mPendingUidChanges.addAll(pendingItemsForUids);
+        ams.dispatchUidsChanged();
+        assertEquals("validateUids should be empty, validateUids: " + ams.mValidateUids,
+                0, ams.mValidateUids.size());
+    }
 }
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index f969e80..8987ac1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -85,7 +85,6 @@
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.atLeast;
@@ -99,6 +98,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 /**
  * Tests for DevicePolicyManager( and DevicePolicyManagerService).
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 3806da6..e43786c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -29,6 +29,7 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
 
 public class MockUtils {
     private MockUtils() {
@@ -47,7 +48,7 @@
                 description.appendText("UserHandle: user-id= \"" + userId + "\"");
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     public static Intent checkIntentComponent(final ComponentName component) {
@@ -63,7 +64,7 @@
                 description.appendText("Intent: component=\"" + component + "\"");
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     public static Intent checkIntentAction(final String action) {
@@ -79,7 +80,7 @@
                 description.appendText("Intent: action=\"" + action + "\"");
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     public static Intent checkIntent(final Intent intent) {
@@ -94,7 +95,7 @@
                 description.appendText(intent.toString());
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     public static Bundle checkUserRestrictions(String... keys) {
@@ -111,7 +112,7 @@
                 description.appendText("User restrictions=" + getRestrictionsAsString(expected));
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     private static String getRestrictionsAsString(Bundle b) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 1b59d72..b410400 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -2119,7 +2119,7 @@
     protected void makeCallerForeground() {
         try {
             mService.mUidObserver.onUidStateChanged(
-                    mInjectedCallingUid, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+                    mInjectedCallingUid, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
@@ -2128,7 +2128,7 @@
     protected void makeCallerBackground() {
         try {
             mService.mUidObserver.onUidStateChanged(
-                    mInjectedCallingUid, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+                    mInjectedCallingUid, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 900da09..7c5eb07 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -1640,7 +1640,7 @@
 
         // State changed, but not foreground, so no resetting.
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
         });
@@ -1664,7 +1664,7 @@
 
         // State changed, package1 foreground, reset.
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+                CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(3, mManager.getRemainingCallCount());
         });
@@ -1684,16 +1684,16 @@
             MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
         });
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+                CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
 
         mInjectedCurrentTimeMillis++;
 
         // Different app comes to foreground briefly, and goes back to background.
         // Now, make sure package 2's counter is reset, even in this case.
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(3, mManager.getRemainingCallCount());
@@ -1724,9 +1724,9 @@
         });
 
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+                CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         mService.mUidObserver.onUidStateChanged(
-                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+                CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
 
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(3, mManager.getRemainingCallCount());
@@ -1753,7 +1753,7 @@
         // Now, also try calling some APIs and make sure foreground apps don't get throttled.
         mService.mUidObserver.onUidStateChanged(
                 UserHandle.getUid(USER_10, CALLING_UID_1),
-                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
             assertEquals(3, mManager.getRemainingCallCount());
             assertFalse(mManager.isRateLimitingActive());
diff --git a/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java b/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java
index 1de6348..8329d68 100644
--- a/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/AccessibilityShortcutControllerTest.java
@@ -45,8 +45,8 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.mockito.internal.util.reflection.Whitebox;
 
+import java.lang.reflect.Field;
 import java.util.Collections;
 
 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN;
@@ -124,7 +124,15 @@
         when(mToast.getWindowParams()).thenReturn(mLayoutParams);
 
         Window window = mock(Window.class);
-        Whitebox.setInternalState(window, "mWindowAttributes", new WindowManager.LayoutParams());
+        // Initialize the mWindowAttributes field which was not properly initialized during mock
+        // creation.
+        try {
+            Field field = Window.class.getDeclaredField("mWindowAttributes");
+            field.setAccessible(true);
+            field.set(window, new WindowManager.LayoutParams());
+        } catch (Exception e) {
+            throw new RuntimeException("Unable to set mWindowAttributes", e);
+        }
         when(mAlertDialog.getWindow()).thenReturn(window);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
index e1dda51..d18457b 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/RetailDemoModeServiceTest.java
@@ -66,16 +66,15 @@
 import com.android.server.SystemService;
 import com.android.server.retaildemo.RetailDemoModeService.Injector;
 
-import org.hamcrest.Description;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
 
 import java.io.File;
 import java.util.concurrent.CountDownLatch;
@@ -283,7 +282,7 @@
         }
 
         @Override
-        public boolean matches(Object argument) {
+        public boolean matchesObject(Object argument) {
             if (argument instanceof Intent) {
                 return ((Intent) argument).filterEquals(mIntent);
             }
@@ -291,8 +290,8 @@
         }
 
         @Override
-        public void describeTo(Description description) {
-            description.appendText("Expected: " + mIntent);
+        public String toString() {
+            return "Expected: " + mIntent;
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
index 8cf7c8a..3cdf109 100644
--- a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java
@@ -28,6 +28,9 @@
 import android.os.UserManager;
 import android.os.storage.VolumeInfo;
 import android.test.AndroidTestCase;
+import android.util.ArrayMap;
+import android.util.Log;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,12 +43,14 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.when;
@@ -57,24 +62,29 @@
     @Mock private PackageManager mPm;
     @Mock private UserManager mUm;
     @Mock private StorageStatsManager mSsm;
-    private List<ApplicationInfo> mApps;
     private List<UserInfo> mUsers;
+    private Map<Integer, List<ApplicationInfo>> mUserApps;
 
     @Before
     public void setUp() throws Exception {
         super.setUp();
         MockitoAnnotations.initMocks(this);
-        mApps = new ArrayList<>();
         when(mContext.getPackageManager()).thenReturn(mPm);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
         when(mContext.getSystemService(Context.STORAGE_STATS_SERVICE)).thenReturn(mSsm);
 
         // Set up the app list.
-        when(mPm.getInstalledApplications(anyInt())).thenReturn(mApps);
+        doAnswer((InvocationOnMock invocation) -> {
+            Integer userId = (Integer) invocation.getArguments()[1];
+            return mUserApps.get(userId);
+        }).when(mPm).getInstalledApplicationsAsUser(anyInt(), anyInt());
 
         // Set up the user list with a single user (0).
         mUsers = new ArrayList<>();
         mUsers.add(new UserInfo(0, "", 0));
+
+        mUserApps = new ArrayMap<>();
+        mUserApps.put(0, new ArrayList<>());
         when(mUm.getUsers()).thenReturn(mUsers);
     }
 
@@ -89,7 +99,7 @@
 
     @Test
     public void testAppOnExternalVolume() throws Exception {
-        addApplication("com.test.app", "differentuuid");
+        addApplication("com.test.app", "differentuuid", 0);
         VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
         volume.fsUuid = "testuuid";
         AppCollector collector = new AppCollector(mContext, volume);
@@ -99,7 +109,7 @@
 
     @Test
     public void testOneValidApp() throws Exception {
-        addApplication("com.test.app", "testuuid");
+        addApplication("com.test.app", "testuuid", 0);
         VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
         volume.fsUuid = "testuuid";
         AppCollector collector = new AppCollector(mContext, volume);
@@ -112,11 +122,9 @@
 
     @Test
     public void testMultipleUsersOneApp() throws Exception {
-        addApplication("com.test.app", "testuuid");
-        ApplicationInfo otherUsersApp = new ApplicationInfo();
-        otherUsersApp.packageName = "com.test.app";
-        otherUsersApp.volumeUuid = "testuuid";
-        otherUsersApp.uid = 1;
+        addApplication("com.test.app", "testuuid", 0);
+        mUserApps.put(1, new ArrayList<>());
+        addApplication("com.test.app", "testuuid", 1);
         mUsers.add(new UserInfo(1, "", 0));
 
         VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
@@ -138,11 +146,28 @@
         AppCollector collector = new AppCollector(mContext, null);
     }
 
-    private void addApplication(String packageName, String uuid) {
+    @Test
+    public void testAppNotFoundDoesntCauseCrash() throws Exception {
+        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
+        addApplication("com.test.app", "uuid", 0);
+        mUsers.add(new UserInfo(1, "", 0));
+        mUserApps.put(1, new ArrayList<>());
+        AppCollector collector = new AppCollector(mContext, volume);
+        when(mSsm.queryStatsForPackage(anyString(), anyString(), any(UserHandle.class))).thenThrow(
+                new IllegalStateException());
+
+        assertThat(collector.getPackageStats(TIMEOUT)).isEmpty();
+    }
+
+    private void addApplication(String packageName, String uuid, int userId) {
         ApplicationInfo info = new ApplicationInfo();
         info.packageName = packageName;
         info.volumeUuid = uuid;
-        mApps.add(info);
+        List<ApplicationInfo> userApps = mUserApps.get(userId);
+        if (userApps == null) {
+            userApps = new ArrayList<>();
+            mUserApps.put(userId, userApps);
+        }
+        userApps.add(info);
     }
-
 }
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index e4b74eb..925f414 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -35,14 +35,12 @@
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
-import org.hamcrest.Description;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import org.mockito.Mockito;
 import org.mockito.Matchers;
-import org.mockito.ArgumentMatcher;
+import org.mockito.compat.ArgumentMatcher;
 
 import java.util.concurrent.CountDownLatch;
 
@@ -149,14 +147,13 @@
         }
 
         @Override
-        public boolean matches(Object p) {
+        public boolean matchesObject(Object p) {
             return ((PackageInfo) p).packageName.equals(mPackageName);
         }
 
-        // Provide a more useful description in case of mismatch
         @Override
-        public void describeTo (Description description) {
-            description.appendText(String.format("PackageInfo with name '%s'", mPackageName));
+        public String toString() {
+            return String.format("PackageInfo with name '%s'", mPackageName);
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index e589bc7..3868242 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -22,7 +22,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
@@ -147,7 +146,6 @@
         final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin");
         appWin.setHasSurface(true);
         assertTrue(appWin.canBeImeTarget());
-        sWm.mInputMethodTargetCandidate = appWin.mClient.asBinder();
         WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(appWin, imeTarget);
 
@@ -158,20 +156,6 @@
         assertTrue(childWin.canBeImeTarget());
         imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(childWin, imeTarget);
-
-        final WindowState appWin2 =
-                createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin2");
-        appWin2.setHasSurface(true);
-        assertTrue(appWin2.canBeImeTarget());
-        // Verify that the IME target isn't adjusted since mInputMethodTargetCandidate didn't change
-        // to the new app.
-        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
-        assertNotEquals(appWin2, imeTarget);
-
-        sWm.mInputMethodTargetCandidate = appWin2.mClient.asBinder();
-        // Verify app is not IME target since its token is set as a candidate.
-        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
-        assertEquals(appWin2, imeTarget);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index c8b73f1..0971bb6 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -82,7 +82,7 @@
                 final ActivityManagerInternal am =
                         LocalServices.getService(ActivityManagerInternal.class);
                 doAnswer((InvocationOnMock invocationOnMock) -> {
-                    final Runnable runnable = invocationOnMock.getArgumentAt(0, Runnable.class);
+                    final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
                     if (runnable != null) {
                         runnable.run();
                     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 18c48b7..911050a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -69,6 +69,7 @@
 class WindowTestsBase {
     static WindowManagerService sWm = null;
     static TestWindowManagerPolicy sPolicy = null;
+    private final static IWindow sIWindow = new TestIWindow();
     private final static Session sMockSession = mock(Session.class);
     private static int sNextDisplayId = Display.DEFAULT_DISPLAY + 1;
     static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
@@ -147,7 +148,6 @@
         }
 
         sWm.mInputMethodTarget = null;
-        sWm.mInputMethodTargetCandidate = null;
     }
 
     private static WindowState createCommonWindow(WindowState parent, int type, String name) {
@@ -222,12 +222,11 @@
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
         attrs.setTitle(name);
 
-        final WindowState w = new WindowState(sWm, sMockSession, new TestIWindow(), token, parent,
-                OP_NONE, 0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
+        final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
+                0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
         // adding it to the token...
         token.addWindow(w);
-        sWm.mWindowMap.put(w.mClient.asBinder(), w);
         return w;
     }
 
@@ -455,9 +454,8 @@
         boolean resizeReported;
 
         TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
-            super(sWm, sMockSession, new TestIWindow(), token, null, OP_NONE, 0, attrs, 0, 0,
+            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0,
                     false /* ownerCanAddInternalSystemWindow */);
-            sWm.mWindowMap.put(mClient.asBinder(), this);
         }
 
         @Override
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index fd335c3..f2bae4c 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -59,6 +59,7 @@
 import org.json.JSONObject;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -672,7 +673,7 @@
                 d.appendText(description);
             }
         };
-        return Mockito.argThat(m);
+        return MockitoHamcrest.argThat(m);
     }
 
     public static List<ShortcutInfo> checkShortcutIds(String... ids) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3c7ee43..7be2b0f 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -342,7 +342,7 @@
 
     private final IUidObserver mUidObserver = new IUidObserver.Stub() {
         @Override
-        public void onUidStateChanged(int uid, int procState) {
+        public void onUidStateChanged(int uid, int procState, long procStateSeq) {
             final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
             synchronized (mUidToKernelCounter) {
                 final int oldCounter = mUidToKernelCounter.get(uid, 0);
@@ -364,7 +364,7 @@
 
         @Override
         public void onUidGone(int uid, boolean disabled) throws RemoteException {
-            onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
+            onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0);
         }
 
         @Override
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index a17676a..b142bc2 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -33,6 +33,7 @@
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
+import android.os.BatteryManager;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.Looper;
@@ -122,6 +123,7 @@
     private static final int MSG_UPDATE_USER_RESTRICTIONS = 6;
     private static final int MSG_UPDATE_HOST_STATE = 7;
     private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8;
+    private static final int MSG_UPDATE_CHARGING_STATE = 9;
 
     private static final int AUDIO_MODE_SOURCE = 1;
 
@@ -203,6 +205,15 @@
         }
     };
 
+    private final BroadcastReceiver mChargingReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+             int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+             boolean usbCharging = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
+             mHandler.sendMessage(MSG_UPDATE_CHARGING_STATE, usbCharging);
+        }
+    };
+
     public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
             UsbSettingsManager settingsManager) {
         mContext = context;
@@ -229,6 +240,8 @@
         }
         mContext.registerReceiver(mHostReceiver,
                 new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED));
+        mContext.registerReceiver(mChargingReceiver,
+                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
     }
 
     private UsbProfileGroupSettingsManager getCurrentSettings() {
@@ -358,6 +371,7 @@
         private int mUsbNotificationId;
         private boolean mAdbNotificationShown;
         private int mCurrentUser = UserHandle.USER_NULL;
+        private boolean mUsbCharging;
 
         public UsbHandler(Looper looper) {
             super(looper);
@@ -456,7 +470,10 @@
             args.argi2 = sourcePower ? 1 :0;
             args.argi3 = sinkPower ? 1 :0;
 
-            obtainMessage(MSG_UPDATE_HOST_STATE, args).sendToTarget();
+            removeMessages(MSG_UPDATE_HOST_STATE);
+            Message msg = obtainMessage(MSG_UPDATE_HOST_STATE, args);
+            // debounce rapid transitions of connect/disconnect on type-c ports
+            sendMessageDelayed(msg, UPDATE_DELAY);
         }
 
         private boolean waitForState(String state) {
@@ -799,6 +816,10 @@
                         mPendingBootBroadcast = true;
                     }
                     break;
+                case MSG_UPDATE_CHARGING_STATE:
+                    mUsbCharging = (msg.arg1 == 1);
+                    updateUsbNotification();
+                    break;
                 case MSG_ENABLE_ADB:
                     setAdbEnabled(msg.arg1 == 1);
                     break;
@@ -892,7 +913,7 @@
                 }
             } else if (mSourcePower) {
                 id = com.android.internal.R.string.usb_supplying_notification_title;
-            } else if (mHostConnected && mSinkPower) {
+            } else if (mHostConnected && mSinkPower && mUsbCharging) {
                 id = com.android.internal.R.string.usb_charging_notification_title;
             }
             if (id != mUsbNotificationId) {
@@ -998,6 +1019,7 @@
             pw.println("  mHostConnected: " + mHostConnected);
             pw.println("  mSourcePower: " + mSourcePower);
             pw.println("  mSinkPower: " + mSinkPower);
+            pw.println("  mUsbCharging: " + mUsbCharging);
             try {
                 pw.println("  Kernel state: "
                         + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index a923fc3..86f4a01 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -41,6 +41,7 @@
 import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.FgThread;
 
@@ -78,7 +79,7 @@
     private final Context mContext;
 
     // Proxy object for the usb hal daemon.
-    // @GuardedBy("mLock")
+    @GuardedBy("mLock")
     private IUsb mProxy = null;
 
     // Callback when the UsbPort status is changed by the kernel.
@@ -92,7 +93,7 @@
     private static final int USB_HAL_DEATH_COOKIE = 1000;
 
     // Usb hal service name.
-    private static String sSERVICENAME = "usb_hal";
+    private static String sServiceName = "usb_hal";
 
     // Used as the key while sending the bundle to Main thread.
     private static final String PORT_INFO = "port_info";
@@ -119,13 +120,14 @@
         try {
             boolean ret = IServiceManager.getService()
                     .registerForNotifications("android.hardware.usb@1.0::IUsb",
-                    "", mServiceNotification);
+                            "", mServiceNotification);
             if (!ret) {
-                logAndPrint(Log.ERROR, null, "Failed to register service start notification");
+                logAndPrint(Log.ERROR, null,
+                        "Failed to register service start notification");
             }
         } catch (RemoteException e) {
-            logAndPrint(Log.ERROR, null, "Failed to register service start notification");
-            Thread.dumpStack();
+            logAndPrintException(null,
+                    "Failed to register service start notification", e);
             return;
         }
         connectToProxy(null);
@@ -136,9 +138,8 @@
             try {
                 mProxy.queryPortStatus();
             } catch (RemoteException e) {
-                logAndPrint(Log.ERROR, null,
-                        "ServiceStart: Failed to query port status");
-                Thread.dumpStack();
+                logAndPrintException(null,
+                        "ServiceStart: Failed to query port status", e);
             }
         }
         mSystemReady = true;
@@ -234,9 +235,9 @@
             RawPortInfo sim = mSimulatedPorts.get(portId);
             if (sim != null) {
                 // Change simulated state.
-                sim.mCurrentMode = newMode;
-                sim.mCurrentPowerRole = newPowerRole;
-                sim.mCurrentDataRole = newDataRole;
+                sim.currentMode = newMode;
+                sim.currentPowerRole = newPowerRole;
+                sim.currentDataRole = newDataRole;
                 updatePortsLocked(pw, null);
             } else if (mProxy != null) {
                 if (currentMode != newMode) {
@@ -248,18 +249,17 @@
                     // directly instead.
 
                     logAndPrint(Log.ERROR, pw, "Trying to set the USB port mode: "
-                                + "portId=" + portId
-                                + ", newMode=" + UsbPort.modeToString(newMode));
+                            + "portId=" + portId
+                            + ", newMode=" + UsbPort.modeToString(newMode));
                     PortRole newRole = new PortRole();
                     newRole.type = PortRoleType.MODE;
                     newRole.role = newMode;
                     try {
                         mProxy.switchRole(portId, newRole);
                     } catch (RemoteException e) {
-                        logAndPrint(Log.ERROR, pw, "Failed to set the USB port mode: "
+                        logAndPrintException(pw, "Failed to set the USB port mode: "
                                 + "portId=" + portId
-                                + ", newMode=" + UsbPort.modeToString(newRole.role));
-                        Thread.dumpStack();
+                                + ", newMode=" + UsbPort.modeToString(newRole.role), e);
                         return;
                     }
                 } else {
@@ -271,10 +271,11 @@
                         try {
                             mProxy.switchRole(portId, newRole);
                         } catch (RemoteException e) {
-                            logAndPrint(Log.ERROR, pw, "Failed to set the USB port power role: "
-                                    + "portId=" + portId
-                                    + ", newPowerRole=" + UsbPort.powerRoleToString(newRole.role));
-                            Thread.dumpStack();
+                            logAndPrintException(pw, "Failed to set the USB port power role: "
+                                            + "portId=" + portId
+                                            + ", newPowerRole=" + UsbPort.powerRoleToString
+                                            (newRole.role),
+                                    e);
                             return;
                         }
                     }
@@ -285,10 +286,11 @@
                         try {
                             mProxy.switchRole(portId, newRole);
                         } catch (RemoteException e) {
-                            logAndPrint(Log.ERROR, pw, "Failed to set the USB port data role: "
-                                    + "portId=" + portId
-                                    + ", newDataRole=" + UsbPort.dataRoleToString(newRole.role));
-                            Thread.dumpStack();
+                            logAndPrintException(pw, "Failed to set the USB port data role: "
+                                            + "portId=" + portId
+                                            + ", newDataRole=" + UsbPort.dataRoleToString(newRole
+                                            .role),
+                                    e);
                             return;
                         }
                     }
@@ -328,7 +330,7 @@
                 return;
             }
 
-            if ((portInfo.mSupportedModes & mode) == 0) {
+            if ((portInfo.supportedModes & mode) == 0) {
                 pw.println("Simulated port does not support mode: " + UsbPort.modeToString(mode));
                 return;
             }
@@ -340,12 +342,12 @@
                     + ", canChangePowerRole=" + canChangePowerRole
                     + ", dataRole=" + UsbPort.dataRoleToString(dataRole)
                     + ", canChangeDataRole=" + canChangeDataRole);
-            portInfo.mCurrentMode = mode;
-            portInfo.mCanChangeMode = canChangeMode;
-            portInfo.mCurrentPowerRole = powerRole;
-            portInfo.mCanChangePowerRole = canChangePowerRole;
-            portInfo.mCurrentDataRole = dataRole;
-            portInfo.mCanChangeDataRole = canChangeDataRole;
+            portInfo.currentMode = mode;
+            portInfo.canChangeMode = canChangeMode;
+            portInfo.currentPowerRole = powerRole;
+            portInfo.canChangePowerRole = canChangePowerRole;
+            portInfo.currentDataRole = dataRole;
+            portInfo.canChangeDataRole = canChangeDataRole;
             updatePortsLocked(pw, null);
         }
     }
@@ -359,12 +361,12 @@
             }
 
             pw.println("Disconnecting simulated port: portId=" + portId);
-            portInfo.mCurrentMode = 0;
-            portInfo.mCanChangeMode = false;
-            portInfo.mCurrentPowerRole = 0;
-            portInfo.mCanChangePowerRole = false;
-            portInfo.mCurrentDataRole = 0;
-            portInfo.mCanChangeDataRole = false;
+            portInfo.currentMode = 0;
+            portInfo.canChangeMode = false;
+            portInfo.currentPowerRole = 0;
+            portInfo.canChangePowerRole = false;
+            portInfo.currentDataRole = 0;
+            portInfo.canChangeDataRole = false;
             updatePortsLocked(pw, null);
         }
     }
@@ -425,7 +427,9 @@
         }
 
         public void notifyPortStatusChange(ArrayList<PortStatus> currentPortStatus, int retval) {
-            if (!portManager.mSystemReady) return;
+            if (!portManager.mSystemReady) {
+                return;
+            }
 
             if (retval != Status.SUCCESS) {
                 logAndPrint(Log.ERROR, pw, "port status enquiry failed");
@@ -490,21 +494,21 @@
 
     private void connectToProxy(IndentingPrintWriter pw) {
         synchronized (mLock) {
-            if (mProxy != null) return;
+            if (mProxy != null) {
+                return;
+            }
 
             try {
-                mProxy = IUsb.getService(sSERVICENAME);
+                mProxy = IUsb.getService(sServiceName);
                 mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
                 mProxy.setCallback(mHALCallback);
                 mProxy.queryPortStatus();
             } catch (NoSuchElementException e) {
-                logAndPrint(Log.ERROR, pw, sSERVICENAME + " not found."
-                        + " Did the service fail to start?");
-                Thread.dumpStack();
+                logAndPrintException(pw, sServiceName + " not found."
+                        + " Did the service fail to start?", e);
             } catch (RemoteException e) {
-                logAndPrint(Log.ERROR, pw, sSERVICENAME
-                        + " connectToProxy: Service not responding");
-                Thread.dumpStack();
+                logAndPrintException(pw, sServiceName
+                        + " connectToProxy: Service not responding", e);
             }
         }
     }
@@ -523,17 +527,17 @@
             final int count = mSimulatedPorts.size();
             for (int i = 0; i < count; i++) {
                 final RawPortInfo portInfo = mSimulatedPorts.valueAt(i);
-                addOrUpdatePortLocked(portInfo.mPortId, portInfo.mSupportedModes,
-                        portInfo.mCurrentMode, portInfo.mCanChangeMode,
-                        portInfo.mCurrentPowerRole, portInfo.mCanChangePowerRole,
-                        portInfo.mCurrentDataRole, portInfo.mCanChangeDataRole, pw);
+                addOrUpdatePortLocked(portInfo.portId, portInfo.supportedModes,
+                        portInfo.currentMode, portInfo.canChangeMode,
+                        portInfo.currentPowerRole, portInfo.canChangePowerRole,
+                        portInfo.currentDataRole, portInfo.canChangeDataRole, pw);
             }
         } else {
             for (RawPortInfo currentPortInfo : newPortInfo) {
-                addOrUpdatePortLocked(currentPortInfo.mPortId, currentPortInfo.mSupportedModes,
-                        currentPortInfo.mCurrentMode, currentPortInfo.mCanChangeMode,
-                        currentPortInfo.mCurrentPowerRole, currentPortInfo.mCanChangePowerRole,
-                        currentPortInfo.mCurrentDataRole, currentPortInfo.mCanChangeDataRole, pw);
+                addOrUpdatePortLocked(currentPortInfo.portId, currentPortInfo.supportedModes,
+                        currentPortInfo.currentMode, currentPortInfo.canChangeMode,
+                        currentPortInfo.currentPowerRole, currentPortInfo.canChangePowerRole,
+                        currentPortInfo.currentDataRole, currentPortInfo.canChangeDataRole, pw);
             }
         }
 
@@ -562,18 +566,18 @@
 
     // Must only be called by updatePortsLocked.
     private void addOrUpdatePortLocked(String portId, int supportedModes,
-                                       int currentMode, boolean canChangeMode,
-                                       int currentPowerRole, boolean canChangePowerRole,
-                                       int currentDataRole, boolean canChangeDataRole,
-                                       IndentingPrintWriter pw) {
+            int currentMode, boolean canChangeMode,
+            int currentPowerRole, boolean canChangePowerRole,
+            int currentDataRole, boolean canChangeDataRole,
+            IndentingPrintWriter pw) {
         // Only allow mode switch capability for dual role ports.
         // Validate that the current mode matches the supported modes we expect.
         if (supportedModes != UsbPort.MODE_DUAL) {
             canChangeMode = false;
             if (currentMode != 0 && currentMode != supportedModes) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent current mode from USB "
-                            + "port driver: supportedModes=" + UsbPort.modeToString(supportedModes)
-                            + ", currentMode=" + UsbPort.modeToString(currentMode));
+                        + "port driver: supportedModes=" + UsbPort.modeToString(supportedModes)
+                        + ", currentMode=" + UsbPort.modeToString(currentMode));
                 currentMode = 0;
             }
         }
@@ -588,8 +592,8 @@
                 // Can change both power and data role independently.
                 // Assume all combinations are possible.
                 supportedRoleCombinations |=
-                    COMBO_SOURCE_HOST | COMBO_SOURCE_DEVICE
-                    | COMBO_SINK_HOST | COMBO_SINK_DEVICE;
+                        COMBO_SOURCE_HOST | COMBO_SOURCE_DEVICE
+                                | COMBO_SINK_HOST | COMBO_SINK_DEVICE;
             } else if (canChangePowerRole) {
                 // Can only change power role.
                 // Assume data role must remain at its current value.
@@ -617,24 +621,24 @@
         if (portInfo == null) {
             portInfo = new PortInfo(portId, supportedModes);
             portInfo.setStatus(currentMode, canChangeMode,
-                               currentPowerRole, canChangePowerRole,
-                               currentDataRole, canChangeDataRole,
-                               supportedRoleCombinations);
+                    currentPowerRole, canChangePowerRole,
+                    currentDataRole, canChangeDataRole,
+                    supportedRoleCombinations);
             mPorts.put(portId, portInfo);
         } else {
             // Sanity check that ports aren't changing definition out from under us.
             if (supportedModes != portInfo.mUsbPort.getSupportedModes()) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent list of supported modes from "
-                            + "USB port driver (should be immutable): "
-                            + "previous=" + UsbPort.modeToString(
-                            portInfo.mUsbPort.getSupportedModes())
-                            + ", current=" + UsbPort.modeToString(supportedModes));
+                        + "USB port driver (should be immutable): "
+                        + "previous=" + UsbPort.modeToString(
+                        portInfo.mUsbPort.getSupportedModes())
+                        + ", current=" + UsbPort.modeToString(supportedModes));
             }
 
             if (portInfo.setStatus(currentMode, canChangeMode,
-                                   currentPowerRole, canChangePowerRole,
-                                   currentDataRole, canChangeDataRole,
-                                   supportedRoleCombinations)) {
+                    currentPowerRole, canChangePowerRole,
+                    currentDataRole, canChangeDataRole,
+                    supportedRoleCombinations)) {
                 portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
             } else {
                 portInfo.mDisposition = PortInfo.DISPOSITION_READY;
@@ -661,7 +665,7 @@
         final Intent intent = new Intent(UsbManager.ACTION_USB_PORT_CHANGED);
         intent.addFlags(
                 Intent.FLAG_RECEIVER_FOREGROUND |
-                Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
         intent.putExtra(UsbManager.EXTRA_PORT, portInfo.mUsbPort);
         intent.putExtra(UsbManager.EXTRA_PORT_STATUS, portInfo.mUsbPortStatus);
 
@@ -682,6 +686,13 @@
         }
     }
 
+    private static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) {
+        Slog.e(TAG, msg, e);
+        if (pw != null) {
+            pw.println(msg + e);
+        }
+    }
+
     private final Handler mHandler = new Handler(FgThread.get().getLooper()) {
         @Override
         public void handleMessage(Message msg) {
@@ -730,7 +741,7 @@
                     || mUsbPortStatus.getCurrentPowerRole() != currentPowerRole
                     || mUsbPortStatus.getCurrentDataRole() != currentDataRole
                     || mUsbPortStatus.getSupportedRoleCombinations()
-                            != supportedRoleCombinations) {
+                    != supportedRoleCombinations) {
                 mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                         supportedRoleCombinations);
                 return true;
@@ -752,32 +763,32 @@
      * Values of the member variables mocked directly incase of emulation.
      */
     private static final class RawPortInfo implements Parcelable {
-        public final String mPortId;
-        public final int mSupportedModes;
-        public int mCurrentMode;
-        public boolean mCanChangeMode;
-        public int mCurrentPowerRole;
-        public boolean mCanChangePowerRole;
-        public int mCurrentDataRole;
-        public boolean mCanChangeDataRole;
+        public final String portId;
+        public final int supportedModes;
+        public int currentMode;
+        public boolean canChangeMode;
+        public int currentPowerRole;
+        public boolean canChangePowerRole;
+        public int currentDataRole;
+        public boolean canChangeDataRole;
 
         RawPortInfo(String portId, int supportedModes) {
-            mPortId = portId;
-            mSupportedModes = supportedModes;
+            this.portId = portId;
+            this.supportedModes = supportedModes;
         }
 
         RawPortInfo(String portId, int supportedModes,
-                                 int currentMode, boolean canChangeMode,
-                                 int currentPowerRole, boolean canChangePowerRole,
-                                 int currentDataRole, boolean canChangeDataRole) {
-            mPortId = portId;
-            mSupportedModes = supportedModes;
-            mCurrentMode = currentMode;
-            mCanChangeMode = canChangeMode;
-            mCurrentPowerRole = currentPowerRole;
-            mCanChangePowerRole = canChangePowerRole;
-            mCurrentDataRole = currentDataRole;
-            mCanChangeDataRole = canChangeDataRole;
+                int currentMode, boolean canChangeMode,
+                int currentPowerRole, boolean canChangePowerRole,
+                int currentDataRole, boolean canChangeDataRole) {
+            this.portId = portId;
+            this.supportedModes = supportedModes;
+            this.currentMode = currentMode;
+            this.canChangeMode = canChangeMode;
+            this.currentPowerRole = currentPowerRole;
+            this.canChangePowerRole = canChangePowerRole;
+            this.currentDataRole = currentDataRole;
+            this.canChangeDataRole = canChangeDataRole;
         }
 
         @Override
@@ -787,37 +798,37 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeString(mPortId);
-            dest.writeInt(mSupportedModes);
-            dest.writeInt(mCurrentMode);
-            dest.writeByte((byte) (mCanChangeMode ? 1 : 0));
-            dest.writeInt(mCurrentPowerRole);
-            dest.writeByte((byte) (mCanChangePowerRole ? 1 : 0));
-            dest.writeInt(mCurrentDataRole);
-            dest.writeByte((byte) (mCanChangeDataRole ? 1 : 0));
+            dest.writeString(portId);
+            dest.writeInt(supportedModes);
+            dest.writeInt(currentMode);
+            dest.writeByte((byte) (canChangeMode ? 1 : 0));
+            dest.writeInt(currentPowerRole);
+            dest.writeByte((byte) (canChangePowerRole ? 1 : 0));
+            dest.writeInt(currentDataRole);
+            dest.writeByte((byte) (canChangeDataRole ? 1 : 0));
         }
 
         public static final Parcelable.Creator<RawPortInfo> CREATOR =
                 new Parcelable.Creator<RawPortInfo>() {
-            @Override
-            public RawPortInfo createFromParcel(Parcel in) {
-                String id = in.readString();
-                int supportedModes = in.readInt();
-                int currentMode = in.readInt();
-                boolean canChangeMode = in.readByte() != 0;
-                int currentPowerRole = in.readInt();
-                boolean canChangePowerRole = in.readByte() != 0;
-                int currentDataRole = in.readInt();
-                boolean canChangeDataRole = in.readByte() != 0;
-                return new RawPortInfo(id, supportedModes, currentMode, canChangeMode,
-                                   currentPowerRole, canChangePowerRole,
-                                   currentDataRole, canChangeDataRole);
-            }
+                    @Override
+                    public RawPortInfo createFromParcel(Parcel in) {
+                        String id = in.readString();
+                        int supportedModes = in.readInt();
+                        int currentMode = in.readInt();
+                        boolean canChangeMode = in.readByte() != 0;
+                        int currentPowerRole = in.readInt();
+                        boolean canChangePowerRole = in.readByte() != 0;
+                        int currentDataRole = in.readInt();
+                        boolean canChangeDataRole = in.readByte() != 0;
+                        return new RawPortInfo(id, supportedModes, currentMode, canChangeMode,
+                                currentPowerRole, canChangePowerRole,
+                                currentDataRole, canChangeDataRole);
+                    }
 
-            @Override
-            public RawPortInfo[] newArray(int size) {
-                return new RawPortInfo[size];
-            }
-        };
+                    @Override
+                    public RawPortInfo[] newArray(int size) {
+                        return new RawPortInfo[size];
+                    }
+                };
     }
 }
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index ced6627..6107895 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.telecom.Logging.EventManager;
 import android.telecom.Logging.Session;
 import android.telecom.Logging.SessionManager;
@@ -55,6 +56,7 @@
     public static boolean ERROR = isLoggable(android.util.Log.ERROR);
 
     private static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */
+    private static final boolean USER_BUILD = Build.TYPE.equals("user");
 
     // Used to synchronize singleton logging lazy initialization
     private static final Object sSingletonSync = new Object();
@@ -404,7 +406,8 @@
 
     /**
      * Redact personally identifiable information for production users.
-     * If we are running in verbose mode, return the original string, otherwise
+     * If we are running in verbose mode, return the original string,
+     * and return "****" if we are running on the user build, otherwise
      * return a SHA-1 hash of the input string.
      */
     public static String pii(Object pii) {
@@ -415,6 +418,11 @@
     }
 
     private static String secureHash(byte[] input) {
+        // Refrain from logging user personal information in user build.
+        if (USER_BUILD) {
+            return "****";
+        }
+
         if (sMessageDigest != null) {
             sMessageDigest.reset();
             sMessageDigest.update(input);
diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java
index cd0a012..2a31e3a 100644
--- a/telephony/java/android/telephony/Rlog.java
+++ b/telephony/java/android/telephony/Rlog.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -32,6 +33,8 @@
  */
 public final class Rlog {
 
+    private static final boolean USER_BUILD = Build.TYPE.equals("user");
+
     private Rlog() {
     }
 
@@ -125,10 +128,15 @@
     /**
      * Returns a secure hash (using the SHA1 algorithm) of the provided input.
      *
-     * @return the hash
+     * @return "****" if the build type is user, otherwise the hash
      * @param input the bytes for which the secure hash should be computed.
      */
     private static String secureHash(byte[] input) {
+        // Refrain from logging user personal information in user build.
+        if (USER_BUILD) {
+            return "****";
+        }
+
         MessageDigest messageDigest;
 
         try {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 92197d6..51b91f4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,6 +23,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.WorkerThread;
 import android.annotation.SystemApi;
 import android.app.ActivityThread;
 import android.app.PendingIntent;
@@ -1495,7 +1496,10 @@
 
 
     /**
-     * Returns the network specifier of the subscription ID pinned to the TelephonyManager.
+     * Returns the network specifier of the subscription ID pinned to the TelephonyManager. The
+     * network specifier is used by {@link
+     * android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to create a {@link
+     * android.net.NetworkRequest} that connects through the subscription.
      *
      * @see android.net.NetworkRequest.Builder#setNetworkSpecifier(String)
      * @see #createForSubscriptionId(int)
@@ -1506,7 +1510,9 @@
     }
 
     /**
-     * Returns the carrier config of the subscription ID pinned to the TelephonyManager.
+     * Returns the carrier config of the subscription ID pinned to the TelephonyManager. If an
+     * invalid subscription ID is pinned to the TelephonyManager, the returned config will contain
+     * default values.
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
      * READ_PHONE_STATE}
@@ -1515,6 +1521,7 @@
      * @see #createForSubscriptionId(int)
      * @see #createForPhoneAccountHandle(PhoneAccountHandle)
      */
+    @WorkerThread
     public PersistableBundle getCarrierConfig() {
         CarrierConfigManager carrierConfigManager = mContext
                 .getSystemService(CarrierConfigManager.class);
@@ -2705,19 +2712,24 @@
 
 
     /**
-     * Returns the package responsible of processing visual voicemail for the phone account.
+     * Returns the package responsible of processing visual voicemail for the subscription ID pinned
+     * to the TelephonyManager. Returns {@code null} when there is no package responsible for
+     * processing visual voicemail for the subscription.
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
      * READ_PHONE_STATE}
+     *
+     * @see #createForSubscriptionId(int)
+     * @see #createForPhoneAccountHandle(PhoneAccountHandle)
+     * @see VisualVoicemailService
      */
     @Nullable
-    public String getVisualVoicemailPackageName(PhoneAccountHandle phoneAccountHandle) {
+    public String getVisualVoicemailPackageName() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 return telephony
-                        .getVisualVoicemailPackageName(mContext.getOpPackageName(),
-                                phoneAccountHandle);
+                        .getVisualVoicemailPackageName(mContext.getOpPackageName(), mSubId);
             }
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
diff --git a/telephony/java/android/telephony/VisualVoicemailSms.java b/telephony/java/android/telephony/VisualVoicemailSms.java
index 6235c10..1e6ea4b 100644
--- a/telephony/java/android/telephony/VisualVoicemailSms.java
+++ b/telephony/java/android/telephony/VisualVoicemailSms.java
@@ -63,7 +63,8 @@
 
     /**
      * The key-value pairs sent by the SMS, or {@code null} if the framework cannot parse the SMS as
-     * voicemail but the carrier pattern indicates it is.
+     * voicemail but the carrier pattern indicates it is. The interpretation of the fields is
+     * carrier dependent.
      */
     public Bundle getFields() {
         return mFields;
diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
index 9d19d08..56a8c62 100644
--- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
+++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
@@ -16,7 +16,6 @@
 package android.telephony;
 
 import android.content.Context;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -55,8 +54,17 @@
      */
     public static final int DESTINATION_PORT_DATA_SMS = -2;
 
+    /**
+     * @hide
+     */
     public static final String DEFAULT_CLIENT_PREFIX = "//VVM";
+    /**
+     * @hide
+     */
     public static final List<String> DEFAULT_ORIGINATING_NUMBERS = Collections.emptyList();
+    /**
+     * @hide
+     */
     public static final int DEFAULT_DESTINATION_PORT = DESTINATION_PORT_ANY;
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 5f3f773..c9c48dc 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -30,9 +30,9 @@
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.telephony.Rlog;
 import android.util.Log;
 
 import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
@@ -595,7 +595,8 @@
             pn = util.parse(number, countryIso);
             if (VDBG) Rlog.v(TAG, "- parsed number: " + pn);
         } catch (NumberParseException e) {
-            Rlog.w(TAG, "getGeoDescription: NumberParseException for incoming number '" + number + "'");
+            Rlog.w(TAG, "getGeoDescription: NumberParseException for incoming number '"
+                    + Rlog.pii(TAG, number) + "'");
         }
 
         if (pn != null) {
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 220ea14..40d1dbb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -504,8 +504,7 @@
     boolean isVisualVoicemailEnabled(String callingPackage,
             in PhoneAccountHandle accountHandle);
 
-    String getVisualVoicemailPackageName(String callingPackage,
-            in PhoneAccountHandle phoneAccountHandle);
+    String getVisualVoicemailPackageName(String callingPackage, int subId);
 
     // Not oneway, caller needs to make sure the vaule is set before receiving a SMS
     void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 881ac87..3330b1a 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1513,6 +1513,21 @@
         err = NO_ERROR;
     }
 
+    if (mipmaps != NULL) {
+        ResourceDirIterator it(mipmaps, String8("mipmap"));
+        while ((err=it.next()) == NO_ERROR) {
+            err = postProcessImage(bundle, assets, &table, it.getFile());
+            if (err != NO_ERROR) {
+                hasErrors = true;
+            }
+        }
+
+        if (err < NO_ERROR) {
+            hasErrors = true;
+        }
+        err = NO_ERROR;
+    }
+
     if (colors != NULL) {
         ResourceDirIterator it(colors, String8("color"));
         while ((err=it.next()) == NO_ERROR) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
index af47aeb..4914a48 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -75,14 +75,14 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate(Bitmap androidBitmap, int shaderTileModeX,
-            int shaderTileModeY) {
+    /*package*/ static long nativeCreate(long nativeMatrix, Bitmap androidBitmap,
+            int shaderTileModeX, int shaderTileModeY) {
         Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
         if (bitmap == null) {
             return 0;
         }
 
-        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(
+        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(nativeMatrix,
                 bitmap.getImage(),
                 Shader_Delegate.getTileMode(shaderTileModeX),
                 Shader_Delegate.getTileMode(shaderTileModeY));
@@ -91,8 +91,9 @@
 
     // ---- Private delegate/helper methods ----
 
-    private BitmapShader_Delegate(BufferedImage image,
+    private BitmapShader_Delegate(long matrix, BufferedImage image,
             TileMode tileModeX, TileMode tileModeY) {
+        super(matrix);
         mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
index a459734..ab37968 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
@@ -63,14 +63,17 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long native_shaderA, long native_shaderB,
-            int native_mode) {
+    /*package*/ static long nativeCreate(long nativeMatrix, long native_shaderA,
+            long native_shaderB, int native_mode) {
         // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
+        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(nativeMatrix);
         return sManager.addNewDelegate(newDelegate);
     }
 
 
     // ---- Private delegate/helper methods ----
 
+    private ComposeShader_Delegate(long nativeMatrix) {
+        super(nativeMatrix);
+    }
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
index 7475c22..6a89d8f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
@@ -41,12 +41,14 @@
     /**
      * Creates the base shader and do some basic test on the parameters.
      *
+     * @param nativeMatrix reference to the shader's native transformation matrix
      * @param colors The colors to be distributed along the gradient line
      * @param positions May be null. The relative positions [0..1] of each
      *            corresponding color in the colors array. If this is null, the
      *            the colors are distributed evenly along the gradient line.
      */
-    protected Gradient_Delegate(int colors[], float positions[]) {
+    protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) {
+        super(nativeMatrix);
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
         }
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index cbc30c3..cd4393a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -56,21 +56,20 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(LinearGradient thisGradient,
+    /*package*/ static long nativeCreate1(LinearGradient thisGradient, long matrix,
             float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode) {
-        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
+        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(matrix, x0, y0,
+                x1, y1, colors, positions, Shader_Delegate.getTileMode(tileMode));
         return sManager.addNewDelegate(newDelegate);
     }
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(LinearGradient thisGradient,
+    /*package*/ static long nativeCreate2(LinearGradient thisGradient, long matrix,
             float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode) {
-        return nativeCreate1(thisGradient,
-                x0, y0, x1, y1, new int[] { color0, color1}, null /*positions*/,
-                tileMode);
+        return nativeCreate1(thisGradient, matrix, x0, y0, x1, y1, new int[] { color0, color1},
+                null /*positions*/, tileMode);
     }
 
     // ---- Private delegate/helper methods ----
@@ -78,6 +77,7 @@
     /**
      * Create a shader that draws a linear gradient along a line.
      *
+     * @param nativeMatrix reference to the shader's native transformation matrix
      * @param x0 The x-coordinate for the start of the gradient line
      * @param y0 The y-coordinate for the start of the gradient line
      * @param x1 The x-coordinate for the end of the gradient line
@@ -88,9 +88,9 @@
      *            the colors are distributed evenly along the gradient line.
      * @param tile The Shader tiling mode
      */
-    private LinearGradient_Delegate(float x0, float y0, float x1, float y1,
-            int colors[], float positions[], TileMode tile) {
-        super(colors, positions);
+    private LinearGradient_Delegate(long nativeMatrix, float x0, float y0, float x1,
+            float y1, int colors[], float positions[], TileMode tile) {
+        super(nativeMatrix, colors, positions);
         mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index 9881a38..b5ba468 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -56,18 +56,18 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(float x, float y, float radius,
+    /*package*/ static long nativeCreate1(long matrix, float x, float y, float radius,
             int colors[], float positions[], int tileMode) {
-        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius,
+        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(matrix, x, y, radius,
                 colors, positions, Shader_Delegate.getTileMode(tileMode));
         return sManager.addNewDelegate(newDelegate);
     }
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(float x, float y, float radius,
+    /*package*/ static long nativeCreate2(long matrix, float x, float y, float radius,
             int color0, int color1, int tileMode) {
-        return nativeCreate1(x, y, radius, new int[] { color0, color1 }, null /*positions*/,
-                tileMode);
+        return nativeCreate1(matrix, x, y, radius, new int[] { color0, color1 },
+                null /*positions*/, tileMode);
     }
 
     // ---- Private delegate/helper methods ----
@@ -75,6 +75,7 @@
     /**
      * Create a shader that draws a radial gradient given the center and radius.
      *
+     * @param nativeMatrix reference to the shader's native transformation matrix
      * @param x The x-coordinate of the center of the radius
      * @param y The y-coordinate of the center of the radius
      * @param radius Must be positive. The radius of the circle for this
@@ -86,9 +87,9 @@
      *            distributed evenly between the center and edge of the circle.
      * @param tile The Shader tiling mode
      */
-    private RadialGradient_Delegate(float x, float y, float radius, int colors[], float positions[],
-            TileMode tile) {
-        super(colors, positions);
+    private RadialGradient_Delegate(long nativeMatrix, float x, float y, float radius,
+            int colors[], float positions[], TileMode tile) {
+        super(nativeMatrix, colors, positions);
         mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 0d491a0..5b75089 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -76,24 +76,16 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_shader) {
-        sManager.removeJavaReferenceFor(native_shader);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeSetLocalMatrix(long native_shader, long matrix_instance) {
-        // get the delegate from the native int.
-        Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
-        if (shaderDelegate == null) {
-            return native_shader;
-        }
-
-        shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
-        return native_shader;
+    /*package*/ static void nativeSafeUnref(long nativeInstance) {
+        sManager.removeJavaReferenceFor(nativeInstance);
     }
 
     // ---- Private delegate/helper methods ----
 
+    protected Shader_Delegate(long nativeMatrix) {
+        mLocalMatrix = Matrix_Delegate.getDelegate(nativeMatrix);
+    }
+
     protected java.awt.geom.AffineTransform getLocalMatrix() {
         if (mLocalMatrix != null) {
             return mLocalMatrix.getAffineTransform();
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 544ba98..30152bc 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -52,14 +52,17 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(float x, float y, int colors[], float positions[]) {
-        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(x, y, colors, positions);
+    /*package*/ static long nativeCreate1(long matrix, float x, float y, int colors[], float
+            positions[]) {
+        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(matrix, x, y, colors,
+                positions);
         return sManager.addNewDelegate(newDelegate);
     }
 
     @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(float x, float y, int color0, int color1) {
-        return nativeCreate1(x, y, new int[] { color0, color1 }, null /*positions*/);
+    /*package*/ static long nativeCreate2(long matrix, float x, float y, int color0, int color1) {
+        return nativeCreate1(matrix, x, y, new int[] { color0, color1 },
+                null /*positions*/);
     }
 
     // ---- Private delegate/helper methods ----
@@ -67,6 +70,7 @@
     /**
      * A subclass of Shader that draws a sweep gradient around a center point.
      *
+     * @param nativeMatrix reference to the shader's native transformation matrix
      * @param cx       The x-coordinate of the center
      * @param cy       The y-coordinate of the center
      * @param colors   The colors to be distributed between around the center.
@@ -78,9 +82,9 @@
      *                 If positions is NULL, then the colors are automatically
      *                 spaced evenly.
      */
-    private SweepGradient_Delegate(float cx, float cy,
-                         int colors[], float positions[]) {
-        super(colors, positions);
+    private SweepGradient_Delegate(long nativeMatrix, float cx, float cy,
+            int colors[], float positions[]) {
+        super(nativeMatrix, colors, positions);
         mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 04fdae9..3276628 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -640,7 +640,7 @@
             return AccessibilityManager.getInstance(this);
         }
 
-        if (AUTO_FILL_MANAGER_SERVICE.equals(service)) {
+        if (AUTOFILL_MANAGER_SERVICE.equals(service)) {
             return null;
         }
 
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index 156c3fd..82b3792 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.net.wifi.RttManager;
 import android.util.Log;
 
@@ -33,7 +34,8 @@
  * <ul>
  *     <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
  *     <li>Creating a network-specifier when requesting a Aware connection:
- *     {@link #createNetworkSpecifier(PeerHandle, byte[])}.
+ *     {@link #createNetworkSpecifierOpen(PeerHandle)} or
+ *     {@link #createNetworkSpecifierPassphrase(PeerHandle, String)}.
  * </ul>
  * The {@link #destroy()} method must be called to destroy discovery sessions once they are
  * no longer needed.
@@ -255,7 +257,7 @@
      * <p>
      * This method should be used when setting up a connection with a peer discovered through Aware
      * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
+     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
      * OOB (out-of-band) mechanism then use the alternative
      * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the
      * peer's MAC address.
@@ -263,24 +265,22 @@
      * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
      * and a Publisher is a RESPONDER.
      * <p>
-     * To set up an encrypted link use the {@link #createNetworkSpecifierPmk(PeerHandle, byte[])}
-     * or {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} APIs.
+     * To set up an encrypted link use the
+     * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API.
      *
      * @param peerHandle The peer's handle obtained through
      * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
      *                   or
      *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
      *                   On a RESPONDER this value is used to gate the acceptance of a connection
-     *                   request from only that peer. A RESPONDER may specify a null - indicating
-     *                   that it will accept connection requests from any device.
+     *                   request from only that peer. A RESPONDER may specify a {@code null} -
+     *                   indicating that it will accept connection requests from any device.
      *
      * @return A string to be used to construct
      * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
-     *
-     * @hide
      */
     public String createNetworkSpecifierOpen(@Nullable PeerHandle peerHandle) {
         if (mTerminated) {
@@ -309,7 +309,7 @@
      * <p>
      * This method should be used when setting up a connection with a peer discovered through Aware
      * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
+     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
      * OOB (out-of-band) mechanism then use the alternative
      * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)} method -
      * which uses the peer's MAC address.
@@ -322,12 +322,11 @@
      * byte[], java.util.List)} or
      * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
      * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
-     *                   from only that peer. A RESPONDER may specify a null - indicating that
-     *                   it will accept connection requests from any device.
+     *                   from only that peer. A RESPONDER may specify a {@code null} - indicating
+     *                   that it will accept connection requests from any device.
      * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
      *                   the passphrase. Use the
-     *                   {@link #createNetworkSpecifierPmk(PeerHandle, byte[])} to specify the
-     *                   PMK directly or {@link #createNetworkSpecifierOpen(PeerHandle)} to
+     *                   {@link #createNetworkSpecifierOpen(PeerHandle)} API to
      *                   specify an open (unencrypted) link.
      *
      * @return A string to be used to construct
@@ -335,8 +334,6 @@
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
-     *
-     * * @hide
      */
     public String createNetworkSpecifierPassphrase(@Nullable PeerHandle peerHandle,
             @NonNull String passphrase) {
@@ -371,7 +368,7 @@
      * <p>
      * This method should be used when setting up a connection with a peer discovered through Aware
      * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
+     * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other
      * OOB (out-of-band) mechanism then use the alternative
      * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses
      * the peer's MAC address.
@@ -400,6 +397,7 @@
      *
      * @hide
      */
+    @SystemApi
     public String createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
             @NonNull byte[] pmk) {
         if (pmk == null || pmk.length == 0) {
@@ -423,27 +421,4 @@
 
         return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk, null);
     }
-
-    /**
-     * Place-holder for {@code createNetworkSpecifierOpen(PeerHandle)}. Present to enable
-     * development of replacements CL without causing an API change. Will be removed when new
-     * APIs are exposed.
-     *
-     * @param peerHandle The peer's handle obtained through
-     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
-     * byte[], java.util.List)} or
-     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
-     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
-     *                   from only that peer. A RESPONDER may specify a null - indicating that
-     *                   it will accept connection requests from any device.
-     * @param token Deprecated and ignored.
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    public String createNetworkSpecifier(@Nullable PeerHandle peerHandle, @Nullable byte[] token) {
-        return createNetworkSpecifierOpen(peerHandle);
-    }
 }
diff --git a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
index cae8706..81a06e8 100644
--- a/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
+++ b/wifi/java/android/net/wifi/aware/IdentityChangedListener.java
@@ -24,7 +24,8 @@
  * your identity - e.g. by starting a discovery session. This actual MAC address of the
  * interface may also be useful if the application uses alternative (non-Aware) discovery but needs
  * to set up a Aware connection. The provided Aware discovery interface MAC address can then be used
- * in {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
+ * in {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
+ * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)}.
  */
 public class IdentityChangedListener {
     /**
diff --git a/wifi/java/android/net/wifi/aware/PeerHandle.java b/wifi/java/android/net/wifi/aware/PeerHandle.java
index bbe9f54..cd45c52 100644
--- a/wifi/java/android/net/wifi/aware/PeerHandle.java
+++ b/wifi/java/android/net/wifi/aware/PeerHandle.java
@@ -19,9 +19,10 @@
 /**
  * Opaque object used to represent a Wi-Fi Aware peer. Obtained from discovery sessions in
  * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}, used
- * when sending messages e,g, {@link PublishDiscoverySession#sendMessage(PeerHandle, int, byte[])},
+ * when sending messages e,g, {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])},
  * or when configuring a network link to a peer, e.g.
- * {@link PublishDiscoverySession#createNetworkSpecifier(PeerHandle, byte[])}.
+ * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or
+ * {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
  */
 public class PeerHandle {
     /** @hide */
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 7b6805c..4d3957a 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -65,8 +65,10 @@
  * <li>Create a Aware network specifier to be used with
  * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
  * to set-up a Aware connection with a peer. Refer to
- * {@link DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])} and
- * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
+ * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)},
+ * {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)},
+ * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])}, and
+ * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)}.
  * </ul>
  * <p>
  *     Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
@@ -115,8 +117,10 @@
  *        <li>{@link NetworkRequest.Builder#addTransportType(int)} of
  *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
  *        <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- *        {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or
- *        {@link DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])}.
+ *        {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])},
+ *        {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)},
+ *        {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)}, or
+ *        {@link DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)}.
  *    </ul>
  */
 public class WifiAwareManager {
@@ -206,8 +210,10 @@
      * Connection creation role is that of INITIATOR. Used to create a network specifier string
      * when requesting a Aware network.
      *
-     * @see DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])
-     * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
+     * @see DiscoverySession#createNetworkSpecifierOpen(PeerHandle)
+     * @see DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)
+     * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
+     * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
      */
     public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
 
@@ -215,8 +221,10 @@
      * Connection creation role is that of RESPONDER. Used to create a network specifier string
      * when requesting a Aware network.
      *
-     * @see DiscoverySession#createNetworkSpecifier(PeerHandle, byte[])
-     * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
+     * @see DiscoverySession#createNetworkSpecifierOpen(PeerHandle)
+     * @see DiscoverySession#createNetworkSpecifierPassphrase(PeerHandle, String)
+     * @see WifiAwareSession#createNetworkSpecifierOpen(int, byte[])
+     * @see WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)
      */
     public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
 
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index f48f641..895defb 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
@@ -193,15 +194,15 @@
      *     when using Aware discovery use the alternative network specifier method -
      *     {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)}.
      * <p>
-     * To set up an encrypted link use the {@link #createNetworkSpecifierPmk(int, byte[], byte[])}
-     * or {@link #createNetworkSpecifierPassphrase(int, byte[], String)} APIs.
+     * To set up an encrypted link use the
+     * {@link #createNetworkSpecifierPassphrase(int, byte[], String)} API.
      *
      * @param role  The role of this device:
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
      * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
      *              value is used to gate the acceptance of a connection request from only that
-     *              peer. A RESPONDER may specify a null - indicating that it will accept
+     *              peer. A RESPONDER may specify a {@code null} - indicating that it will accept
      *              connection requests from any device.
      *
      * @return A string to be used to construct
@@ -209,8 +210,6 @@
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
-     *
-     * @hide
      */
     public String createNetworkSpecifierOpen(@WifiAwareManager.DataPathRole int role,
             @Nullable byte[] peer) {
@@ -242,12 +241,10 @@
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
      * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
      *              value is used to gate the acceptance of a connection request from only that
-     *              peer. A RESPONDER may specify a null - indicating that it will accept
+     *              peer. A RESPONDER may specify a {@code null} - indicating that it will accept
      *              connection requests from any device.
      * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from
-     *                   the passphrase. Use the
-     *                   {@link #createNetworkSpecifierPmk(int, byte[], byte[])} to specify the
-     *                   PMK directly or {@link #createNetworkSpecifierOpen(int, byte[])} to
+     *                   the passphrase. Use {@link #createNetworkSpecifierOpen(int, byte[])} to
      *                   specify an open (unencrypted) link.
      *
      * @return A string to be used to construct
@@ -255,8 +252,6 @@
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
-     *
-     * @hide
      */
     public String createNetworkSpecifierPassphrase(@WifiAwareManager.DataPathRole int role,
             @Nullable byte[] peer, @NonNull String passphrase) {
@@ -307,6 +302,7 @@
      *
      * @hide
      */
+    @SystemApi
     public String createNetworkSpecifierPmk(@WifiAwareManager.DataPathRole int role,
             @Nullable byte[] peer, @NonNull byte[] pmk) {
         WifiAwareManager mgr = mMgr.get();
@@ -323,28 +319,4 @@
         }
         return mgr.createNetworkSpecifier(mClientId, role, peer, pmk, null);
     }
-
-    /**
-     * Place-holder for {@code #createNetworkSpecifierOpen(int, byte[])}. Present to enable
-     * development of replacements CL without causing an API change. Will be removed when new
-     * APIs are exposed.
-     *
-     * @param role  The role of this device:
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
-     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
-     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
-     *              value is used to gate the acceptance of a connection request from only that
-     *              peer. A RESPONDER may specify a null - indicating that it will accept
-     *              connection requests from any device.
-     * @param token Deprecated and ignored.
-     * @return A string to be used to construct
-     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
-     * android.net.ConnectivityManager.NetworkCallback)}
-     * [or other varieties of that API].
-     */
-    public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
-            @Nullable byte[] peer, @Nullable byte[] token) {
-        return createNetworkSpecifierOpen(role, peer);
-    }
 }