Merge "Allow the support library to add its own droiddoc options"
diff --git a/api/current.txt b/api/current.txt
index 2644372..2276012 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5415,6 +5415,7 @@
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
+    method public android.os.Bundle getExtras();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
@@ -5548,12 +5549,14 @@
     method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
     method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
     method public void deleteNotificationChannel(java.lang.String);
+    method public void deleteNotificationChannelGroup(java.lang.String);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.Map<java.lang.String, android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
     method public int getImportance();
     method public android.app.NotificationChannel getNotificationChannel(java.lang.String);
+    method public java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups();
     method public java.util.List<android.app.NotificationChannel> getNotificationChannels();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
@@ -5715,6 +5718,8 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.RemoteAction> CREATOR;
   }
@@ -7120,6 +7125,7 @@
     method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
     method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
     method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+    method public int getLeMaximumAdvertisingDataLength();
     method public java.lang.String getName();
     method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
     method public int getProfileConnectionState(int);
@@ -10670,6 +10676,7 @@
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
+    field public static final java.lang.String FEATURE_VR_HEADTRACKING = "android.hardware.vr.headtracking";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
@@ -12755,7 +12762,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -12779,6 +12786,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13002,6 +13012,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -13518,6 +13532,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -37155,11 +37173,11 @@
     field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
     field public static final int REASON_APP_CANCEL = 8; // 0x8
     field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9
+    field public static final int REASON_CANCEL = 2; // 0x2
+    field public static final int REASON_CANCEL_ALL = 3; // 0x3
     field public static final int REASON_CHANNEL_BANNED = 17; // 0x11
-    field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2
-    field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3
-    field public static final int REASON_DELEGATE_CLICK = 1; // 0x1
-    field public static final int REASON_DELEGATE_ERROR = 4; // 0x4
+    field public static final int REASON_CLICK = 1; // 0x1
+    field public static final int REASON_ERROR = 4; // 0x4
     field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
     field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc
     field public static final int REASON_LISTENER_CANCEL = 10; // 0xa
@@ -45073,8 +45091,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 boolean autofill(android.view.autofill.AutofillValue);
+    method public boolean autofill(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -46289,7 +46307,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 asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46298,7 +46316,7 @@
     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 newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
@@ -47570,11 +47588,11 @@
     method public void commit();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
+    method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     method public void notifyViewEntered(android.view.View);
+    method public void notifyViewEntered(android.view.View, int, android.graphics.Rect);
     method public void notifyViewExited(android.view.View);
-    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
-    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
-    method public void notifyVirtualViewExited(android.view.View, int);
+    method public void notifyViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void requestAutofill(android.view.View);
     method public void requestAutofill(android.view.View, int, android.graphics.Rect);
@@ -47587,9 +47605,10 @@
   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);
+    method public void onAutofillEvent(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
+    field public static final int EVENT_INPUT_UNAVAILABLE = 3; // 0x3
   }
 
   public final class AutofillValue implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index eb5ebd7..ae510c9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5589,6 +5589,7 @@
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
+    method public android.os.Bundle getExtras();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
@@ -5751,12 +5752,14 @@
     method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
     method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
     method public void deleteNotificationChannel(java.lang.String);
+    method public void deleteNotificationChannelGroup(java.lang.String);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.Map<java.lang.String, android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
     method public int getImportance();
     method public android.app.NotificationChannel getNotificationChannel(java.lang.String);
+    method public java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups();
     method public java.util.List<android.app.NotificationChannel> getNotificationChannels();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
@@ -5918,6 +5921,8 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.RemoteAction> CREATOR;
   }
@@ -7589,6 +7594,7 @@
     method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
     method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
     method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+    method public int getLeMaximumAdvertisingDataLength();
     method public java.lang.String getName();
     method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
     method public int getProfileConnectionState(int);
@@ -11328,6 +11334,7 @@
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
+    field public static final java.lang.String FEATURE_VR_HEADTRACKING = "android.hardware.vr.headtracking";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
@@ -13489,7 +13496,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -13513,6 +13520,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13736,6 +13746,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -14252,6 +14266,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -34415,6 +34433,7 @@
     method public deprecated void setUserRestrictions(android.os.Bundle);
     method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
     method public static boolean supportsMultipleUsers();
+    field public static final java.lang.String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
     field public static final java.lang.String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
     field public static final java.lang.String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
     field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
@@ -40226,11 +40245,11 @@
     field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
     field public static final int REASON_APP_CANCEL = 8; // 0x8
     field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9
+    field public static final int REASON_CANCEL = 2; // 0x2
+    field public static final int REASON_CANCEL_ALL = 3; // 0x3
     field public static final int REASON_CHANNEL_BANNED = 17; // 0x11
-    field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2
-    field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3
-    field public static final int REASON_DELEGATE_CLICK = 1; // 0x1
-    field public static final int REASON_DELEGATE_ERROR = 4; // 0x4
+    field public static final int REASON_CLICK = 1; // 0x1
+    field public static final int REASON_ERROR = 4; // 0x4
     field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
     field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc
     field public static final int REASON_LISTENER_CANCEL = 10; // 0xa
@@ -48536,8 +48555,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 boolean autofill(android.view.autofill.AutofillValue);
+    method public boolean autofill(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -49752,7 +49771,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 asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -49761,7 +49780,7 @@
     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 newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
@@ -51036,11 +51055,11 @@
     method public void commit();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
+    method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     method public void notifyViewEntered(android.view.View);
+    method public void notifyViewEntered(android.view.View, int, android.graphics.Rect);
     method public void notifyViewExited(android.view.View);
-    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
-    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
-    method public void notifyVirtualViewExited(android.view.View, int);
+    method public void notifyViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void requestAutofill(android.view.View);
     method public void requestAutofill(android.view.View, int, android.graphics.Rect);
@@ -51053,9 +51072,10 @@
   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);
+    method public void onAutofillEvent(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
+    field public static final int EVENT_INPUT_UNAVAILABLE = 3; // 0x3
   }
 
   public final class AutofillValue implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3b02916..ea3e6e2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5425,6 +5425,7 @@
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
+    method public android.os.Bundle getExtras();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
@@ -5558,6 +5559,7 @@
     method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup>);
     method public void createNotificationChannels(java.util.List<android.app.NotificationChannel>);
     method public void deleteNotificationChannel(java.lang.String);
+    method public void deleteNotificationChannelGroup(java.lang.String);
     method public android.service.notification.StatusBarNotification[] getActiveNotifications();
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.Map<java.lang.String, android.app.AutomaticZenRule> getAutomaticZenRules();
@@ -5565,6 +5567,7 @@
     method public android.content.ComponentName getEffectsSuppressor();
     method public int getImportance();
     method public android.app.NotificationChannel getNotificationChannel(java.lang.String);
+    method public java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups();
     method public java.util.List<android.app.NotificationChannel> getNotificationChannels();
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
@@ -5726,6 +5729,8 @@
     method public java.lang.CharSequence getContentDescription();
     method public android.graphics.drawable.Icon getIcon();
     method public java.lang.CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.RemoteAction> CREATOR;
   }
@@ -7147,6 +7152,7 @@
     method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
     method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
     method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+    method public int getLeMaximumAdvertisingDataLength();
     method public java.lang.String getName();
     method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
     method public int getProfileConnectionState(int);
@@ -10706,6 +10712,7 @@
     field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory";
     field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host";
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
+    field public static final java.lang.String FEATURE_VR_HEADTRACKING = "android.hardware.vr.headtracking";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
@@ -12793,7 +12800,7 @@
   }
 
   public class ColorFilter {
-    ctor public ColorFilter();
+    ctor public deprecated ColorFilter();
   }
 
   public class ColorMatrix {
@@ -12817,6 +12824,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public void getColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrixArray(float[]);
   }
 
   public abstract class ColorSpace {
@@ -13040,6 +13050,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -13556,6 +13570,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -31717,6 +31735,7 @@
     method public deprecated void setUserRestrictions(android.os.Bundle);
     method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
     method public static boolean supportsMultipleUsers();
+    field public static final java.lang.String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
     field public static final java.lang.String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
     field public static final java.lang.String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
     field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user";
@@ -37331,11 +37350,11 @@
     field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
     field public static final int REASON_APP_CANCEL = 8; // 0x8
     field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9
+    field public static final int REASON_CANCEL = 2; // 0x2
+    field public static final int REASON_CANCEL_ALL = 3; // 0x3
     field public static final int REASON_CHANNEL_BANNED = 17; // 0x11
-    field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2
-    field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3
-    field public static final int REASON_DELEGATE_CLICK = 1; // 0x1
-    field public static final int REASON_DELEGATE_ERROR = 4; // 0x4
+    field public static final int REASON_CLICK = 1; // 0x1
+    field public static final int REASON_ERROR = 4; // 0x4
     field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd
     field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc
     field public static final int REASON_LISTENER_CANCEL = 10; // 0xa
@@ -45433,8 +45452,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 boolean autofill(android.view.autofill.AutofillValue);
+    method public boolean autofill(int, android.view.autofill.AutofillValue);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -46656,7 +46675,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 asyncNewChild(int, int, int);
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46665,7 +46684,7 @@
     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 newChild(int, int, int);
     method public abstract void setAccessibilityFocused(boolean);
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
@@ -47939,11 +47958,11 @@
     method public void commit();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
+    method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
     method public void notifyViewEntered(android.view.View);
+    method public void notifyViewEntered(android.view.View, int, android.graphics.Rect);
     method public void notifyViewExited(android.view.View);
-    method public void notifyVirtualValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
-    method public void notifyVirtualViewEntered(android.view.View, int, android.graphics.Rect);
-    method public void notifyVirtualViewExited(android.view.View, int);
+    method public void notifyViewExited(android.view.View, int);
     method public void registerCallback(android.view.autofill.AutofillManager.AutofillCallback);
     method public void requestAutofill(android.view.View);
     method public void requestAutofill(android.view.View, int, android.graphics.Rect);
@@ -47956,9 +47975,10 @@
   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);
+    method public void onAutofillEvent(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
+    field public static final int EVENT_INPUT_UNAVAILABLE = 3; // 0x3
   }
 
   public final class AutofillValue implements android.os.Parcelable {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index e5df278..75d4f32 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -21,8 +21,11 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
 import android.annotation.Size;
 import android.annotation.SystemApi;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.BroadcastBehavior;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -335,6 +338,8 @@
      *
      * @deprecated use #addOnAccountsUpdatedListener to get account updates in runtime.
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(includeBackground = true)
     public static final String LOGIN_ACCOUNTS_CHANGED_ACTION =
         "android.accounts.LOGIN_ACCOUNTS_CHANGED";
 
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 86adbb0..5c7a12c 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -431,31 +431,28 @@
 
     // Force all the animations to end when the duration scale is 0.
     private void forceToEnd() {
-        if (mEndCanBeCalled) {
-            end();
+        // TODO: Below is commented out to temp work around b/36241584, uncomment this when it's
+        // fixed.
+//        if (mEndCanBeCalled) {
+//            end();
+//            return;
+//        }
+
+        // Note: we don't want to combine this case with the end() method below because in
+        // the case of developer calling end(), we still need to make sure end() is explicitly
+        // called on the child animators to maintain the old behavior.
+        if (mReversing) {
+            handleAnimationEvents(mLastEventId, 0, getTotalDuration());
         } else {
-            // Note: we don't want to combine this case with the end() method below because in
-            // the case of developer calling end(), we still need to make sure end() is explicitly
-            // called on the child animators to maintain the old behavior.
-            if (mReversing) {
-                mLastEventId = mLastEventId == -1 ? mEvents.size() : mLastEventId;
-                for (int j = mLastEventId - 1; j >= 0; j--) {
-                    AnimationEvent event = mEvents.get(j);
-                    if (event.mEvent == AnimationEvent.ANIMATION_END) {
-                        event.mNode.mAnimation.reverse();
-                    }
-                }
-            } else {
-                for (int j = mLastEventId + 1; j < mEvents.size(); j++) {
-                    AnimationEvent event = mEvents.get(j);
-                    if (event.mEvent == AnimationEvent.ANIMATION_START) {
-                        event.mNode.mAnimation.start();
-                    }
-                }
+            long zeroScalePlayTime = getTotalDuration();
+            if (zeroScalePlayTime == DURATION_INFINITE) {
+                // Use a large number for the play time.
+                zeroScalePlayTime = Integer.MAX_VALUE;
             }
-            mPlayingSet.clear();
-            endAnimation();
+            handleAnimationEvents(mLastEventId, mEvents.size() - 1, zeroScalePlayTime);
         }
+        mPlayingSet.clear();
+        endAnimation();
     }
 
     /**
@@ -730,7 +727,7 @@
         if (isEmptySet) {
             // In the case of empty AnimatorSet, or 0 duration scale, we will trigger the
             // onAnimationEnd() right away.
-            forceToEnd();
+            end();
         }
     }
 
@@ -1130,8 +1127,10 @@
      */
     private void pulseFrame(Node node, long animPlayTime) {
         if (!node.mEnded) {
+            float durationScale = ValueAnimator.getDurationScale();
+            durationScale = durationScale == 0  ? 1 : durationScale;
             node.mEnded = node.mAnimation.pulseAnimationFrame(
-                    (long) (animPlayTime * ValueAnimator.getDurationScale()));
+                    (long) (animPlayTime * durationScale));
         }
     }
 
diff --git a/core/java/android/annotation/BroadcastBehavior.java b/core/java/android/annotation/BroadcastBehavior.java
new file mode 100644
index 0000000..9b2ca31
--- /dev/null
+++ b/core/java/android/annotation/BroadcastBehavior.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 android.annotation;
+
+import android.content.Intent;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Description of how the annotated broadcast action behaves.
+ *
+ * @hide
+ */
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.SOURCE)
+public @interface BroadcastBehavior {
+    /**
+     * This broadcast will only be delivered to an explicit target.
+     *
+     * @see Intent#setPackage(String)
+     * @see Intent#setComponent(android.content.ComponentName)
+     */
+    boolean explicitOnly() default false;
+
+    /**
+     * This broadcast will only be delivered to registered receivers.
+     *
+     * @see Intent#FLAG_RECEIVER_REGISTERED_ONLY
+     */
+    boolean registeredOnly() default false;
+
+    /**
+     * This broadcast will include all {@code AndroidManifest.xml} receivers
+     * regardless of process state.
+     *
+     * @see Intent#FLAG_RECEIVER_INCLUDE_BACKGROUND
+     */
+    boolean includeBackground() default false;
+}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 78c29e8..37a11ec 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.metrics.LogMaker;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
@@ -23,6 +24,8 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.policy.PhoneWindow;
 
 import android.annotation.CallSuper;
@@ -765,6 +768,7 @@
     /*package*/ Configuration mCurrentConfig;
     private SearchManager mSearchManager;
     private MenuInflater mMenuInflater;
+    private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     static final class NonConfigurationInstances {
         Object activity;
@@ -7188,6 +7192,8 @@
     public void autofill(List<AutofillId> ids, List<AutofillValue> values) {
         final View root = getWindow().getDecorView();
         final int itemCount = ids.size();
+        int numApplied = 0;
+
         for (int i = 0; i < itemCount; i++) {
             final AutofillId id = ids.get(i);
             final AutofillValue value = values.get(i);
@@ -7197,12 +7203,22 @@
                 Log.w(TAG, "autofill(): no View with id " + viewId);
                 continue;
             }
+            final boolean wasApplied;
             if (id.isVirtual()) {
-                view.autofillVirtual(id.getVirtualChildId(), value);
+                wasApplied = view.autofill(id.getVirtualChildId(), value);
             } else {
-                view.autofill(value);
+                wasApplied = view.autofill(value);
+            }
+
+            if (wasApplied) {
+                numApplied++;
             }
         }
+
+        LogMaker log = new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_DATASET_APPLIED);
+        log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, itemCount);
+        log.addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, numApplied);
+        mMetricsLogger.write(log);
     }
 
     /** @hide */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5cdfb8e..6b53cd8 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -149,6 +149,7 @@
 import libcore.io.EventLogger;
 import libcore.io.IoUtils;
 import libcore.net.event.NetworkEventDispatcher;
+import dalvik.system.BaseDexClassLoader;
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
@@ -336,6 +337,8 @@
         Configuration overrideConfig;
         // Used for consolidating configs before sending on to Activity.
         private Configuration tmpConfig = new Configuration();
+        // Callback used for updating activity override config.
+        ViewRootImpl.ActivityConfigCallback configCallback;
         ActivityClientRecord nextIdle;
 
         ProfilerInfo profilerInfo;
@@ -371,6 +374,14 @@
             stopped = false;
             hideForNow = false;
             nextIdle = null;
+            configCallback = (Configuration overrideConfig, int newDisplayId) -> {
+                if (activity == null) {
+                    throw new IllegalStateException(
+                            "Received config update for non-existing activity");
+                }
+                activity.mMainThread.handleActivityConfigurationChanged(
+                        new ActivityConfigChangeData(token, overrideConfig), newDisplayId);
+            };
         }
 
         public boolean isPreHoneycomb() {
@@ -3680,6 +3691,12 @@
                 if (r.activity.mVisibleFromClient) {
                     r.activity.makeVisible();
                 }
+                final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl();
+                if (viewRoot != null) {
+                    // TODO: Figure out the best place to set the callback.
+                    // This looks like a place where decor view is already initialized.
+                    viewRoot.setActivityConfigCallback(r.configCallback);
+                }
             }
 
             if (!r.onlyLocalRequest) {
@@ -5028,7 +5045,7 @@
      * @param displayId Id of the display where activity was moved to, -1 if there was no move and
      *                  value didn't change.
      */
-    private void handleActivityConfigurationChanged(ActivityConfigChangeData data, int displayId) {
+    void handleActivityConfigurationChanged(ActivityConfigChangeData data, int displayId) {
         ActivityClientRecord r = mActivities.get(data.activityToken);
         // Check input params.
         if (r == null || r.activity == null) {
@@ -5045,6 +5062,7 @@
 
         // Perform updates.
         r.overrideConfig = data.overrideConfig;
+        final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl();
         if (movedToDifferentDisplay) {
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity moved to display, activity:"
                     + r.activityInfo.name + ", displayId=" + displayId
@@ -5052,13 +5070,15 @@
 
             performConfigurationChangedForActivity(r, mCompatConfiguration, displayId,
                     true /* movedToDifferentDisplay */);
-            final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl();
             viewRoot.onMovedToDisplay(displayId);
         } else {
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
                     + r.activityInfo.name + ", config=" + data.overrideConfig);
             performConfigurationChangedForActivity(r, mCompatConfiguration);
         }
+        // Notify the ViewRootImpl instance about configuration changes. It may have initiated this
+        // update to make sure that resources are updated before updating itself.
+        viewRoot.updateConfiguration();
         mSomeActivitiesChanged = true;
     }
 
@@ -5571,6 +5591,16 @@
             }
         }
 
+        // If we use profiles, setup the dex reporter to notify package manager
+        // of any relevant dex loads. The idle maintenance job will use the information
+        // reported to optimize the loaded dex files.
+        // Note that we only need one global reporter per app.
+        // Make sure we do this before calling onCreate so that we can capture the
+        // complete application startup.
+        if (SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
+            BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
+        }
+
         // Install the Network Security Config Provider. This must happen before the application
         // code is loaded to prevent issues with instances of TLS objects being created before
         // the provider is installed.
@@ -6284,35 +6314,26 @@
         // add dropbox logging to libcore
         DropBox.setReporter(new DropBoxReporter());
 
-        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
-            @Override
-            public void onConfigurationChanged(Configuration newConfig) {
-                synchronized (mResourcesManager) {
-                    // We need to apply this change to the resources
-                    // immediately, because upon returning the view
-                    // hierarchy will be informed about it.
-                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
-                        updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
-                                mResourcesManager.getConfiguration().getLocales());
+        ViewRootImpl.ConfigChangedCallback configChangedCallback
+                = (Configuration globalConfig) -> {
+            synchronized (mResourcesManager) {
+                // We need to apply this change to the resources immediately, because upon returning
+                // the view hierarchy will be informed about it.
+                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
+                        null /* compat */)) {
+                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
+                            mResourcesManager.getConfiguration().getLocales());
 
-                        // This actually changed the resources!  Tell
-                        // everyone about it.
-                        if (mPendingConfiguration == null ||
-                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
-                            mPendingConfiguration = newConfig;
-
-                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
-                        }
+                    // This actually changed the resources! Tell everyone about it.
+                    if (mPendingConfiguration == null
+                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
+                        mPendingConfiguration = globalConfig;
+                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                     }
                 }
             }
-            @Override
-            public void onLowMemory() {
-            }
-            @Override
-            public void onTrimMemory(int level) {
-            }
-        });
+        };
+        ViewRootImpl.addConfigCallback(configChangedCallback);
     }
 
     public static ActivityThread systemMain() {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0f2ce3c..09e7595 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -362,6 +362,8 @@
     public static final String OPSTR_ANSWER_PHONE_CALLS
             = "android:answer_phone_calls";
 
+    // Warning: If an permission is added here it also has to be added to
+    // com.android.packageinstaller.permission.utils.EventLogger
     private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
             // RUNTIME PERMISSIONS
             // Contacts
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 9f1a539..e645261 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -22,6 +22,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.os.Binder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemProperties;
@@ -430,7 +431,7 @@
             dest.writeInt(throwLineNumber);
             dest.writeString(stackTrace);
             int total = dest.dataPosition()-start;
-            if (total > 20*1024) {
+            if (Binder.CHECK_PARCEL_SIZE && total > 20*1024) {
                 Slog.d("Error", "ERR: exClass=" + exceptionClassName);
                 Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
                 Slog.d("Error", "ERR: file=" + throwFileName);
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
new file mode 100644
index 0000000..13f288a
--- /dev/null
+++ b/core/java/android/app/DexLoadReporter.java
@@ -0,0 +1,168 @@
+/*
+ * 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.app;
+
+import android.os.FileUtils;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import dalvik.system.BaseDexClassLoader;
+import dalvik.system.VMRuntime;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A dex load reporter which will notify package manager of any dex file loaded
+ * with {@code BaseDexClassLoader}.
+ * The goals are:
+ *     1) discover secondary dex files so that they can be optimized during the
+ *        idle maintenance job.
+ *     2) determine whether or not a dex file is used by an app which does not
+ *        own it (in order to select the optimal compilation method).
+ * @hide
+ */
+/*package*/ class DexLoadReporter implements BaseDexClassLoader.Reporter {
+    private static final String TAG = "DexLoadReporter";
+
+    private static final DexLoadReporter INSTANCE = new DexLoadReporter();
+
+    private static final boolean DEBUG = false;
+
+    // We must guard the access to the list of data directories because
+    // we might have concurrent accesses. Apps might load dex files while
+    // new data dirs are registered (due to creation of LoadedApks via
+    // create createApplicationContext).
+    @GuardedBy("mDataDirs")
+    private final Set<String> mDataDirs;
+
+    private DexLoadReporter() {
+        mDataDirs = new HashSet<>();
+    }
+
+    /*package*/ static DexLoadReporter getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Register an application data directory with the reporter.
+     * The data directories are used to determine if a dex file is secondary dex or not.
+     * Note that this method may be called multiple times for the same app, registering
+     * different data directories. This may happen when apps share the same user id
+     * ({@code android:sharedUserId}). For example, if app1 and app2 share the same user
+     * id, and app1 loads app2 apk, then both data directories will be registered.
+     */
+    /*package*/ void registerAppDataDir(String packageName, String dataDir) {
+        if (DEBUG) {
+            Slog.i(TAG, "Package " + packageName + " registering data dir: " + dataDir);
+        }
+        // TODO(calin): A few code paths imply that the data dir
+        // might be null. Investigate when that can happen.
+        if (dataDir != null) {
+            synchronized (mDataDirs) {
+                mDataDirs.add(dataDir);
+            }
+        }
+    }
+
+    @Override
+    public void report(List<String> dexPaths) {
+        if (dexPaths.isEmpty()) {
+            return;
+        }
+        // Notify the package manager about the dex loads unconditionally.
+        // The load might be for either a primary or secondary dex file.
+        notifyPackageManager(dexPaths);
+        // Check for secondary dex files and register them for profiling if
+        // possible.
+        registerSecondaryDexForProfiling(dexPaths);
+    }
+
+    private void notifyPackageManager(List<String> dexPaths) {
+        String packageName = ActivityThread.currentPackageName();
+        try {
+            ActivityThread.getPackageManager().notifyDexLoad(
+                    packageName, dexPaths, VMRuntime.getRuntime().vmInstructionSet());
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Failed to notify PM about dex load for package " + packageName, re);
+        }
+    }
+
+    private void registerSecondaryDexForProfiling(List<String> dexPaths) {
+        if (!SystemProperties.getBoolean("dalvik.vm.dexopt.secondary", false)) {
+            return;
+        }
+        // Make a copy of the current data directories so that we don't keep the lock
+        // while registering for profiling. The registration will perform I/O to
+        // check for or create the profile.
+        String[] dataDirs;
+        synchronized (mDataDirs) {
+            dataDirs = mDataDirs.toArray(new String[0]);
+        }
+        for (String dexPath : dexPaths) {
+            registerSecondaryDexForProfiling(dexPath, dataDirs);
+        }
+    }
+
+    private void registerSecondaryDexForProfiling(String dexPath, String[] dataDirs) {
+        if (!isSecondaryDexFile(dexPath, dataDirs)) {
+            // The dex path is not a secondary dex file. Nothing to do.
+            return;
+        }
+        File secondaryProfile = getSecondaryProfileFile(dexPath);
+        try {
+            // Create the profile if not already there.
+            // Returns true if the file was created, false if the file already exists.
+            // or throws exceptions in case of errors.
+            boolean created = secondaryProfile.createNewFile();
+            if (DEBUG && created) {
+                Slog.i(TAG, "Created profile for secondary dex: " + secondaryProfile);
+            }
+        } catch (IOException ex) {
+            Slog.e(TAG, "Failed to create profile for secondary dex " + secondaryProfile +
+                    ":" + ex.getMessage());
+            // Don't move forward with the registration if we failed to create the profile.
+            return;
+        }
+
+        VMRuntime.registerAppInfo(secondaryProfile.getPath(), new String[] { dexPath });
+    }
+
+    // A dex file is a secondary dex file if it is in any of the registered app
+    // data directories.
+    private boolean isSecondaryDexFile(String dexPath, String[] dataDirs) {
+        for (String dataDir : dataDirs) {
+            if (FileUtils.contains(dataDir, dexPath)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Secondary dex profiles are stored next to the dex file and have the same
+    // name with '.prof' appended.
+    // NOTE: Keep in sync with installd.
+    private File getSecondaryProfileFile(String dexPath) {
+        return new File(dexPath + ".prof");
+    }
+}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 896f56c..5ea2480 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -67,6 +67,8 @@
     ParceledListSlice getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
     int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
     int getDeletedChannelCount(String pkg, int uid);
+    void deleteNotificationChannelGroup(String pkg, String channelGroupId);
+    ParceledListSlice getNotificationChannelGroups(String pkg);
 
     // TODO: Remove this when callers have been migrated to the equivalent
     // INotificationListener method.
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 77c4c7e..cf41e4e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -55,7 +55,6 @@
 
 import com.android.internal.util.ArrayUtils;
 
-import dalvik.system.BaseDexClassLoader;
 import dalvik.system.VMRuntime;
 
 import java.io.File;
@@ -752,39 +751,10 @@
         VMRuntime.registerAppInfo(profileFile.getPath(),
                 codePaths.toArray(new String[codePaths.size()]));
 
-        // Setup the reporter to notify package manager of any relevant dex loads.
-        // At this point the primary apk is loaded and will not be reported.
-        // Anything loaded from now on will be tracked as a potential secondary
-        // or foreign dex file. The goal is to enable:
-        //    1) monitoring and compilation of secondary dex file
-        //    2) track whether or not a dex file is used by other apps (used to
-        //       determined the compilation filter of apks).
-        if (BaseDexClassLoader.getReporter() != DexLoadReporter.INSTANCE) {
-            // Set the dex load reporter if not already set.
-            // Note that during the app's life cycle different LoadedApks may be
-            // created and loaded (e.g. if two different apps share the same runtime).
-            BaseDexClassLoader.setReporter(DexLoadReporter.INSTANCE);
-        }
-    }
-
-    private static class DexLoadReporter implements BaseDexClassLoader.Reporter {
-        private static final DexLoadReporter INSTANCE = new DexLoadReporter();
-
-        private DexLoadReporter() {}
-
-        @Override
-        public void report(List<String> dexPaths) {
-            if (dexPaths.isEmpty()) {
-                return;
-            }
-            String packageName = ActivityThread.currentPackageName();
-            try {
-                ActivityThread.getPackageManager().notifyDexLoad(
-                        packageName, dexPaths, VMRuntime.getRuntime().vmInstructionSet());
-            } catch (RemoteException re) {
-                Slog.e(TAG, "Failed to notify PM about dex load for package " + packageName, re);
-            }
-        }
+        // Register the app data directory with the reporter. It will
+        // help deciding whether or not a dex file is the primary apk or a
+        // secondary dex.
+        DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
     }
 
     /**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a098591..aee9d386 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1935,7 +1935,9 @@
         if (this.actions != null) {
             that.actions = new Action[this.actions.length];
             for(int i=0; i<this.actions.length; i++) {
-                that.actions[i] = this.actions[i].clone();
+                if ( this.actions[i] != null) {
+                    that.actions[i] = this.actions[i].clone();
+                }
             }
         }
 
@@ -3432,7 +3434,9 @@
          * @param action The action to add.
          */
         public Builder addAction(Action action) {
-            mActions.add(action);
+            if (action != null) {
+                mActions.add(action);
+            }
             return this;
         }
 
@@ -3446,7 +3450,9 @@
         public Builder setActions(Action... actions) {
             mActions.clear();
             for (int i = 0; i < actions.length; i++) {
-                mActions.add(actions[i]);
+                if (actions[i] != null) {
+                    mActions.add(actions[i]);
+                }
             }
             return this;
         }
@@ -5651,11 +5657,13 @@
             static final String KEY_SENDER = "sender";
             static final String KEY_DATA_MIME_TYPE = "type";
             static final String KEY_DATA_URI= "uri";
+            static final String KEY_EXTRAS_BUNDLE = "extras";
 
             private final CharSequence mText;
             private final long mTimestamp;
             private final CharSequence mSender;
 
+            private Bundle mExtras = new Bundle();
             private String mDataMimeType;
             private Uri mDataUri;
 
@@ -5724,6 +5732,13 @@
             }
 
             /**
+             * Get the extras Bundle for this message.
+             */
+            public Bundle getExtras() {
+                return mExtras;
+            }
+
+            /**
              * Get the text used to display the contact's name in the messaging experience
              */
             public CharSequence getSender() {
@@ -5760,6 +5775,9 @@
                 if (mDataUri != null) {
                     bundle.putParcelable(KEY_DATA_URI, mDataUri);
                 }
+                if (mExtras != null) {
+                    bundle.putBundle(KEY_EXTRAS_BUNDLE, mExtras);
+                }
                 return bundle;
             }
 
@@ -5794,10 +5812,12 @@
                                 bundle.getLong(KEY_TIMESTAMP), bundle.getCharSequence(KEY_SENDER));
                         if (bundle.containsKey(KEY_DATA_MIME_TYPE) &&
                                 bundle.containsKey(KEY_DATA_URI)) {
-
                             message.setData(bundle.getString(KEY_DATA_MIME_TYPE),
                                     (Uri) bundle.getParcelable(KEY_DATA_URI));
                         }
+                        if (bundle.containsKey(KEY_EXTRAS_BUNDLE)) {
+                            message.getExtras().putAll(bundle.getBundle(KEY_EXTRAS_BUNDLE));
+                        }
                         return message;
                     }
                 } catch (ClassCastException e) {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 2a78b6b..0379970 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -498,6 +498,30 @@
     }
 
     /**
+     * Returns all notification channel groups belonging to the calling app.
+     */
+    public List<NotificationChannelGroup> getNotificationChannelGroups() {
+        INotificationManager service = getService();
+        try {
+            return service.getNotificationChannelGroups(mContext.getPackageName()).getList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Deletes the given notification channel group.
+     */
+    public void deleteNotificationChannelGroup(String groupId) {
+        INotificationManager service = getService();
+        try {
+            service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @hide
      */
     @TestApi
diff --git a/core/java/android/app/RemoteAction.java b/core/java/android/app/RemoteAction.java
index 5958bc1..e7fe407 100644
--- a/core/java/android/app/RemoteAction.java
+++ b/core/java/android/app/RemoteAction.java
@@ -41,12 +41,14 @@
     private final CharSequence mTitle;
     private final CharSequence mContentDescription;
     private final PendingIntent mActionIntent;
+    private boolean mEnabled;
 
     RemoteAction(Parcel in) {
         mIcon = Icon.CREATOR.createFromParcel(in);
         mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mActionIntent = PendingIntent.CREATOR.createFromParcel(in);
+        mEnabled = in.readBoolean();
     }
 
     public RemoteAction(@NonNull Icon icon, @NonNull CharSequence title,
@@ -59,6 +61,21 @@
         mTitle = title;
         mContentDescription = contentDescription;
         mActionIntent = intent;
+        mEnabled = true;
+    }
+
+    /**
+     * Sets whether this action is enabled.
+     */
+    public void setEnabled(boolean enabled) {
+        mEnabled = enabled;
+    }
+
+    /**
+     * Return whether this action is enabled.
+     */
+    public boolean isEnabled() {
+        return mEnabled;
     }
 
     /**
@@ -91,7 +108,9 @@
 
     @Override
     public RemoteAction clone() {
-        return new RemoteAction(mIcon, mTitle, mContentDescription, mActionIntent);
+        RemoteAction action = new RemoteAction(mIcon, mTitle, mContentDescription, mActionIntent);
+        action.setEnabled(mEnabled);
+        return action;
     }
 
     @Override
@@ -105,11 +124,13 @@
         TextUtils.writeToParcel(mTitle, out, flags);
         TextUtils.writeToParcel(mContentDescription, out, flags);
         mActionIntent.writeToParcel(out, flags);
+        out.writeBoolean(mEnabled);
     }
 
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
         pw.print("title=" + mTitle);
+        pw.print(" enabled=" + mEnabled);
         pw.print(" contentDescription=" + mContentDescription);
         pw.print(" icon=" + mIcon);
         pw.print(" action=" + mActionIntent.getIntent());
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 0fb5966..d9b6eed 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -17,6 +17,7 @@
 package android.app.admin;
 
 import android.accounts.AccountManager;
+import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -81,6 +82,7 @@
      * that other applications can not abuse it.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_DEVICE_ADMIN_ENABLED
             = "android.app.action.DEVICE_ADMIN_ENABLED";
 
@@ -94,6 +96,7 @@
      * to the user before they disable your admin.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
             = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
 
@@ -115,6 +118,7 @@
      * its intent filter.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_DEVICE_ADMIN_DISABLED
             = "android.app.action.DEVICE_ADMIN_DISABLED";
 
@@ -131,6 +135,7 @@
      * this broadcast.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_PASSWORD_CHANGED
             = "android.app.action.ACTION_PASSWORD_CHANGED";
 
@@ -147,6 +152,7 @@
      * this broadcast.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_PASSWORD_FAILED
             = "android.app.action.ACTION_PASSWORD_FAILED";
 
@@ -160,6 +166,7 @@
      * this broadcast.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_PASSWORD_SUCCEEDED
             = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
 
@@ -173,6 +180,7 @@
      * this broadcast.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_PASSWORD_EXPIRING
             = "android.app.action.ACTION_PASSWORD_EXPIRING";
 
@@ -187,6 +195,7 @@
      * @see DevicePolicyManager#isLockTaskPermitted(String)
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_LOCK_TASK_ENTERING
             = "android.app.action.LOCK_TASK_ENTERING";
 
@@ -200,6 +209,7 @@
      * @see DevicePolicyManager#isLockTaskPermitted(String)
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_LOCK_TASK_EXITING
             = "android.app.action.LOCK_TASK_EXITING";
 
@@ -232,6 +242,7 @@
      * <p>Output: Nothing</p>
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
             "android.app.action.PROFILE_PROVISIONING_COMPLETE";
 
@@ -244,6 +255,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_BUGREPORT_SHARING_DECLINED =
             "android.app.action.BUGREPORT_SHARING_DECLINED";
 
@@ -256,6 +268,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED";
 
     /**
@@ -266,6 +279,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_BUGREPORT_SHARE =
             "android.app.action.BUGREPORT_SHARE";
 
@@ -274,6 +288,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_SECURITY_LOGS_AVAILABLE
             = "android.app.action.SECURITY_LOGS_AVAILABLE";
 
@@ -283,6 +298,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_NETWORK_LOGS_AVAILABLE
             = "android.app.action.NETWORK_LOGS_AVAILABLE";
 
@@ -314,7 +330,8 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_USER_ADDED  = "android.app.action.USER_ADDED";
+    @BroadcastBehavior(explicitOnly = true)
+    public static final String ACTION_USER_ADDED = "android.app.action.USER_ADDED";
 
     /**
      * Broadcast action: notify the device owner that a user or profile has been removed.
@@ -323,6 +340,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_USER_REMOVED = "android.app.action.USER_REMOVED";
 
     /**
@@ -401,6 +419,7 @@
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE =
             "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
 
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index b1fbc8f..27bfb51 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1612,9 +1612,8 @@
             return newChild(index, false, 0, 0);
         }
 
-        // TODO(b/33197203, b/33802548): add CTS/unit test
         @Override
-        public ViewStructure newChildForAutofill(int index, int virtualId, int flags) {
+        public ViewStructure newChild(int index, int virtualId, int flags) {
             return newChild(index, true, virtualId, flags);
         }
 
@@ -1624,7 +1623,7 @@
         }
 
         @Override
-        public ViewStructure asyncNewChildForAutofill(int index, int virtualId, int flags) {
+        public ViewStructure asyncNewChild(int index, int virtualId, int flags) {
             return asyncNewChild(index, true, virtualId);
         }
 
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 67c791d..74a39e8 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -16,8 +16,11 @@
 
 package android.appwidget;
 
+import android.annotation.BroadcastBehavior;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -81,12 +84,14 @@
      *
      * @see #ACTION_APPWIDGET_CONFIGURE
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
 
     /**
      * Similar to ACTION_APPWIDGET_PICK, but used from keyguard
      * @hide
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String
             ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK";
 
@@ -133,6 +138,7 @@
      * @see #ACTION_APPWIDGET_CONFIGURE
      *
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND";
 
     /**
@@ -157,6 +163,7 @@
      * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED}
      * broadcast.
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
 
     /**
@@ -290,6 +297,8 @@
      *
      * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
 
     /**
@@ -302,6 +311,8 @@
      *      AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
      *      AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
 
     /**
@@ -312,6 +323,8 @@
      *
      * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
 
     /**
@@ -322,6 +335,8 @@
      *
      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context)
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
 
     /**
@@ -334,6 +349,8 @@
      *
      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
 
     /**
@@ -365,6 +382,8 @@
      *
      * @see #ACTION_APPWIDGET_HOST_RESTORED
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_RESTORED
             = "android.appwidget.action.APPWIDGET_RESTORED";
 
@@ -402,6 +421,8 @@
      *
      * @see #ACTION_APPWIDGET_RESTORED
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(explicitOnly = true)
     public static final String ACTION_APPWIDGET_HOST_RESTORED
             = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
 
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 488511b..4e1e42d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1483,6 +1483,25 @@
     }
 
     /**
+     * Return the maximum LE advertising data length,
+     * if LE Extended Advertising feature is supported.
+     *
+     * @return the maximum LE advertising data length.
+     */
+    public int getLeMaximumAdvertisingDataLength() {
+        if (!getLeAccess()) return 0;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.getLeMaximumAdvertisingDataLength();
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to get getLeMaximumAdvertisingDataLength, error: ", e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return 0;
+    }
+
+    /**
      * Return true if hardware has entries available for matching beacons
      *
      * @return true if there are hw entries available for matching beacons
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 76ca554..b337817 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -108,6 +108,7 @@
     boolean isLeCodedPhySupported();
     boolean isLeExtendedAdvertisingSupported();
     boolean isLePeriodicAdvertisingSupported();
+    int getLeMaximumAdvertisingDataLength();
     BluetoothActivityEnergyInfo reportActivityInfo();
 
     /**
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 33fedc7..29f29e7 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -50,14 +50,6 @@
     void stopScan(in int scannerId);
     void flushPendingBatchResults(in int scannerId);
 
-    void registerAdvertiser(in IAdvertiserCallback callback);
-    void unregisterAdvertiser(in int advertiserId);
-    void startMultiAdvertising(in int advertiserId,
-                               in AdvertiseData advertiseData,
-                               in AdvertiseData scanResponse,
-                               in AdvertiseSettings settings);
-    void stopMultiAdvertising(in int advertiserId);
-
     void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
                                 in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
                                 in AdvertiseData periodicData, in IAdvertisingSetCallback callback);
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index e03c947..c9f1d7a 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -28,6 +28,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -60,11 +61,12 @@
     private final IBluetoothManager mBluetoothManager;
     private final Handler mHandler;
     private BluetoothAdapter mBluetoothAdapter;
-    private final Map<AdvertiseCallback, AdvertiseCallbackWrapper>
-            mLeAdvertisers = new HashMap<AdvertiseCallback, AdvertiseCallbackWrapper>();
+    private final Map<AdvertiseCallback, AdvertisingSetCallback>
+            mLegacyAdvertisers = new HashMap<>();
     private final Map<AdvertisingSetCallback, IAdvertisingSetCallback>
-            advertisingSetCallbackWrappers = new HashMap<>();
-    private final Map<Integer, AdvertisingSet> advertisingSets = new HashMap<>();
+            mCallbackWrappers = Collections.synchronizedMap(new HashMap<>());
+    private final Map<Integer, AdvertisingSet>
+            mAdvertisingSets = Collections.synchronizedMap(new HashMap<>());
 
     /**
      * Use BluetoothAdapter.getLeAdvertiser() instead.
@@ -109,7 +111,7 @@
     public void startAdvertising(AdvertiseSettings settings,
             AdvertiseData advertiseData, AdvertiseData scanResponse,
             final AdvertiseCallback callback) {
-        synchronized (mLeAdvertisers) {
+        synchronized (mLegacyAdvertisers) {
             BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
             if (callback == null) {
                 throw new IllegalArgumentException("callback cannot be null");
@@ -120,25 +122,65 @@
                 postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
                 return;
             }
-            if (mLeAdvertisers.containsKey(callback)) {
+            if (mLegacyAdvertisers.containsKey(callback)) {
                 postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
                 return;
             }
 
-            IBluetoothGatt gatt;
-            try {
-                gatt = mBluetoothManager.getBluetoothGatt();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
-                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
-                return;
+            AdvertisingSetParameters.Builder parameters = new AdvertisingSetParameters.Builder();
+            parameters.setLegacyMode(true);
+            parameters.setConnectable(isConnectable);
+            parameters.setTimeout(settings.getTimeout());
+            if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_POWER) {
+                parameters.setInterval(1600); // 1s
+            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_BALANCED) {
+                parameters.setInterval(400); // 250ms
+            } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) {
+                parameters.setInterval(160); // 100ms
             }
-            AdvertiseCallbackWrapper wrapper = new AdvertiseCallbackWrapper(callback, advertiseData,
-                    scanResponse, settings, gatt);
-            wrapper.startRegisteration();
+
+            if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW) {
+                parameters.setTxPowerLevel(-21);
+            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_LOW) {
+                parameters.setTxPowerLevel(-15);
+            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) {
+                parameters.setTxPowerLevel(-7);
+            } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) {
+                parameters.setTxPowerLevel(1);
+            }
+
+            AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
+            mLegacyAdvertisers.put(callback, wrapped);
+            startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
+                                wrapped);
         }
     }
 
+    AdvertisingSetCallback wrapOldCallback(AdvertiseCallback callback, AdvertiseSettings settings) {
+        return new AdvertisingSetCallback() {
+            public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int status) {
+                if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+                    postStartFailure(callback, status);
+                    return;
+                }
+
+                postStartSuccess(callback, settings);
+            }
+
+            /* Legacy advertiser is disabled on timeout */
+            public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) {
+                if (enabled == true) {
+                    Log.e(TAG, "Legacy advertiser should be only disabled on timeout," +
+                        " but was enabled!");
+                    return;
+                }
+
+                stopAdvertising(callback);
+            }
+
+        };
+    }
+
     /**
      * Stop Bluetooth LE advertising. The {@code callback} must be the same one use in
      * {@link BluetoothLeAdvertiser#startAdvertising}.
@@ -148,20 +190,21 @@
      * @param callback {@link AdvertiseCallback} identifies the advertising instance to stop.
      */
     public void stopAdvertising(final AdvertiseCallback callback) {
-        synchronized (mLeAdvertisers) {
+        synchronized (mLegacyAdvertisers) {
             if (callback == null) {
                 throw new IllegalArgumentException("callback cannot be null");
             }
-            AdvertiseCallbackWrapper wrapper = mLeAdvertisers.get(callback);
+            AdvertisingSetCallback wrapper = mLegacyAdvertisers.get(callback);
             if (wrapper == null) return;
-            wrapper.stopAdvertising();
+
+            stopAdvertisingSet(wrapper);
         }
     }
 
     /**
     * Creates a new advertising set. If operation succeed, device will start advertising. This
     * method returns immediately, the operation status is delivered through
-    * {@code callback.onNewAdvertisingSet()}.
+    * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
     * @param advertiseData Advertisement data to be broadcasted.
@@ -180,7 +223,7 @@
     /**
     * Creates a new advertising set. If operation succeed, device will start advertising. This
     * method returns immediately, the operation status is delivered through
-    * {@code callback.onNewAdvertisingSet()}.
+    * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
     * @param advertiseData Advertisement data to be broadcasted.
@@ -209,7 +252,10 @@
         }
 
         IAdvertisingSetCallback wrapped = wrap(callback, handler);
-        advertisingSetCallbackWrappers.put(callback, wrapped);
+        if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
+            throw new IllegalArgumentException(
+                "callback instance already associated with advertising");
+        }
 
         try {
             gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
@@ -229,10 +275,9 @@
           throw new IllegalArgumentException("callback cannot be null");
         }
 
-        IAdvertisingSetCallback wrapped = advertisingSetCallbackWrappers.remove(callback);
+        IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
         if (wrapped == null) {
-            throw new IllegalArgumentException(
-                "callback does not represent valid registered callback.");
+            return;
         }
 
         IBluetoothGatt gatt;
@@ -251,7 +296,9 @@
      * @hide
      */
     public void cleanup() {
-        mLeAdvertisers.clear();
+        mLegacyAdvertisers.clear();
+        mCallbackWrappers.clear();
+        mAdvertisingSets.clear();
     }
 
     // Compute the size of advertisement data or scan resp
@@ -317,13 +364,13 @@
                     public void run() {
                         if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
                             callback.onAdvertisingSetStarted(null, status);
-                            advertisingSetCallbackWrappers.remove(callback);
+                            mCallbackWrappers.remove(callback);
                             return;
                         }
 
                         AdvertisingSet advertisingSet =
                             new AdvertisingSet(advertiserId, mBluetoothManager);
-                        advertisingSets.put(advertiserId, advertisingSet);
+                        mAdvertisingSets.put(advertiserId, advertisingSet);
                         callback.onAdvertisingSetStarted(advertisingSet, status);
                     }
                 });
@@ -333,10 +380,10 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onAdvertisingSetStopped(advertisingSet);
-                        advertisingSets.remove(advertiserId);
-                        advertisingSetCallbackWrappers.remove(callback);
+                        mAdvertisingSets.remove(advertiserId);
+                        mCallbackWrappers.remove(callback);
                     }
                 });
             }
@@ -345,7 +392,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onAdvertisingEnabled(advertisingSet, enabled, status);
                     }
                 });
@@ -355,7 +402,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onAdvertisingDataSet(advertisingSet, status);
                     }
                 });
@@ -365,7 +412,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onScanResponseDataSet(advertisingSet, status);
                     }
                 });
@@ -375,7 +422,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onAdvertisingParametersUpdated(advertisingSet, status);
                     }
                 });
@@ -385,7 +432,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
                     }
                 });
@@ -395,7 +442,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
                     }
                 });
@@ -405,7 +452,7 @@
                 handler.post(new Runnable() {
                     @Override
                     public void run() {
-                        AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+                        AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
                         callback.onPeriodicAdvertisingEnable(advertisingSet, enable, status);
                     }
                 });
@@ -413,144 +460,6 @@
         };
     }
 
-    /**
-     * Bluetooth GATT interface callbacks for advertising.
-     */
-    private class AdvertiseCallbackWrapper extends IAdvertiserCallback.Stub {
-        private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
-        private final AdvertiseCallback mAdvertiseCallback;
-        private final AdvertiseData mAdvertisement;
-        private final AdvertiseData mScanResponse;
-        private final AdvertiseSettings mSettings;
-        private final IBluetoothGatt mBluetoothGatt;
-
-        // mAdvertiserId -1: not registered
-        // -2: advertise stopped or registration timeout
-        // >=0: registered and advertising started
-        private int mAdvertiserId;
-        private boolean mIsAdvertising = false;
-        private int registrationError = AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR;
-
-        public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
-                AdvertiseData advertiseData, AdvertiseData scanResponse,
-                AdvertiseSettings settings,
-                IBluetoothGatt bluetoothGatt) {
-            mAdvertiseCallback = advertiseCallback;
-            mAdvertisement = advertiseData;
-            mScanResponse = scanResponse;
-            mSettings = settings;
-            mBluetoothGatt = bluetoothGatt;
-            mAdvertiserId = -1;
-        }
-
-        public void startRegisteration() {
-            synchronized (this) {
-                if (mAdvertiserId == -2) return;
-
-                try {
-                    mBluetoothGatt.registerAdvertiser(this);
-                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
-                } catch (InterruptedException | RemoteException e) {
-                    Log.e(TAG, "Failed to start registeration", e);
-                }
-                if (mAdvertiserId >= 0 && mIsAdvertising) {
-                    mLeAdvertisers.put(mAdvertiseCallback, this);
-                } else if (mAdvertiserId < 0) {
-
-                    // Registration timeout, reset mClientIf to -2 so no subsequent operations can
-                    // proceed.
-                    if (mAdvertiserId == -1) mAdvertiserId = -2;
-                    // Post internal error if registration failed.
-                    postStartFailure(mAdvertiseCallback, registrationError);
-                } else {
-                    // Unregister application if it's already registered but advertise failed.
-                    try {
-                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
-                        mAdvertiserId = -2;
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "remote exception when unregistering", e);
-                    }
-                }
-            }
-        }
-
-        public void stopAdvertising() {
-            synchronized (this) {
-                try {
-                    mBluetoothGatt.stopMultiAdvertising(mAdvertiserId);
-                    wait(LE_CALLBACK_TIMEOUT_MILLIS);
-                } catch (InterruptedException | RemoteException e) {
-                    Log.e(TAG, "Failed to stop advertising", e);
-                }
-                // Advertise callback should have been removed from LeAdvertisers when
-                // onMultiAdvertiseCallback was called. In case onMultiAdvertiseCallback is never
-                // invoked and wait timeout expires, remove callback here.
-                if (mLeAdvertisers.containsKey(mAdvertiseCallback)) {
-                    mLeAdvertisers.remove(mAdvertiseCallback);
-                }
-            }
-        }
-
-        /**
-         * Advertiser interface registered - app is ready to go
-         */
-        @Override
-        public void onAdvertiserRegistered(int status, int advertiserId) {
-            Log.d(TAG, "onAdvertiserRegistered() - status=" + status + " advertiserId=" + advertiserId);
-            synchronized (this) {
-                if (status == BluetoothGatt.GATT_SUCCESS) {
-                    try {
-                        if (mAdvertiserId == -2) {
-                            // Registration succeeds after timeout, unregister advertiser.
-                            mBluetoothGatt.unregisterAdvertiser(advertiserId);
-                        } else {
-                            mAdvertiserId = advertiserId;
-                            mBluetoothGatt.startMultiAdvertising(mAdvertiserId, mAdvertisement,
-                                    mScanResponse, mSettings);
-                        }
-                        return;
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "failed to start advertising", e);
-                    }
-                } else if (status == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) {
-                    registrationError = status;
-                }
-                // Registration failed.
-                mAdvertiserId = -2;
-                notifyAll();
-            }
-        }
-
-        @Override
-        public void onMultiAdvertiseCallback(int status, boolean isStart,
-                AdvertiseSettings settings) {
-            synchronized (this) {
-                if (isStart) {
-                    if (status == AdvertiseCallback.ADVERTISE_SUCCESS) {
-                        // Start success
-                        mIsAdvertising = true;
-                        postStartSuccess(mAdvertiseCallback, settings);
-                    } else {
-                        // Start failure.
-                        postStartFailure(mAdvertiseCallback, status);
-                    }
-                } else {
-                    // unregister advertiser for stop.
-                    try {
-                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
-                        mAdvertiserId = -2;
-                        mIsAdvertising = false;
-                        mLeAdvertisers.remove(mAdvertiseCallback);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "remote exception when unregistering", e);
-                    }
-                }
-                notifyAll();
-            }
-
-        }
-    }
-
     private void postStartFailure(final AdvertiseCallback callback, final int error) {
         mHandler.post(new Runnable() {
             @Override
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1f01e28..4dc6fd2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -17,6 +17,7 @@
 package android.content;
 
 import android.annotation.AnyRes;
+import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -1992,6 +1993,7 @@
      * This is a protected intent that can only be sent by the system.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(includeBackground = true)
     public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 33f57e0..10ffab2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2355,6 +2355,13 @@
             = "android.hardware.vr.high_performance";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
+     * The device implements headtracking suitable for a VR device.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_VR_HEADTRACKING = "android.hardware.vr.headtracking";
+
+    /**
      * Action to external storage service to clean out removed apps.
      * @hide
      */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e15a0e2..be6dc05 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -211,6 +211,14 @@
         CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT);
     }
 
+    private static final boolean LOG_UNSAFE_BROADCASTS = false;
+
+    // Set of broadcast actions that are safe for manifest receivers
+    private static final Set<String> SAFE_BROADCASTS = new ArraySet<>();
+    static {
+        SAFE_BROADCASTS.add(Intent.ACTION_BOOT_COMPLETED);
+    }
+
     /** @hide */
     public static class NewPermissionInfo {
         public final String name;
@@ -4203,6 +4211,7 @@
                 sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false);
         if (visibleToEphemeral) {
             a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            owner.visibleToInstantApps = true;
         }
 
         sa.recycle();
@@ -4247,6 +4256,18 @@
                 if (intent.isVisibleToInstantApp()) {
                     a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
+                if (LOG_UNSAFE_BROADCASTS && receiver
+                        && (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O)) {
+                    for (int i = 0; i < intent.countActions(); i++) {
+                        final String action = intent.getAction(i);
+                        if (action == null || !action.startsWith("android.")) continue;
+                        if (!SAFE_BROADCASTS.contains(action)) {
+                            Slog.w(TAG, "Broadcast " + action + " may never be delivered to "
+                                    + owner.packageName + " as requested at: "
+                                    + parser.getPositionDescription());
+                        }
+                    }
+                }
             } else if (!receiver && parser.getName().equals("preferred")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
                 if (!parseIntent(res, parser, false /*allowGlobs*/, false /*allowAutoVerify*/,
@@ -4696,6 +4717,7 @@
                 sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false);
         if (visibleToEphemeral) {
             p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            owner.visibleToInstantApps = true;
         }
 
         sa.recycle();
@@ -5012,6 +5034,7 @@
                 sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false);
         if (visibleToEphemeral) {
             s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            owner.visibleToInstantApps = true;
         }
 
         sa.recycle();
@@ -5615,6 +5638,11 @@
 
         public byte[] restrictUpdateHash;
 
+        /**
+         * Set if the app or any of its components are visible to Instant Apps.
+         */
+        public boolean visibleToInstantApps;
+
         public Package(String packageName) {
             this.packageName = packageName;
             this.manifestPackageName = packageName;
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 8bc65af..e3b97e8 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -100,6 +100,8 @@
     private final CameraCharacteristics mCharacteristics;
     private final int mTotalPartialCount;
 
+    private static final long NANO_PER_SECOND = 1000000000; //ns
+
     /**
      * A list tracking request and its expected last regular frame number and last reprocess frame
      * number. Updated when calling ICameraDeviceUser methods.
@@ -1239,6 +1241,14 @@
         private final List<CaptureRequest> mRequestList;
         private final Handler mHandler;
         private final int mSessionId;
+        /**
+         * <p>Determine if the callback holder is for a constrained high speed request list that
+         * expects batched capture results. Capture results will be batched if the request list
+         * is interleaved with preview and video requests. Capture results won't be batched if the
+         * request list only contains preview requests, or if the request doesn't belong to a
+         * constrained high speed list.
+         */
+        private final boolean mHasBatchedOutputs;
 
         CaptureCallbackHolder(CaptureCallback callback, List<CaptureRequest> requestList,
                 Handler handler, boolean repeating, int sessionId) {
@@ -1251,6 +1261,25 @@
             mRequestList = new ArrayList<CaptureRequest>(requestList);
             mCallback = callback;
             mSessionId = sessionId;
+
+            // Check whether this callback holder is for batched outputs.
+            // The logic here should match createHighSpeedRequestList.
+            boolean hasBatchedOutputs = true;
+            for (int i = 0; i < requestList.size(); i++) {
+                CaptureRequest request = requestList.get(i);
+                if (!request.isPartOfCRequestList()) {
+                    hasBatchedOutputs = false;
+                    break;
+                }
+                if (i == 0) {
+                    Collection<Surface> targets = request.getTargets();
+                    if (targets.size() != 2) {
+                        hasBatchedOutputs = false;
+                        break;
+                    }
+                }
+            }
+            mHasBatchedOutputs = hasBatchedOutputs;
         }
 
         public boolean isRepeating() {
@@ -1288,6 +1317,14 @@
         public int getSessionId() {
             return mSessionId;
         }
+
+        public int getRequestCount() {
+            return mRequestList.size();
+        }
+
+        public boolean hasBatchedOutputs() {
+            return mHasBatchedOutputs;
+        }
     }
 
     /**
@@ -1777,10 +1814,27 @@
                         @Override
                         public void run() {
                             if (!CameraDeviceImpl.this.isClosed()) {
-                                holder.getCallback().onCaptureStarted(
-                                    CameraDeviceImpl.this,
-                                    holder.getRequest(resultExtras.getSubsequenceId()),
-                                    timestamp, frameNumber);
+                                final int subsequenceId = resultExtras.getSubsequenceId();
+                                final CaptureRequest request = holder.getRequest(subsequenceId);
+
+                                if (holder.hasBatchedOutputs()) {
+                                    // Send derived onCaptureStarted for requests within the batch
+                                    final Range<Integer> fpsRange =
+                                        request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+                                    for (int i = 0; i < holder.getRequestCount(); i++) {
+                                        holder.getCallback().onCaptureStarted(
+                                            CameraDeviceImpl.this,
+                                            holder.getRequest(i),
+                                            timestamp - (subsequenceId - i) *
+                                            NANO_PER_SECOND/fpsRange.getUpper(),
+                                            frameNumber - (subsequenceId - i));
+                                    }
+                                } else {
+                                    holder.getCallback().onCaptureStarted(
+                                        CameraDeviceImpl.this,
+                                        holder.getRequest(resultExtras.getSubsequenceId()),
+                                        timestamp, frameNumber);
+                                }
                             }
                         }
                     });
@@ -1845,46 +1899,91 @@
                 Runnable resultDispatch = null;
 
                 CaptureResult finalResult;
+                // Make a copy of the native metadata before it gets moved to a CaptureResult
+                // object.
+                final CameraMetadataNative resultCopy;
+                if (holder.hasBatchedOutputs()) {
+                    resultCopy = new CameraMetadataNative(result);
+                } else {
+                    resultCopy = null;
+                }
 
                 // Either send a partial result or the final capture completed result
                 if (isPartialResult) {
                     final CaptureResult resultAsCapture =
                             new CaptureResult(result, request, resultExtras);
-
                     // Partial result
                     resultDispatch = new Runnable() {
                         @Override
                         public void run() {
-                            if (!CameraDeviceImpl.this.isClosed()){
-                                holder.getCallback().onCaptureProgressed(
-                                    CameraDeviceImpl.this,
-                                    request,
-                                    resultAsCapture);
+                            if (!CameraDeviceImpl.this.isClosed()) {
+                                if (holder.hasBatchedOutputs()) {
+                                    // Send derived onCaptureProgressed for requests within
+                                    // the batch.
+                                    for (int i = 0; i < holder.getRequestCount(); i++) {
+                                        CameraMetadataNative resultLocal =
+                                                new CameraMetadataNative(resultCopy);
+                                        CaptureResult resultInBatch = new CaptureResult(
+                                                resultLocal, holder.getRequest(i), resultExtras);
+
+                                        holder.getCallback().onCaptureProgressed(
+                                            CameraDeviceImpl.this,
+                                            holder.getRequest(i),
+                                            resultInBatch);
+                                    }
+                                } else {
+                                    holder.getCallback().onCaptureProgressed(
+                                        CameraDeviceImpl.this,
+                                        request,
+                                        resultAsCapture);
+                                }
                             }
                         }
                     };
-
                     finalResult = resultAsCapture;
                 } else {
                     List<CaptureResult> partialResults =
                             mFrameNumberTracker.popPartialResults(frameNumber);
 
+                    final long sensorTimestamp =
+                            result.get(CaptureResult.SENSOR_TIMESTAMP);
+                    final Range<Integer> fpsRange =
+                            request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+                    final int subsequenceId = resultExtras.getSubsequenceId();
                     final TotalCaptureResult resultAsCapture = new TotalCaptureResult(result,
                             request, resultExtras, partialResults, holder.getSessionId());
-
                     // Final capture result
                     resultDispatch = new Runnable() {
                         @Override
                         public void run() {
                             if (!CameraDeviceImpl.this.isClosed()){
-                                holder.getCallback().onCaptureCompleted(
-                                    CameraDeviceImpl.this,
-                                    request,
-                                    resultAsCapture);
+                                if (holder.hasBatchedOutputs()) {
+                                    // Send derived onCaptureCompleted for requests within
+                                    // the batch.
+                                    for (int i = 0; i < holder.getRequestCount(); i++) {
+                                        resultCopy.set(CaptureResult.SENSOR_TIMESTAMP,
+                                                sensorTimestamp - (subsequenceId - i) *
+                                                NANO_PER_SECOND/fpsRange.getUpper());
+                                        CameraMetadataNative resultLocal =
+                                                new CameraMetadataNative(resultCopy);
+                                        TotalCaptureResult resultInBatch = new TotalCaptureResult(
+                                            resultLocal, holder.getRequest(i), resultExtras,
+                                            partialResults, holder.getSessionId());
+
+                                        holder.getCallback().onCaptureCompleted(
+                                            CameraDeviceImpl.this,
+                                            holder.getRequest(i),
+                                            resultInBatch);
+                                    }
+                                } else {
+                                    holder.getCallback().onCaptureCompleted(
+                                        CameraDeviceImpl.this,
+                                        request,
+                                        resultAsCapture);
+                                }
                             }
                         }
                     };
-
                     finalResult = resultAsCapture;
                 }
 
diff --git a/core/java/android/hardware/radio/RadioModule.java b/core/java/android/hardware/radio/RadioModule.java
index fc7d0d2..8964893 100644
--- a/core/java/android/hardware/radio/RadioModule.java
+++ b/core/java/android/hardware/radio/RadioModule.java
@@ -16,6 +16,8 @@
 
 package android.hardware.radio;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
@@ -23,6 +25,7 @@
 import android.os.Looper;
 import android.os.Message;
 import java.lang.ref.WeakReference;
+import java.util.List;
 import java.util.UUID;
 
 /**
@@ -76,6 +79,8 @@
 
     public native int getProgramInformation(RadioManager.ProgramInfo[] info);
 
+    public native @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
+
     public native boolean isAntennaConnected();
 
     public native boolean hasControl();
diff --git a/core/java/android/hardware/radio/RadioTuner.java b/core/java/android/hardware/radio/RadioTuner.java
index 5c82555..c8034eb 100644
--- a/core/java/android/hardware/radio/RadioTuner.java
+++ b/core/java/android/hardware/radio/RadioTuner.java
@@ -16,6 +16,8 @@
 
 package android.hardware.radio;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
@@ -23,6 +25,7 @@
 import android.os.Looper;
 import android.os.Message;
 import java.lang.ref.WeakReference;
+import java.util.List;
 import java.util.UUID;
 
 /**
@@ -209,6 +212,20 @@
     public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
 
     /**
+     * Get the list of discovered radio stations.
+     *
+     * To get the full list, set filter to null or empty string. Otherwise, client application
+     * must verify vendor product/name before setting this parameter to anything else.
+     *
+     * @param filter vendor-specific selector for radio stations.
+     * @return a list of radio stations.
+     * @throws IllegalStateException if the scan is in progress or has not been started.
+     * @throws IllegalArgumentException if the filter argument is not valid.
+     * @hide FutureFeature
+     */
+    public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
+
+    /**
      * Get current antenna connection state for current configuration.
      * Only valid if a configuration has been applied.
      * @return {@code true} if the antenna is connected, {@code false} otherwise.
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 0136979..7906707 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -66,7 +66,8 @@
      * of classes can potentially create leaks.
      */
     private static final boolean FIND_POTENTIAL_LEAKS = false;
-    private static final boolean CHECK_PARCEL_SIZE = false;
+    /** @hide */
+    public static final boolean CHECK_PARCEL_SIZE = false;
     static final String TAG = "Binder";
 
     /** @hide */
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index a265dd0..94fd5b0 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -219,6 +219,7 @@
     public native final void writeStatus(int status);
     public native final void verifySuccess();
     public native final void releaseTemporaryStorage();
+    public native final void release();
 
     public native final void send();
 
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index caea202..f503b3a 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -2638,7 +2638,7 @@
             dest.writeString(broadcastIntentAction);
             dest.writeStringArray(tags);
             int total = dest.dataPosition()-start;
-            if (total > 10*1024) {
+            if (Binder.CHECK_PARCEL_SIZE && total > 10*1024) {
                 Slog.d(TAG, "VIO: policy=" + policy + " dur=" + durationMillis
                         + " numLoop=" + violationNumThisLoop
                         + " anim=" + numAnimationsRunning
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a638cd4..f6712f8 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.app.Activity;
@@ -763,6 +764,16 @@
     public static final int PIN_VERIFICATION_SUCCESS = -1;
 
     /**
+     * Sent when user restrictions have changed.
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi // To allow seeing it from CTS.
+    public static final String ACTION_USER_RESTRICTIONS_CHANGED =
+            "android.os.action.USER_RESTRICTIONS_CHANGED";
+
+    /**
      * Error result indicating that this user is not allowed to add other users on this device.
      * This is a result code returned from the activity created by the intent
      * {@link #createUserCreationIntent(String, String, String, PersistableBundle)}.
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 6663f03..6213d27 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -215,8 +215,10 @@
          * @throws IllegalArgumentException if {@code requiredIds} is {@code null} or empty.
          */
         public Builder(@SaveDataType int type, @NonNull AutofillId[] requiredIds) {
+            if (false) {// TODO(b/33197203): re-move when clients use it
             Preconditions.checkArgument(requiredIds != null && requiredIds.length > 0,
-                    "must have at least on required id: " + Arrays.toString(requiredIds));
+                    "must have at least one required id: " + Arrays.toString(requiredIds));
+            }
             switch (type) {
                 case SAVE_DATA_TYPE_PASSWORD:
                 case SAVE_DATA_TYPE_ADDRESS:
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 70e0461..f55c7cf 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -149,13 +149,13 @@
     // Notification cancellation reasons
 
     /** Notification was canceled by the status bar reporting a notification click. */
-    public static final int REASON_DELEGATE_CLICK = 1;
+    public static final int REASON_CLICK = 1;
     /** Notification was canceled by the status bar reporting a user dismissal. */
-    public static final int REASON_DELEGATE_CANCEL = 2;
+    public static final int REASON_CANCEL = 2;
     /** Notification was canceled by the status bar reporting a user dismiss all. */
-    public static final int REASON_DELEGATE_CANCEL_ALL = 3;
+    public static final int REASON_CANCEL_ALL = 3;
     /** Notification was canceled by the status bar reporting an inflation error. */
-    public static final int REASON_DELEGATE_ERROR = 4;
+    public static final int REASON_ERROR = 4;
     /** Notification was canceled by the package manager modifying the package. */
     public static final int REASON_PACKAGE_CHANGED = 5;
     /** Notification was canceled by the owning user context being stopped. */
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 10e4177..6034c18 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -50,5 +50,13 @@
      * @param enabled true if the device should be placed in persistent VR mode.
      */
     void setPersistentVrModeEnabled(in boolean enabled);
+
+    /**
+     * Return current virtual display id.
+     *
+     * @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
+     * currently, else return the display id of the virtual display
+     */
+    int getCompatibilityDisplayId();
 }
 
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 483a49b..6bbb0ff 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -18,11 +18,11 @@
 
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.util.MergedConfiguration;
 import android.view.WindowInsets;
 
 import com.android.internal.R;
 import com.android.internal.os.HandlerCaller;
-import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.BaseSurfaceHolder;
 
@@ -32,7 +32,6 @@
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.Intent;
-import android.content.res.Configuration;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
@@ -55,7 +54,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerGlobal;
 
 import java.io.FileDescriptor;
@@ -169,7 +167,7 @@
         final Rect mFinalSystemInsets = new Rect();
         final Rect mFinalStableInsets = new Rect();
         final Rect mBackdropFrame = new Rect();
-        final Configuration mConfiguration = new Configuration();
+        final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
 
         final WindowManager.LayoutParams mLayout
                 = new WindowManager.LayoutParams();
@@ -288,7 +286,7 @@
             @Override
             public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                     Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                    Configuration newConfig, Rect backDropRect, boolean forceLayout,
+                    MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout,
                     boolean alwaysConsumeNavBar, int displayId) {
                 Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED,
                         reportDraw ? 1 : 0, outsets);
@@ -568,7 +566,8 @@
                     out.print(mVisibleInsets.toShortString());
                     out.print(" mWinFrame="); out.print(mWinFrame.toShortString());
                     out.print(" mContentInsets="); out.println(mContentInsets.toShortString());
-            out.print(prefix); out.print("mConfiguration="); out.println(mConfiguration);
+            out.print(prefix); out.print("mConfiguration=");
+                    out.println(mMergedConfiguration.getMergedConfiguration());
             out.print(prefix); out.print("mLayout="); out.println(mLayout);
             synchronized (mLock) {
                 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
@@ -695,7 +694,7 @@
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
                             mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
-                            mConfiguration, mSurfaceHolder.mSurface);
+                            mMergedConfiguration, mSurfaceHolder.mSurface);
 
                     if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
                             + ", frame=" + mWinFrame);
diff --git a/core/java/android/util/LauncherIcons.java b/core/java/android/util/LauncherIcons.java
new file mode 100644
index 0000000..e5aa2b5
--- /dev/null
+++ b/core/java/android/util/LauncherIcons.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Utility class to handle icon treatments (e.g., shadow generation) for the Launcher icons.
+ * @hide
+ */
+public final class LauncherIcons {
+
+    private final Paint mPaint = new Paint();
+    private final Canvas mCanvas = new Canvas();
+
+    private static final int KEY_SHADOW_ALPHA = 61;
+    private static final int AMBIENT_SHADOW_ALPHA = 30;
+    private static final float BLUR_FACTOR = 0.5f / 48;
+    private int mShadowInset;
+    private Bitmap mShadowBitmap;
+    private int mIconSize;
+    private Resources mRes;
+
+    public LauncherIcons(Context context) {
+        mRes = context.getResources();
+        DisplayMetrics metrics = mRes.getDisplayMetrics();
+        mShadowInset = (int) metrics.density / DisplayMetrics.DENSITY_DEFAULT;
+        mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
+            Paint.FILTER_BITMAP_FLAG));
+        mIconSize = (int) mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
+    }
+
+    /**
+     * Draw the drawable into a bitmap.
+     */
+    public Bitmap createIconBitmap(Drawable icon) {
+        final Bitmap bitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ARGB_8888);
+        mPaint.setAlpha(255);
+        mCanvas.setBitmap(bitmap);
+        int iconInset = 0;
+        if (mShadowBitmap != null) {
+            mCanvas.drawBitmap(mShadowBitmap, 0, 0, mPaint);
+            iconInset = mShadowInset;
+        }
+
+        icon.setBounds(iconInset, iconInset, mIconSize - iconInset,
+            mIconSize - iconInset);
+        icon.draw(mCanvas);
+        mCanvas.setBitmap(null);
+        return bitmap;
+    }
+
+    public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
+        if (!(drawable instanceof AdaptiveIconDrawable)) {
+            return drawable;
+        }
+        AdaptiveIconDrawable d =
+            (AdaptiveIconDrawable) drawable.getConstantState().newDrawable().mutate();
+        getShadowBitmap(d);
+        Bitmap iconbitmap = createIconBitmap(d);
+        return new BitmapDrawable(mRes, iconbitmap);
+    }
+
+    private Bitmap getShadowBitmap(AdaptiveIconDrawable d) {
+        if (mShadowBitmap != null) {
+            return mShadowBitmap;
+        }
+
+        int shadowSize = mIconSize - mShadowInset;
+        mShadowBitmap = Bitmap.createBitmap(mIconSize, mIconSize, Bitmap.Config.ALPHA_8);
+        mCanvas.setBitmap(mShadowBitmap);
+
+        // Draw key shadow
+        mPaint.setColor(Color.TRANSPARENT);
+        float blur = BLUR_FACTOR * mIconSize;
+        mPaint.setShadowLayer(blur, 0, mShadowInset, KEY_SHADOW_ALPHA << 24);
+        d.setBounds(mShadowInset, mShadowInset, mIconSize - mShadowInset, mIconSize - mShadowInset);
+        mCanvas.drawPath(d.getIconMask(), mPaint);
+
+        // Draw ambient shadow
+        mPaint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
+        d.setBounds(mShadowInset, 2 * mShadowInset, mIconSize - mShadowInset, mIconSize);
+        mCanvas.drawPath(d.getIconMask(), mPaint);
+        mPaint.clearShadowLayer();
+
+        return mShadowBitmap;
+    }
+}
diff --git a/core/java/android/util/MergedConfiguration.aidl b/core/java/android/util/MergedConfiguration.aidl
new file mode 100644
index 0000000..c24dbbe
--- /dev/null
+++ b/core/java/android/util/MergedConfiguration.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.util;
+
+parcelable MergedConfiguration;
\ No newline at end of file
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
new file mode 100644
index 0000000..d94af8a
--- /dev/null
+++ b/core/java/android/util/MergedConfiguration.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.util;
+
+import android.annotation.NonNull;
+import android.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Container that holds global and override config and their merge product.
+ * Merged configuration updates automatically whenever global or override configs are updated via
+ * setters.
+ *
+ * {@hide}
+ */
+public class MergedConfiguration implements Parcelable {
+
+    private Configuration mGlobalConfig = new Configuration();
+    private Configuration mOverrideConfig = new Configuration();
+    private Configuration mMergedConfig = new Configuration();
+
+    public MergedConfiguration() {
+    }
+
+    public MergedConfiguration(Configuration globalConfig, Configuration overrideConfig) {
+        setConfiguration(globalConfig, overrideConfig);
+    }
+
+    public MergedConfiguration(MergedConfiguration mergedConfiguration) {
+        setConfiguration(mergedConfiguration.getGlobalConfiguration(),
+                mergedConfiguration.getOverrideConfiguration());
+    }
+
+    private MergedConfiguration(Parcel in) {
+        readFromParcel(in);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mGlobalConfig, flags);
+        dest.writeParcelable(mOverrideConfig, flags);
+        dest.writeParcelable(mMergedConfig, flags);
+    }
+
+    public void readFromParcel(Parcel source) {
+        mGlobalConfig = source.readParcelable(Configuration.class.getClassLoader());
+        mOverrideConfig = source.readParcelable(Configuration.class.getClassLoader());
+        mMergedConfig = source.readParcelable(Configuration.class.getClassLoader());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<MergedConfiguration> CREATOR = new Creator<MergedConfiguration>() {
+        @Override
+        public MergedConfiguration createFromParcel(Parcel in) {
+            return new MergedConfiguration(in);
+        }
+
+        @Override
+        public MergedConfiguration[] newArray(int size) {
+            return new MergedConfiguration[size];
+        }
+    };
+
+    /**
+     * Update global and override configurations.
+     * Merged configuration will automatically be updated.
+     * @param globalConfig New global configuration.
+     * @param overrideConfig New override configuration.
+     */
+    public void setConfiguration(Configuration globalConfig, Configuration overrideConfig) {
+        mGlobalConfig.setTo(globalConfig);
+        mOverrideConfig.setTo(overrideConfig);
+        updateMergedConfig();
+    }
+
+    /**
+     * @return Stored global configuration value.
+     */
+    @NonNull
+    public Configuration getGlobalConfiguration() {
+        return mGlobalConfig;
+    }
+
+    /**
+     * @return Stored override configuration value.
+     */
+    public Configuration getOverrideConfiguration() {
+        return mOverrideConfig;
+    }
+
+    /**
+     * @return Stored merged configuration value.
+     */
+    public Configuration getMergedConfiguration() {
+        return mMergedConfig;
+    }
+
+    /** Update merged config when global or override config changes. */
+    private void updateMergedConfig() {
+        mMergedConfig.setTo(mGlobalConfig);
+        mMergedConfig.updateFrom(mOverrideConfig);
+    }
+}
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
index e59937d..ca54bef 100644
--- a/core/java/android/view/AccessibilityIterators.java
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.content.ComponentCallbacks;
 import android.content.res.Configuration;
 
 import java.text.BreakIterator;
@@ -65,7 +64,7 @@
     }
 
     static class CharacterTextSegmentIterator extends AbstractTextSegmentIterator
-            implements ComponentCallbacks {
+            implements ViewRootImpl.ConfigChangedCallback {
         private static CharacterTextSegmentIterator sInstance;
 
         private Locale mLocale;
@@ -144,19 +143,14 @@
         }
 
         @Override
-        public void onConfigurationChanged(Configuration newConfig) {
-            Locale locale = newConfig.locale;
+        public void onConfigurationChanged(Configuration globalConfig) {
+            final Locale locale = globalConfig.getLocales().get(0);
             if (!mLocale.equals(locale)) {
                 mLocale = locale;
                 onLocaleChanged(locale);
             }
         }
 
-        @Override
-        public void onLowMemory() {
-            /* ignore */
-        }
-
         protected void onLocaleChanged(Locale locale) {
             mImpl = BreakIterator.getCharacterInstance(locale);
         }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 14b2abe..611cc63 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -17,7 +17,6 @@
 
 package android.view;
 
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -26,6 +25,7 @@
 import android.view.MotionEvent;
 
 import com.android.internal.os.IResultReceiver;
+import android.util.MergedConfiguration;
 
 /**
  * API back to a client window that the Window Manager uses to inform it of
@@ -49,8 +49,8 @@
 
     void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
             in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw,
-            in Configuration newConfig, in Rect backDropFrame, boolean forceLayout,
-            boolean alwaysConsumeNavBar, int displayId);
+            in MergedConfiguration newMergedConfiguration, in Rect backDropFrame,
+            boolean forceLayout, boolean alwaysConsumeNavBar, int displayId);
     void moved(int newX, int newY);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 7e6af11..51d6514 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -11,17 +11,17 @@
 ** 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 
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
 package android.view;
 
 import android.content.ClipData;
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
+import android.util.MergedConfiguration;
 import android.view.InputChannel;
 import android.view.IWindow;
 import android.view.IWindowId;
@@ -83,9 +83,9 @@
      * treat as real display. Example of such area is a chin in some models of wearable devices.
      * @param outBackdropFrame Rect which is used draw the resizing background during a resize
      * operation.
-     * @param outConfiguration New configuration of window, if it is now
-     * becoming visible and the global configuration has changed since it
-     * was last displayed.
+     * @param outMergedConfiguration New config container that holds global, override and merged
+     * config for window, if it is now becoming visible and the merged configuration has changed
+     * since it was last displayed.
      * @param outSurface Object in which is placed the new display surface.
      *
      * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
@@ -95,8 +95,8 @@
             int requestedWidth, int requestedHeight, int viewVisibility,
             int flags, out Rect outFrame, out Rect outOverscanInsets,
             out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
-            out Rect outOutsets, out Rect outBackdropFrame, out Configuration outConfig,
-            out Surface outSurface);
+            out Rect outOutsets, out Rect outBackdropFrame,
+            out MergedConfiguration outMergedConfiguration, out Surface outSurface);
 
     /*
      * Notify the window manager that an application is relaunching and
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 6d320ef..824e035 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,8 +16,9 @@
 
 package android.view;
 
-import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
 import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
 import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
 
 import android.content.Context;
@@ -28,6 +29,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
@@ -777,6 +779,31 @@
     }
 
     /**
+     * This method still exists only for compatibility reasons because some applications have relied
+     * on this method via reflection. See Issue 36345857 for details.
+     *
+     * @deprecated No platform code is using this method anymore.
+     * @hide
+     */
+    @Deprecated
+    public void setWindowType(int type) {
+        if (getContext().getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+            throw new UnsupportedOperationException(
+                    "SurfaceView#setWindowType() has never been a public API.");
+        }
+
+        if (type == TYPE_APPLICATION_PANEL) {
+            Log.e(TAG, "If you are calling SurfaceView#setWindowType(TYPE_APPLICATION_PANEL) "
+                    + "just to make the SurfaceView to be placed on top of its window, you must "
+                    + "call setZOrderOnTop(true) instead.", new Throwable());
+            setZOrderOnTop(true);
+            return;
+        }
+        Log.e(TAG, "SurfaceView#setWindowType(int) is deprecated and now does nothing. "
+                + "type=" + type, new Throwable());
+    }
+
+    /**
      * Check to see if the surface has fixed size dimensions or if the surface's
      * dimensions are dimensions are dependent on its current layout.
      *
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 80f6c32..583dad4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2749,13 +2749,8 @@
      *                 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
@@ -7384,13 +7379,13 @@
      * <p>When implementing this method, subclasses must follow the rules below:
      *
      * <ol>
-     * <li>Also implement {@link #autofillVirtual(int, AutofillValue)} to autofill the virtual
+     * <li>Also implement {@link #autofill(int, AutofillValue)} to autofill the virtual
      * children.
      * <li>Call
-     * {@link android.view.autofill.AutofillManager#notifyVirtualViewEntered} and
-     * {@link android.view.autofill.AutofillManager#notifyVirtualViewExited(View, int)}
+     * {@link android.view.autofill.AutofillManager#notifyViewEntered} and
+     * {@link android.view.autofill.AutofillManager#notifyViewExited(View, int)}
      * when the focus inside the view changed.
-     * <li>Call {@link android.view.autofill.AutofillManager#notifyVirtualValueChanged(View, int,
+     * <li>Call {@link android.view.autofill.AutofillManager#notifyValueChanged(View, int,
      * AutofillValue)} when the value of a child changed.
      * <li>Call {@link AutofillManager#commit()} when the autofill context
      * of the view structure changed and you want the current autofill interaction if such
@@ -7445,8 +7440,11 @@
      * </pre>
      *
      * @param value value to be autofilled.
+     *
+     * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
      */
-    public void autofill(@SuppressWarnings("unused") AutofillValue value) {
+    public boolean autofill(@SuppressWarnings("unused") AutofillValue value) {
+        return false;
     }
 
     /**
@@ -7457,14 +7455,17 @@
      *
      * @param value value to be autofilled.
      * @param virtualId id identifying the virtual child inside the custom view.
+     *
+     * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
      */
-    public void autofillVirtual(@SuppressWarnings("unused") int virtualId,
+    public boolean autofill(@SuppressWarnings("unused") int virtualId,
             @SuppressWarnings("unused") AutofillValue value) {
+        return false;
     }
 
     /**
      * Describes the autofill type that should be used on calls to
-     * {@link #autofill(AutofillValue)} and {@link #autofillVirtual(int, AutofillValue)}.
+     * {@link #autofill(AutofillValue)} and {@link #autofill(int, AutofillValue)}.
      *
      * <p>By default returns {@link #AUTOFILL_TYPE_NONE}, but views should override it (and
      * {@link #autofill(AutofillValue)} to support the Autofill Framework.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ed42385..1681787 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.View.PFLAG_DRAW_ANIMATION;
 import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
 import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
@@ -28,10 +29,10 @@
 import android.animation.LayoutTransition;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
 import android.app.ResourcesManager;
 import android.content.ClipData;
 import android.content.ClipDescription;
-import android.content.ComponentCallbacks;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
@@ -67,6 +68,7 @@
 import android.util.AndroidRuntimeException;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.TypedValue;
@@ -161,7 +163,44 @@
     static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
     static boolean sFirstDrawComplete = false;
 
-    static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList();
+    /**
+     * Callback for notifying about global configuration changes.
+     */
+    public interface ConfigChangedCallback {
+
+        /** Notifies about global config change. */
+        void onConfigurationChanged(Configuration globalConfig);
+    }
+
+    private static final ArrayList<ConfigChangedCallback> sConfigCallbacks = new ArrayList<>();
+
+    /**
+     * Callback for notifying activities about override configuration changes.
+     */
+    public interface ActivityConfigCallback {
+
+        /**
+         * Notifies about override config change and/or move to different display.
+         * @param overrideConfig New override config to apply to activity.
+         * @param newDisplayId New display id, {@link Display#INVALID_DISPLAY} if not changed.
+         */
+        void onConfigurationChanged(Configuration overrideConfig, int newDisplayId);
+    }
+
+    /**
+     * Callback used to notify corresponding activity about override configuration change and make
+     * sure that all resources are set correctly before updating the ViewRootImpl's internal state.
+     */
+    private ActivityConfigCallback mActivityConfigCallback;
+
+    /**
+     * Used when configuration change first updates the config of corresponding activity.
+     * In that case we receive a call back from {@link ActivityThread} and this flag is used to
+     * preserve the initial value.
+     *
+     * @see #performConfigurationChange(Configuration, Configuration, boolean, int)
+     */
+    private boolean mForceNextConfigUpdate;
 
     /**
      * Signals that compatibility booleans have been initialized according to
@@ -344,8 +383,12 @@
 
     private WindowInsets mLastWindowInsets;
 
-    final Configuration mLastConfiguration = new Configuration();
-    final Configuration mPendingConfiguration = new Configuration();
+    /** Last applied configuration obtained from resources. */
+    private final Configuration mLastConfigurationFromResources = new Configuration();
+    /** Last configuration reported from WM or via {@link #MSG_UPDATE_CONFIGURATION}. */
+    private final MergedConfiguration mLastReportedMergedConfiguration = new MergedConfiguration();
+    /** Configurations waiting to be applied. */
+    private final MergedConfiguration mPendingMergedConfiguration = new MergedConfiguration();
 
     boolean mScrollMayChange;
     @SoftInputModeFlags
@@ -464,7 +507,7 @@
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
 
         if (!sCompatibilityDone) {
-            sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.O;
+            sAlwaysAssignFocus = true;
 
             sCompatibilityDone = true;
         }
@@ -480,12 +523,18 @@
         }
     }
 
-    public static void addConfigCallback(ComponentCallbacks callback) {
+    /** Add static config callback to be notified about global config changes. */
+    public static void addConfigCallback(ConfigChangedCallback callback) {
         synchronized (sConfigCallbacks) {
             sConfigCallbacks.add(callback);
         }
     }
 
+    /** Add activity config callback to be notified about override config changes. */
+    public void setActivityConfigCallback(ActivityConfigCallback callback) {
+        mActivityConfigCallback = callback;
+    }
+
     public void addWindowCallbacks(WindowCallbacks callback) {
         if (USE_MT_RENDERER) {
             synchronized (mWindowCallbacks) {
@@ -1558,6 +1607,7 @@
             mFullRedrawNeeded = true;
             mLayoutRequested = true;
 
+            final Configuration config = mContext.getResources().getConfiguration();
             if (shouldUseDisplaySize(lp)) {
                 // NOTE -- system code, won't try to do compat mode.
                 Point size = new Point();
@@ -1565,7 +1615,6 @@
                 desiredWindowWidth = size.x;
                 desiredWindowHeight = size.y;
             } else {
-                Configuration config = mContext.getResources().getConfiguration();
                 desiredWindowWidth = dipToPx(config.screenWidthDp);
                 desiredWindowHeight = dipToPx(config.screenHeightDp);
             }
@@ -1577,11 +1626,11 @@
             mAttachInfo.mHasWindowFocus = false;
             mAttachInfo.mWindowVisibility = viewVisibility;
             mAttachInfo.mRecomputeGlobalAttributes = false;
-            mLastConfiguration.setTo(host.getResources().getConfiguration());
+            mLastConfigurationFromResources.setTo(config);
             mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
             // Set the layout direction if it has not been set before (inherit is the default)
             if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
-                host.setLayoutDirection(mLastConfiguration.getLayoutDirection());
+                host.setLayoutDirection(config.getLayoutDirection());
             }
             host.dispatchAttachedToWindow(mAttachInfo, 0);
             mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
@@ -1826,11 +1875,14 @@
                         + " outsets=" + mPendingOutsets.toShortString()
                         + " surface=" + mSurface);
 
-                if (mPendingConfiguration.seq != 0) {
+                final Configuration pendingMergedConfig =
+                        mPendingMergedConfiguration.getMergedConfiguration();
+                if (pendingMergedConfig.seq != 0) {
                     if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
-                            + mPendingConfiguration);
-                    updateConfiguration(new Configuration(mPendingConfiguration), !mFirst);
-                    mPendingConfiguration.seq = 0;
+                            + pendingMergedConfig);
+                    performConfigurationChange(mPendingMergedConfiguration, !mFirst,
+                            INVALID_DISPLAY /* same display */);
+                    pendingMergedConfig.seq = 0;
                     updatedConfiguration = true;
                 }
 
@@ -3388,43 +3440,82 @@
         unscheduleTraversals();
     }
 
-    void updateConfiguration(Configuration config, boolean force) {
-        if (DEBUG_CONFIGURATION) Log.v(mTag,
-                "Applying new config to window "
-                + mWindowAttributes.getTitle()
-                + ": " + config);
+    /**
+     * Notifies all callbacks that configuration and/or display has changed and updates internal
+     * state.
+     * @param mergedConfiguration New global and override config in {@link MergedConfiguration}
+     *                            container.
+     * @param force Flag indicating if we should force apply the config.
+     * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} if not
+     *                     changed.
+     */
+    private void performConfigurationChange(MergedConfiguration mergedConfiguration, boolean force,
+            int newDisplayId) {
+        if (mergedConfiguration == null) {
+            throw new IllegalArgumentException("No merged config provided.");
+        }
 
-        CompatibilityInfo ci = mDisplay.getDisplayAdjustments().getCompatibilityInfo();
+        Configuration globalConfig = mergedConfiguration.getGlobalConfiguration();
+        final Configuration overrideConfig = mergedConfiguration.getOverrideConfiguration();
+        if (DEBUG_CONFIGURATION) Log.v(mTag,
+                "Applying new config to window " + mWindowAttributes.getTitle()
+                        + ", globalConfig: " + globalConfig
+                        + ", overrideConfig: " + overrideConfig);
+
+        final CompatibilityInfo ci = mDisplay.getDisplayAdjustments().getCompatibilityInfo();
         if (!ci.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
-            config = new Configuration(config);
-            ci.applyToConfiguration(mNoncompatDensity, config);
+            globalConfig = new Configuration(globalConfig);
+            ci.applyToConfiguration(mNoncompatDensity, globalConfig);
         }
 
         synchronized (sConfigCallbacks) {
             for (int i=sConfigCallbacks.size()-1; i>=0; i--) {
-                sConfigCallbacks.get(i).onConfigurationChanged(config);
+                sConfigCallbacks.get(i).onConfigurationChanged(globalConfig);
             }
         }
-        if (mView != null) {
-            // At this point the resources have been updated to
-            // have the most recent config, whatever that is.  Use
-            // the one in them which may be newer.
-            final Resources localResources = mView.getResources();
-            config = localResources.getConfiguration();
-            if (force || mLastConfiguration.diff(config) != 0) {
-                // Update the display with new DisplayAdjustments.
-                mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(
-                        mDisplay.getDisplayId(), localResources);
 
-                final int lastLayoutDirection = mLastConfiguration.getLayoutDirection();
-                final int currentLayoutDirection = config.getLayoutDirection();
-                mLastConfiguration.setTo(config);
-                if (lastLayoutDirection != currentLayoutDirection &&
-                        mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
-                    mView.setLayoutDirection(currentLayoutDirection);
-                }
-                mView.dispatchConfigurationChanged(config);
+        mLastReportedMergedConfiguration.setConfiguration(globalConfig, overrideConfig);
+
+        mForceNextConfigUpdate = force;
+        if (mActivityConfigCallback != null) {
+            // An activity callback is set - notify it about override configuration update.
+            // This basically initiates a round trip to ActivityThread and back, which will ensure
+            // that corresponding activity and resources are updated before updating inner state of
+            // ViewRootImpl. Eventually it will call #updateConfiguration().
+            mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId);
+        } else {
+            // There is no activity callback - update the configuration right away.
+            updateConfiguration();
+        }
+        mForceNextConfigUpdate = false;
+    }
+
+    /**
+     * Update display and views if last applied merged configuration changed.
+     */
+    public void updateConfiguration() {
+        if (mView == null) {
+            return;
+        }
+
+        // At this point the resources have been updated to
+        // have the most recent config, whatever that is.  Use
+        // the one in them which may be newer.
+        final Resources localResources = mView.getResources();
+        final Configuration config = localResources.getConfiguration();
+        if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) {
+            // Update the display with new DisplayAdjustments.
+            mDisplay = ResourcesManager.getInstance().getAdjustedDisplay(
+                    mDisplay.getDisplayId(), localResources);
+
+            final int lastLayoutDirection = mLastConfigurationFromResources.getLayoutDirection();
+            final int currentLayoutDirection = config.getLayoutDirection();
+            mLastConfigurationFromResources.setTo(config);
+            if (lastLayoutDirection != currentLayoutDirection
+                    && mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) {
+                mView.setLayoutDirection(currentLayoutDirection);
             }
+            mView.dispatchConfigurationChanged(config);
         }
     }
 
@@ -3582,13 +3673,16 @@
                 if (mAdded) {
                     SomeArgs args = (SomeArgs) msg.obj;
 
-                    if (mDisplay.getDisplayId() != args.argi3) {
-                        onMovedToDisplay(args.argi3);
+                    final int displayId = args.argi3;
+                    final boolean displayChanged = mDisplay.getDisplayId() != displayId;
+                    if (displayChanged) {
+                        onMovedToDisplay(displayId);
                     }
 
-                    Configuration config = (Configuration) args.arg4;
-                    if (config != null) {
-                        updateConfiguration(config, false);
+                    final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+                    if (mergedConfiguration != null) {
+                        performConfigurationChange(mergedConfiguration, false /* force */,
+                                displayChanged ? displayId : INVALID_DISPLAY /* same display */);
                     }
 
                     final boolean framesChanged = !mWinFrame.equals(args.arg1)
@@ -3759,11 +3853,19 @@
                 handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo) msg.obj);
             } break;
             case MSG_UPDATE_CONFIGURATION: {
-                Configuration config = (Configuration)msg.obj;
-                if (config.isOtherSeqNewer(mLastConfiguration)) {
-                    config = mLastConfiguration;
+                Configuration config = (Configuration) msg.obj;
+                if (config.isOtherSeqNewer(
+                        mLastReportedMergedConfiguration.getMergedConfiguration())) {
+                    // If we already have a newer merged config applied - use its global part.
+                    config = mLastReportedMergedConfiguration.getGlobalConfiguration();
                 }
-                updateConfiguration(config, false);
+
+                // Use the newer global config and last reported override config.
+                mPendingMergedConfiguration.setConfiguration(config,
+                        mLastReportedMergedConfiguration.getOverrideConfiguration());
+
+                performConfigurationChange(mPendingMergedConfiguration, false /* force */,
+                        INVALID_DISPLAY /* same display */);
             } break;
             case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
                 setAccessibilityFocus(null, null);
@@ -5902,7 +6004,7 @@
         if (params != null) {
             if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
         }
-        mPendingConfiguration.seq = 0;
+        mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
         //Log.d(mTag, ">>>>>> CALLING relayout");
         if (params != null && mOrigWindowType != params.type) {
             // For compatibility with old apps, don't crash here.
@@ -5918,8 +6020,8 @@
                 (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                 viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                 mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
-                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,
-                mSurface);
+                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame,
+                mPendingMergedConfiguration, mSurface);
 
         mPendingAlwaysConsumeNavBar =
                 (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;
@@ -6199,9 +6301,9 @@
         }
     }
 
-    public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
+    private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
             Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-            Configuration newConfig, Rect backDropFrame, boolean forceLayout,
+            MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
             boolean alwaysConsumeNavBar, int displayId) {
         if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString()
                 + " contentInsets=" + contentInsets.toShortString()
@@ -6233,7 +6335,8 @@
         args.arg1 = sameProcessCall ? new Rect(frame) : frame;
         args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets;
         args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets;
-        args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig;
+        args.arg4 = sameProcessCall && mergedConfiguration != null
+                ? new MergedConfiguration(mergedConfiguration) : null;
         args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
         args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
         args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
@@ -7243,13 +7346,13 @@
         @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                Configuration newConfig, Rect backDropFrame, boolean forceLayout,
+                MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
                 boolean alwaysConsumeNavBar, int displayId) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
-                        visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame,
-                        forceLayout, alwaysConsumeNavBar, displayId);
+                        visibleInsets, stableInsets, outsets, reportDraw, mergedConfiguration,
+                        backDropFrame, forceLayout, alwaysConsumeNavBar, displayId);
             }
         }
 
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 38c7738..4168756 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -275,13 +275,12 @@
      *            {@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#autofill(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 newChild(int index, int virtualId, int flags);
 
     /**
      * Like {@link #newChild}, but allows the caller to asynchronously populate the returned
@@ -294,7 +293,7 @@
     public abstract ViewStructure asyncNewChild(int index);
 
     /**
-     * Like {@link #newChildForAutofill(int, int, int)}, but allows the caller to asynchronously
+     * Like {@link #newChild(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
@@ -307,13 +306,12 @@
      *            {@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#autofill(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);
+    public abstract ViewStructure asyncNewChild(int index, int virtualId, int flags);
 
     /**
      * Sets the {@link View#getAutofillType()} that can be used to autofill this node.
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index f036b9c..9ed6371 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -83,7 +83,7 @@
     /** @hide */ public static final int FLAG_VIEW_EXITED =   0x20000000;
     /** @hide */ public static final int FLAG_VALUE_CHANGED = 0x10000000;
 
-    private final Rect mTempRect = new Rect();
+    @NonNull private final Rect mTempRect = new Rect();
 
     private final IAutoFillManager mService;
     private IAutoFillManagerClient mServiceClient;
@@ -196,6 +196,9 @@
         ensureServiceClientAddedIfNeeded();
 
         if (!mEnabled) {
+            if (mCallback != null) {
+                mCallback.onAutofillEvent(view, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+            }
             return;
         }
 
@@ -236,11 +239,13 @@
      * @param childId id identifying the virtual child inside the view.
      * @param bounds child boundaries, relative to the top window.
      */
-    public void notifyVirtualViewEntered(@NonNull View view, int childId,
-            @NonNull Rect bounds) {
+    public void notifyViewEntered(@NonNull View view, int childId, @NonNull Rect bounds) {
         ensureServiceClientAddedIfNeeded();
 
         if (!mEnabled) {
+            if (mCallback != null) {
+                mCallback.onAutofillEvent(view, childId, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+            }
             return;
         }
 
@@ -261,7 +266,7 @@
      * @param view the {@link View} whose descendant is the virtual view.
      * @param childId id identifying the virtual child inside the view.
      */
-    public void notifyVirtualViewExited(@NonNull View view, int childId) {
+    public void notifyViewExited(@NonNull View view, int childId) {
         ensureServiceClientAddedIfNeeded();
 
         if (mEnabled && mHasSession) {
@@ -295,7 +300,7 @@
      * @param childId id identifying the virtual child inside the parent view.
      * @param value new value of the child.
      */
-    public void notifyVirtualValueChanged(View view, int childId, AutofillValue value) {
+    public void notifyValueChanged(View view, int childId, AutofillValue value) {
         if (!mEnabled || !mHasSession) {
             return;
         }
@@ -371,8 +376,8 @@
         return new AutofillId(parent.getAccessibilityViewId(), childId);
     }
 
-    private void startSession(AutofillId id, IBinder windowToken, Rect bounds,
-            AutofillValue value, int flags) {
+    private void startSession(@NonNull AutofillId id, @NonNull IBinder windowToken,
+            @NonNull Rect bounds, @NonNull AutofillValue value, int flags) {
         if (DEBUG) {
             Log.d(TAG, "startSession(): id=" + id + ", bounds=" + bounds + ", value=" + value
                     + ", flags=" + flags);
@@ -381,8 +386,8 @@
         try {
             mService.startSession(mContext.getActivityToken(), windowToken,
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
-                    mCallback != null, flags);
-            final AutofillClient client = getClient();
+                    mCallback != null, flags, mContext.getOpPackageName());
+            AutofillClient client = getClient();
             if (client != null) {
                 client.resetableStateAvailable();
             }
@@ -503,7 +508,7 @@
             return;
         }
         if (id.isVirtual()) {
-            mCallback.onAutofillEventVirtual(view, id.getVirtualChildId(), event);
+            mCallback.onAutofillEvent(view, id.getVirtualChildId(), event);
         } else {
             mCallback.onAutofillEvent(view, event);
         }
@@ -539,13 +544,23 @@
         public static final int EVENT_INPUT_HIDDEN = 2;
 
         /**
+         * The auto-fill input UI affordance associated with the view won't be shown because
+         * autofill is not available.
+         *
+         * <p>If the view provides its own auto-complete UI affordance but was not displaying it
+         * to avoid flickering, it could shown it upon receiving this event.
+         */
+        public static final int EVENT_INPUT_UNAVAILABLE = 3;
+
+        /**
          * Called after a change in the autofill state associated with a view.
          *
          * @param view view associated with the change.
          *
          * @param event currently either {@link #EVENT_INPUT_SHOWN} or {@link #EVENT_INPUT_HIDDEN}.
          */
-        public void onAutofillEvent(@NonNull View view, @AutofillEventType int event) {}
+        public void onAutofillEvent(@NonNull View view, @AutofillEventType int event) {
+        }
 
         /**
          * Called after a change in the autofill state associated with a virtual view.
@@ -555,8 +570,8 @@
          *
          * @param event currently either {@link #EVENT_INPUT_SHOWN} or {@link #EVENT_INPUT_HIDDEN}.
          */
-        public void onAutofillEventVirtual(@NonNull View view, int childId,
-                @AutofillEventType int event) {}
+        public void onAutofillEvent(@NonNull View view, int childId, @AutofillEventType int event) {
+        }
     }
 
     private static final class AutofillManagerClient extends IAutoFillManagerClient.Stub {
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 85b05e5..97210cc 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -32,7 +32,7 @@
     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,
-            boolean hasCallback, int flags);
+            boolean hasCallback, int flags, String packageName);
     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);
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index 020e80a..fae5742 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -514,14 +514,15 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
-        if (!isEnabled()) return;
+    public boolean autofill(AutofillValue value) {
+        if (!isEnabled()) return false;
 
         if (value.isList()) {
             setSelection(value.getListValue());
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
+        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 899a824..9dc61ab 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -584,14 +584,16 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
-        if (!isEnabled()) return;
+    public boolean autofill(AutofillValue value) {
+        if (!isEnabled()) return false;
 
         if (value.isToggle()) {
             setChecked(value.getToggleValue());
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
+
+        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index f63573f..7d04f35 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -775,14 +775,16 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
-        if (!isEnabled()) return;
+    public boolean autofill(AutofillValue value) {
+        if (!isEnabled()) return false;
 
         if (value.isDate()) {
             mDelegate.updateDate(value.getDateValue());
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
+
+        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index 5e8279a..a7574c7 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -426,23 +426,24 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
-        if (!isEnabled()) return;
+    public boolean autofill(AutofillValue value) {
+        if (!isEnabled()) return false;
 
         int index;
         if (value.isList()) {
             index = value.getListValue();
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
-            return;
+            return false;
         }
 
         final View child = getChildAt(index);
         if (child == null) {
             Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
-            return;
+            return false;
         }
         check(child.getId());
+        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c5c317d..26edc43 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10028,14 +10028,17 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
+    public boolean autofill(AutofillValue value) {
         if (value.isText()) {
             if (isTextEditable()) {
                 setText(value.getTextValue(), mBufferType, true, 0);
+                return true;
             }
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
+
+        return false;
     }
 
     @Override
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index cfa78b5..1e97e3b 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -530,14 +530,16 @@
     }
 
     @Override
-    public void autofill(AutofillValue value) {
-        if (!isEnabled()) return;
+    public boolean autofill(AutofillValue value) {
+        if (!isEnabled()) return false;
 
         if (value.isDate()) {
             mDelegate.setDate(value.getDateValue());
         } else {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
+
+        return true;
     }
 
     @Override
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index 96468ab..0a9faa1 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -142,6 +142,21 @@
             Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
         }
 
-        RuntimeInit.applicationInit(targetSdkVersion, argv, null);
+        // Check whether the first argument is a "-cp" in argv, and assume the next argument is the
+        // classpath. If found, create a PathClassLoader and use it for applicationInit.
+        ClassLoader classLoader = null;
+        if (argv != null && argv.length > 2 && argv[0].equals("-cp")) {
+            classLoader = ZygoteInit.createPathClassLoader(argv[1], targetSdkVersion);
+
+            // Install this classloader as the context classloader, too.
+            Thread.currentThread().setContextClassLoader(classLoader);
+
+            // Remove the classpath from the arguments.
+            String removedArgs[] = new String[argv.length - 2];
+            System.arraycopy(argv, 2, removedArgs, 0, argv.length - 2);
+            argv = removedArgs;
+        }
+
+        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
     }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 76d8af1..b2a2fec 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -468,7 +468,8 @@
                 String[] amendedArgs = new String[args.length + 2];
                 amendedArgs[0] = "-cp";
                 amendedArgs[1] = systemServerClasspath;
-                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
+                System.arraycopy(args, 0, amendedArgs, 2, args.length);
+                args = amendedArgs;
             }
 
             WrapperInit.execApplication(parsedArgs.invokeWith,
@@ -477,8 +478,7 @@
         } else {
             ClassLoader cl = null;
             if (systemServerClasspath != null) {
-                cl = createSystemServerClassLoader(systemServerClasspath,
-                                                   parsedArgs.targetSdkVersion);
+                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
 
                 Thread.currentThread().setContextClassLoader(cl);
             }
@@ -493,15 +493,14 @@
     }
 
     /**
-     * Creates a PathClassLoader for the system server. It also creates
-     * a shared namespace associated with the classloader to let it access
-     * platform-private native libraries.
+     * Creates a PathClassLoader for the given class path that is associated with a shared
+     * namespace, i.e., this classloader can access platform-private native libraries. The
+     * classloader will use java.library.path as the native library path.
      */
-    private static PathClassLoader createSystemServerClassLoader(String systemServerClasspath,
-                                                                 int targetSdkVersion) {
+    static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
       String libraryPath = System.getProperty("java.library.path");
 
-      return PathClassLoaderFactory.createClassLoader(systemServerClasspath,
+      return PathClassLoaderFactory.createClassLoader(classPath,
                                                       libraryPath,
                                                       libraryPath,
                                                       ClassLoader.getSystemClassLoader(),
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index ce51dc4..361fd3da 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -16,12 +16,12 @@
 
 package com.android.internal.view;
 
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.hardware.input.InputManager;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.util.MergedConfiguration;
 import android.view.DragEvent;
 import android.view.IWindow;
 import android.view.IWindowSession;
@@ -39,8 +39,9 @@
 
     @Override
     public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
-            Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig,
-            Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) {
+            Rect stableInsets, Rect outsets, boolean reportDraw,
+            MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
+            boolean alwaysConsumeNavBar, int displayId) {
         if (reportDraw) {
             try {
                 mSession.finishDrawing(this);
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 80207ee..e86932c 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -115,6 +115,7 @@
         // Lets calculate how many lines the given measurement allows us.
         int availableHeight = height - mPaddingTop - mPaddingBottom;
         int maxLines = availableHeight / getLineHeight();
+        maxLines = Math.max(1, maxLines);
         if (getMaxLines() > 0) {
             maxLines = Math.min(getMaxLines(), maxLines);
         }
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index b259ad1..1104318 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.widget;
 
-import com.android.internal.R;
-
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -28,6 +26,8 @@
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
+
 /**
  * A custom-built layout for the Notification.MessagingStyle.
  *
@@ -119,23 +119,30 @@
                 }
                 final View child = getChildAt(i);
                 LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
-
+                ImageFloatingTextView textChild = null;
                 if (child instanceof ImageFloatingTextView) {
                     // Pretend we need the image padding for all views, we don't know which
                     // one will end up needing to do this (might end up not using all the space,
                     // but calculating this exactly would be more expensive).
-                    ((ImageFloatingTextView) child).setNumIndentLines(
-                            mIndentLines == 2 ? 3 : mIndentLines);
+                    textChild = (ImageFloatingTextView) child;
+                    textChild.setNumIndentLines(mIndentLines == 2 ? 3 : mIndentLines);
                 }
 
-                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+                int spacing = first ? 0 : mSpacing;
+                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, totalHeight
+                        - mPaddingTop - mPaddingBottom + spacing);
 
                 final int childHeight = child.getMeasuredHeight();
                 int newHeight = Math.max(totalHeight, totalHeight + childHeight + lp.topMargin +
-                        lp.bottomMargin + (first ? 0 : mSpacing));
+                        lp.bottomMargin + spacing);
                 first = false;
+                boolean measuredTooSmall = false;
+                if (textChild != null) {
+                    measuredTooSmall = childHeight < textChild.getLayout().getHeight()
+                            + textChild.getPaddingTop() + textChild.getPaddingBottom();
+                }
 
-                if (newHeight <= targetHeight) {
+                if (newHeight <= targetHeight && !measuredTooSmall) {
                     totalHeight = newHeight;
                     lp.hide = false;
                 } else {
@@ -168,7 +175,15 @@
                 }
                 boolean changed = textChild.setNumIndentLines(Math.max(0, imageLines));
                 if (changed || !recalculateVisibility) {
-                    measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+                    final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+                            mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
+                            lp.width);
+                    // we want to measure it at most as high as it is currently, otherwise we'll
+                    // drop later lines
+                    final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                            targetHeight - child.getMeasuredHeight(), lp.height);
+
+                    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);;
                 }
                 imageLines -= textChild.getLineCount();
             }
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index 79439e2..5553a3e 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -30,7 +30,7 @@
 
 class SkColorFilterGlue {
 public:
-    static void finalizer(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
+    static void SafeUnref(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
         SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
         SkSafeUnref(filter);
     }
@@ -57,19 +57,19 @@
 };
 
 static const JNINativeMethod colorfilter_methods[] = {
-    {"destroyFilter", "(J)V", (void*) SkColorFilterGlue::finalizer}
+    {"nSafeUnref", "(J)V", (void*) SkColorFilterGlue::SafeUnref}
 };
 
 static const JNINativeMethod porterduff_methods[] = {
-    { "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
+    { "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter },
 };
 
 static const JNINativeMethod lighting_methods[] = {
-    { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter   },
+    { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter },
 };
 
 static const JNINativeMethod colormatrix_methods[] = {
-    { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
+    { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter },
 };
 
 int register_android_graphics_ColorFilter(JNIEnv* env) {
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 1bd2333..678041f 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -404,6 +404,11 @@
     signalExceptionForError(env, err);
 }
 
+static void JHwParcel_native_release(
+        JNIEnv *env, jobject thiz) {
+    JHwParcel::GetNativeContext(env, thiz)->setParcel(NULL, false /* assumeOwnership */);
+}
+
 static void JHwParcel_native_releaseTemporaryStorage(
         JNIEnv *env, jobject thiz) {
     JHwParcel::GetNativeContext(env, thiz)->getStorage()->release(env);
@@ -955,6 +960,10 @@
 
     { "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
         (void *)JHwParcel_native_writeBuffer },
+
+    { "release", "()V",
+        (void *)JHwParcel_native_release },
+
 };
 
 namespace android {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 9660de4..956b724 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -26,7 +26,9 @@
 #include <sys/un.h>
 #include <unistd.h>
 
+#include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
 // Static whitelist of open paths that the zygote is allowed to keep open.
@@ -65,9 +67,10 @@
       return true;
   }
 
-  static const std::string kFrameworksPrefix = "/system/framework/";
-  static const std::string kJarSuffix = ".jar";
-  if (StartsWith(path, kFrameworksPrefix) && EndsWith(path, kJarSuffix)) {
+  static const char* kFrameworksPrefix = "/system/framework/";
+  static const char* kJarSuffix = ".jar";
+  if (android::base::StartsWith(path, kFrameworksPrefix)
+      && android::base::EndsWith(path, kJarSuffix)) {
     return true;
   }
 
@@ -79,28 +82,31 @@
   // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap
   // /data/resource-cache/system@vendor@overlay-subdir@pg@framework-res.apk@idmap
   // See AssetManager.cpp for more details on overlay-subdir.
-  static const std::string kOverlayDir = "/system/vendor/overlay/";
-  static const std::string kVendorOverlayDir = "/vendor/overlay";
-  static const std::string kOverlaySubdir = "/system/vendor/overlay-subdir/";
-  static const std::string kApkSuffix = ".apk";
+  static const char* kOverlayDir = "/system/vendor/overlay/";
+  static const char* kVendorOverlayDir = "/vendor/overlay";
+  static const char* kOverlaySubdir = "/system/vendor/overlay-subdir/";
+  static const char* kApkSuffix = ".apk";
 
-  if ((StartsWith(path, kOverlayDir) || StartsWith(path, kOverlaySubdir)
-       || StartsWith(path, kVendorOverlayDir))
-      && EndsWith(path, kApkSuffix)
+  if ((android::base::StartsWith(path, kOverlayDir)
+       || android::base::StartsWith(path, kOverlaySubdir)
+       || android::base::StartsWith(path, kVendorOverlayDir))
+      && android::base::EndsWith(path, kApkSuffix)
       && path.find("/../") == std::string::npos) {
     return true;
   }
 
-  static const std::string kOverlayIdmapPrefix = "/data/resource-cache/";
-  static const std::string kOverlayIdmapSuffix = ".apk@idmap";
-  if (StartsWith(path, kOverlayIdmapPrefix) && EndsWith(path, kOverlayIdmapSuffix)
+  static const char* kOverlayIdmapPrefix = "/data/resource-cache/";
+  static const char* kOverlayIdmapSuffix = ".apk@idmap";
+  if (android::base::StartsWith(path, kOverlayIdmapPrefix)
+      && android::base::EndsWith(path, kOverlayIdmapSuffix)
       && path.find("/../") == std::string::npos) {
     return true;
   }
 
   // All regular files that are placed under this path are whitelisted automatically.
-  static const std::string kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
-  if (StartsWith(path, kZygoteWhitelistPath) && path.find("/../") == std::string::npos) {
+  static const char* kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
+  if (android::base::StartsWith(path, kZygoteWhitelistPath)
+      && path.find("/../") == std::string::npos) {
     return true;
   }
 
@@ -111,24 +117,6 @@
     : whitelist_() {
 }
 
-// TODO: Call android::base::StartsWith instead of copying the code here.
-// static
-bool FileDescriptorWhitelist::StartsWith(const std::string& str,
-                                         const std::string& prefix) {
-  return str.compare(0, prefix.size(), prefix) == 0;
-}
-
-// TODO: Call android::base::EndsWith instead of copying the code here.
-// static
-bool FileDescriptorWhitelist::EndsWith(const std::string& str,
-                                       const std::string& suffix) {
-  if (suffix.size() > str.size()) {
-    return false;
-  }
-
-  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
 FileDescriptorWhitelist* FileDescriptorWhitelist::instance_ = nullptr;
 
 // static
@@ -174,7 +162,8 @@
   }
 
   std::string file_path;
-  if (!Readlink(fd, &file_path)) {
+  const std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fd);
+  if (!android::base::Readlink(fd_path, &file_path)) {
     return NULL;
   }
 
@@ -299,30 +288,6 @@
   is_sock(false) {
 }
 
-// TODO: Call android::base::Readlink instead of copying the code here.
-// static
-bool FileDescriptorInfo::Readlink(const int fd, std::string* result) {
-  char path[64];
-  snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
-
-  // Code copied from android::base::Readlink starts here :
-
-  // Annoyingly, the readlink system call returns EINVAL for a zero-sized buffer,
-  // and truncates to whatever size you do supply, so it can't be used to query.
-  // We could call lstat first, but that would introduce a race condition that
-  // we couldn't detect.
-  // ext2 and ext4 both have PAGE_SIZE limitations, so we assume that here.
-  char buf[4096];
-  ssize_t len = readlink(path, buf, sizeof(buf));
-  if (len == -1) {
-    PLOG(ERROR) << "Readlink on " << fd << " failed.";
-    return false;
-  }
-
-  result->assign(buf, len);
-  return true;
-}
-
 // static
 bool FileDescriptorInfo::GetSocketName(const int fd, std::string* result) {
   sockaddr_storage ss;
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
index 03298c3..a39e387 100644
--- a/core/jni/fd_utils.h
+++ b/core/jni/fd_utils.h
@@ -59,10 +59,6 @@
  private:
   FileDescriptorWhitelist();
 
-  static bool StartsWith(const std::string& str, const std::string& prefix);
-
-  static bool EndsWith(const std::string& str, const std::string& suffix);
-
   static FileDescriptorWhitelist* instance_;
 
   std::vector<std::string> whitelist_;
@@ -99,8 +95,6 @@
   FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
                      int fd_flags, int fs_flags, off_t offset);
 
-  static bool Readlink(const int fd, std::string* result);
-
   // Returns the locally-bound name of the socket |fd|. Returns true
   // iff. all of the following hold :
   //
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c991f22..58e4051 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3593,7 +3593,7 @@
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
-        <service android:name="com.android.server.BackgroundDexOptJobService"
+        <service android:name="com.android.server.pm.BackgroundDexOptService"
                  android:exported="true"
                  android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6e0d9dc..385f256 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1386,6 +1386,9 @@
     <!-- Boolean indicating if current platform supports BLE peripheral mode -->
     <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
 
+    <!-- Boolean indicating if current platform supports HFP inband ringing -->
+    <bool name="config_bluetooth_hfp_inband_ringing_support">false</bool>
+
     <!-- Max number of scan filters supported by blutooth controller. 0 if the
          device does not support hardware scan filters-->
     <integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1ed069b..d1c14e9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4567,22 +4567,25 @@
     <!-- Accessibility string used for describing the button in time picker that changes the dialog to circular clock mode. [CHAR LIMIT=NONE] -->
     <string name="time_picker_radial_mode_description">Switch to clock mode for the time input.</string>
 
-    <!-- Title for the auto-fill save dialog shown when the the contents of the activity can be saved
-         by an auto-fill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
+    <!-- Accessibility title for the autofill dialog used to select a list of options to autofill an activity. [CHAR LIMIT=NONE] -->
+    <string name="autofill_picker_accessibility_title">Autofill options</string>
+
+    <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+         by an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
     <string name="autofill_save_title">Save to <xliff:g id="label" example="MyPass">%1$s</xliff:g>?</string>
-    <!-- Title for the auto-fill save dialog shown when the the contents of the activity can be saved
-         by an auto-fill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
+    <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+         by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
     <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to <xliff:g id="label" example="MyPass">%2$s</xliff:g>?</string>
-    <!-- Label for the auto-fill save button [CHAR LIMIT=NONE] -->
+    <!-- Label for the autofill save button [CHAR LIMIT=NONE] -->
     <string name="autofill_save_yes">Save</string>
-    <!-- Label for the auto-fill cancel button [CHAR LIMIT=NONE] -->
+    <!-- Label for the autofill cancel button [CHAR LIMIT=NONE] -->
     <string name="autofill_save_no">No thanks</string>
 
-    <!-- Label for the type of data being saved for auto-fill when it represent user credentials with a password [CHAR LIMIT=NONE] -->
+    <!-- Label for the type of data being saved for autofill when it represent user credentials with a password [CHAR LIMIT=NONE] -->
     <string name="autofill_save_type_password">password</string>
-    <!-- Label for the type of data being saved for auto-fill when it represent an address (street, city, etc.) [CHAR LIMIT=NONE] -->
+    <!-- Label for the type of data being saved for autofill when it represent an address (street, city, etc.) [CHAR LIMIT=NONE] -->
     <string name="autofill_save_type_address">address</string>
-    <!-- Label for the type of data being saved for auto-fill when it represents a credit card [CHAR LIMIT=NONE] -->
+    <!-- Label for the type of data being saved for autofill when it represents a credit card [CHAR LIMIT=NONE] -->
     <string name="autofill_save_type_credit_card">credit card</string>
 
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 07cecbc..0d4a407 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -242,6 +242,7 @@
   <java-symbol type="bool" name="config_bluetooth_address_validation" />
   <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
   <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
+  <java-symbol type="bool" name="config_bluetooth_hfp_inband_ringing_support" />
   <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
   <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
   <java-symbol type="bool" name="config_enableAutoPowerModes" />
@@ -2848,6 +2849,7 @@
   <java-symbol type="id" name="autofill_save_yes" />
   <java-symbol type="id" name="autofill_save_close" />
   <java-symbol type="string" name="autofill" />
+  <java-symbol type="string" name="autofill_picker_accessibility_title " />
   <java-symbol type="string" name="autofill_save_title" />
   <java-symbol type="string" name="autofill_save_title_with_type" />
   <java-symbol type="string" name="autofill_save_yes" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index fba8e23..dbc9e5d 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -40,6 +40,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common org.apache.http.legacy
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index ac62bf4..0ca3729 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -28,21 +28,51 @@
  */
 public class ColorFilter {
     /**
-     * Holds the pointer to the native SkColorFilter instance.
-     *
-     * @hide
+     * @deprecated Use subclass constructors directly instead.
      */
-    public long native_instance;
+    @Deprecated
+    public ColorFilter() {}
+
+    /**
+     * Holds the pointer to the native SkColorFilter instance.
+     */
+    private long mNativeInstance;
+
+    long createNativeInstance() {
+        return 0;
+    }
+
+    void discardNativeInstance() {
+        if (mNativeInstance != 0) {
+            nSafeUnref(mNativeInstance);
+            mNativeInstance = 0;
+        }
+    }
 
     @Override
     protected void finalize() throws Throwable {
         try {
-            super.finalize();
+            if (mNativeInstance != 0) {
+                nSafeUnref(mNativeInstance);
+            }
+            mNativeInstance = -1;
         } finally {
-            destroyFilter(native_instance);
-            native_instance = 0;
+            super.finalize();
         }
     }
 
-    static native void destroyFilter(long native_instance);
+    /** @hide */
+    public long getNativeInstance() {
+        if (mNativeInstance == -1) {
+            throw new IllegalStateException("attempting to use a finalized ColorFilter");
+        }
+
+        if (mNativeInstance == 0) {
+            mNativeInstance = createNativeInstance();
+        }
+        return mNativeInstance;
+
+    }
+
+    static native void nSafeUnref(long native_instance);
 }
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index 1b1849e..6299b2c 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -268,4 +268,21 @@
         m[5] = 1;   m[6] = -0.34414f;   m[7] = -0.71414f;
         m[10] = 1;  m[11] = 1.772f;     m[12] = 0;
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        // if (obj == this) return true; -- NaN value would mean matrix != itself
+        if (!(obj instanceof ColorMatrix)) {
+            return false;
+        }
+
+        // we don't use Arrays.equals(), since that considers NaN == NaN
+        final float[] other = ((ColorMatrix) obj).mArray;
+        for (int i = 0; i < 20; i++) {
+            if (other[i] != mArray[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 291c8ff..61f6cc5 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -16,6 +16,9 @@
 
 package android.graphics;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 /**
  * A color filter that transforms colors through a 4x5 color matrix. This filter
  * can be used to change the saturation of pixels, convert from YUV to RGB, etc.
@@ -32,9 +35,8 @@
      *               the filter, so changes made to the matrix after the filter
      *               is constructed will not be reflected in the filter.
      */
-    public ColorMatrixColorFilter(ColorMatrix matrix) {
+    public ColorMatrixColorFilter(@NonNull ColorMatrix matrix) {
         mMatrix.set(matrix);
-        update();
     }
 
     /**
@@ -44,84 +46,76 @@
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See ColorMatrix.
      */
-    public ColorMatrixColorFilter(float[] array) {
+    public ColorMatrixColorFilter(@NonNull float[] array) {
         if (array.length < 20) {
             throw new ArrayIndexOutOfBoundsException();
         }
         mMatrix.set(array);
-        update();
     }
 
     /**
-     * Returns the {@link ColorMatrix} used by this filter. The returned
-     * value is never null. Modifying the returned matrix does not have
-     * any effect until you call {@link #setColorMatrix(ColorMatrix)}.
+     * Copies the ColorMatrix from the filter into the passed ColorMatrix.
      *
-     * @see #setColorMatrix(ColorMatrix)
-     *
-     * @hide
+     * @param colorMatrix Set to the current value of the filter's ColorMatrix.
      */
-    public ColorMatrix getColorMatrix() {
-        return mMatrix;
+    public void getColorMatrix(ColorMatrix colorMatrix) {
+        colorMatrix.set(mMatrix);
     }
 
     /**
-     * Specifies the color matrix used by this filter. If the specified
-     * color matrix is null, this filter's color matrix will be reset to
-     * the identity matrix.
+     * Copies the provided color matrix to be used by this filter.
+     *
+     * If the specified color matrix is null, this filter's color matrix will be reset to the
+     * identity matrix.
      *
      * @param matrix A {@link ColorMatrix} or null
      *
-     * @see #getColorMatrix()
-     * @see android.graphics.ColorMatrix#reset()
-     * @see #setColorMatrix(float[])
-     *
-     * @hide
+     * @see #getColorMatrix(ColorMatrix)
+     * @see #setColorMatrixArray(float[])
+     * @see ColorMatrix#reset()
      */
-    public void setColorMatrix(ColorMatrix matrix) {
+    public void setColorMatrix(@Nullable ColorMatrix matrix) {
+        discardNativeInstance();
         if (matrix == null) {
             mMatrix.reset();
-        } else if (matrix != mMatrix) {
+        } else {
             mMatrix.set(matrix);
         }
-        update();
     }
 
     /**
-     * Specifies the color matrix used by this filter. If the specified
-     * color matrix is null, this filter's color matrix will be reset to
-     * the identity matrix.
+     * Copies the provided color matrix to be used by this filter.
+     *
+     * If the specified color matrix is null, this filter's color matrix will be reset to the
+     * identity matrix.
      *
      * @param array Array of floats used to transform colors, treated as a 4x5
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See {@link ColorMatrix}.
      *
-     * @see #getColorMatrix()
-     * @see android.graphics.ColorMatrix#reset()
+     * @see #getColorMatrix(ColorMatrix)
      * @see #setColorMatrix(ColorMatrix)
+     * @see ColorMatrix#reset()
      *
      * @throws ArrayIndexOutOfBoundsException if the specified array's
      *         length is < 20
-     *
-     * @hide
      */
-    public void setColorMatrix(float[] array) {
+    public void setColorMatrixArray(@Nullable float[] array) {
+        // called '...Array' so that passing null isn't ambiguous
+        discardNativeInstance();
         if (array == null) {
             mMatrix.reset();
         } else {
             if (array.length < 20) {
                 throw new ArrayIndexOutOfBoundsException();
             }
-
             mMatrix.set(array);
         }
-        update();
     }
 
-    private void update() {
-        final float[] colorMatrix = mMatrix.getArray();
-        destroyFilter(native_instance);
-        native_instance = nativeColorMatrixFilter(colorMatrix);
+    @Override
+    long createNativeInstance() {
+        return nativeColorMatrixFilter(mMatrix.getArray());
     }
 
     private static native long nativeColorMatrixFilter(float[] array);
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index ad78430..b0c145b 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -21,6 +21,8 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
+
 /**
  * A color filter that can be used to simulate simple lighting effects.
  * A <code>LightingColorFilter</code> is defined by two parameters, one
@@ -37,7 +39,9 @@
  * The result is pinned to the <code>[0..255]</code> range for each channel.
  */
 public class LightingColorFilter extends ColorFilter {
+    @ColorInt
     private int mMul;
+    @ColorInt
     private int mAdd;
 
     /**
@@ -45,10 +49,9 @@
      * and then adds a second color. The alpha components of the mul and add
      * arguments are ignored.
      */
-    public LightingColorFilter(int mul, int add) {
+    public LightingColorFilter(@ColorInt int mul, @ColorInt int add) {
         mMul = mul;
         mAdd = add;
-        update();
     }
 
     /**
@@ -56,9 +59,8 @@
      * color filter is applied.
      *
      * @see #setColorMultiply(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColorMultiply() {
         return mMul;
     }
@@ -69,12 +71,12 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorMultiply()
-     *
-     * @hide
      */
-    public void setColorMultiply(int mul) {
-        mMul = mul;
-        update();
+    public void setColorMultiply(@ColorInt int mul) {
+        if (mMul != mul) {
+            mMul = mul;
+            discardNativeInstance();
+        }
     }
 
     /**
@@ -82,9 +84,8 @@
      * when the color filter is applied.
      *
      * @see #setColorAdd(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColorAdd() {
         return mAdd;
     }
@@ -95,17 +96,17 @@
      * The alpha channel of this color is ignored.
      *
      * @see #getColorAdd()
-     *
-     * @hide
      */
-    public void setColorAdd(int add) {
-        mAdd = add;
-        update();
+    public void setColorAdd(@ColorInt int add) {
+        if (mAdd != add) {
+            mAdd = add;
+            discardNativeInstance();
+        }
     }
 
-    private void update() {
-        destroyFilter(native_instance);
-        native_instance = native_CreateLightingFilter(mMul, mAdd);
+    @Override
+    long createNativeInstance() {
+        return native_CreateLightingFilter(mMul, mAdd);
     }
 
     private static native long native_CreateLightingFilter(int mul, int add);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 7ca4615..5d6aa8a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -42,7 +42,8 @@
 public class Paint {
 
     private long mNativePaint;
-    private long mNativeShader = 0;
+    private long mNativeShader;
+    private long mNativeColorFilter;
 
     // The approximate size of a native paint object.
     private static final long NATIVE_PAINT_SIZE = 98;
@@ -584,6 +585,11 @@
             mNativeShader = newNativeShader;
             nSetShader(mNativePaint, mNativeShader);
         }
+        long newNativeColorFilter = mColorFilter == null ? 0 : mColorFilter.getNativeInstance();
+        if (newNativeColorFilter != mNativeColorFilter) {
+            mNativeColorFilter = newNativeColorFilter;
+            nSetColorFilter(mNativePaint, mNativeColorFilter);
+        }
         return mNativePaint;
     }
 
@@ -1044,10 +1050,13 @@
      * @return       filter
      */
     public ColorFilter setColorFilter(ColorFilter filter) {
-        long filterNative = 0;
-        if (filter != null)
-            filterNative = filter.native_instance;
-        nSetColorFilter(mNativePaint, filterNative);
+        // If mColorFilter changes, cached value of native shader aren't valid, since
+        // old shader's pointer may be reused by another shader allocation later
+        if (mColorFilter != filter) {
+            mNativeColorFilter = -1;
+        }
+
+        // Defer setting the filter natively until getNativeInstance() is called
         mColorFilter = filter;
         return filter;
     }
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index 69d6891..ccc6ead 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -24,6 +24,7 @@
  * color and a specific {@link PorterDuff Porter-Duff composite mode}.
  */
 public class PorterDuffColorFilter extends ColorFilter {
+    @ColorInt
     private int mColor;
     private PorterDuff.Mode mMode;
 
@@ -40,7 +41,6 @@
     public PorterDuffColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) {
         mColor = color;
         mMode = mode;
-        update();
     }
 
     /**
@@ -49,9 +49,8 @@
      *
      * @see Color
      * @see #setColor(int)
-     *
-     * @hide
      */
+    @ColorInt
     public int getColor() {
         return mColor;
     }
@@ -65,12 +64,12 @@
      * @see Color
      * @see #getColor()
      * @see #getMode()
-     *
-     * @hide
      */
-    public void setColor(int color) {
-        mColor = color;
-        update();
+    public void setColor(@ColorInt int color) {
+        if (mColor != color) {
+            mColor = color;
+            discardNativeInstance();
+        }
     }
 
     /**
@@ -79,8 +78,6 @@
      *
      * @see PorterDuff
      * @see #setMode(android.graphics.PorterDuff.Mode)
-     *
-     * @hide
      */
     public PorterDuff.Mode getMode() {
         return mMode;
@@ -93,17 +90,18 @@
      * @see PorterDuff
      * @see #getMode()
      * @see #getColor()
-     *
-     * @hide
      */
     public void setMode(@NonNull PorterDuff.Mode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("mode must be non-null");
+        }
         mMode = mode;
-        update();
+        discardNativeInstance();
     }
 
-    private void update() {
-        destroyFilter(native_instance);
-        native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
+    @Override
+    long createNativeInstance() {
+        return native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
     }
 
     @Override
@@ -115,10 +113,7 @@
             return false;
         }
         final PorterDuffColorFilter other = (PorterDuffColorFilter) object;
-        if (mColor != other.mColor || mMode != other.mMode) {
-            return false;
-        }
-        return true;
+        return (mColor == other.mColor && mMode.nativeInt == other.mMode.nativeInt);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index b584e0d..8410ab2 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -106,8 +106,10 @@
     }
 
     void discardNativeInstance() {
-        nativeSafeUnref(mNativeInstance);
-        mNativeInstance = 0;
+        if (mNativeInstance != 0) {
+            nativeSafeUnref(mNativeInstance);
+            mNativeInstance = 0;
+        }
     }
 
     /**
@@ -120,7 +122,9 @@
     @Override
     protected void finalize() throws Throwable {
         try {
-            nativeSafeUnref(mNativeInstance);
+            if (mNativeInstance != 0) {
+                nativeSafeUnref(mNativeInstance);
+            }
             mNativeInstance = -1;
         } finally {
             super.finalize();
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 0722c18..c6c9271 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -218,6 +218,8 @@
     }
 
     /**
+     * Only call this method after bound is set on this drawable.
+     *
      * @return the mask path object used to clip the drawable
      */
     public Path getIconMask() {
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 3a12419..a1539b8 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -333,7 +333,7 @@
         // Color filters always override tint filters.
         final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter);
         final long colorFilterNativeInstance = colorFilter == null ? 0 :
-                colorFilter.native_instance;
+                colorFilter.getNativeInstance();
         boolean canReuseCache = mVectorState.canReuseCache();
         int pixelCount = nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(),
                 colorFilterNativeInstance, mTmpBounds, needMirroring(),
diff --git a/libs/hwui/FloatColor.h b/libs/hwui/FloatColor.h
index d8afa35..a738ba4 100644
--- a/libs/hwui/FloatColor.h
+++ b/libs/hwui/FloatColor.h
@@ -38,13 +38,14 @@
     }
 
     // "color" is a gamma-encoded sRGB color
-    // After calling this method, the color is stored as a linear color. The color
-    // is not pre-multiplied.
-    void setUnPreMultipliedSRGB(uint32_t color) {
+    // After calling this method, the color is stored as a un-premultiplied linear color
+    // if linear blending is enabled. Otherwise, the color is stored as a un-premultiplied
+    // gamma-encoded sRGB color
+    void setUnPreMultiplied(uint32_t color) {
         a = ((color >> 24) & 0xff) / 255.0f;
-        r = EOCF_sRGB(((color >> 16) & 0xff) / 255.0f);
-        g = EOCF_sRGB(((color >>  8) & 0xff) / 255.0f);
-        b = EOCF_sRGB(((color      ) & 0xff) / 255.0f);
+        r = EOCF(((color >> 16) & 0xff) / 255.0f);
+        g = EOCF(((color >>  8) & 0xff) / 255.0f);
+        b = EOCF(((color      ) & 0xff) / 255.0f);
     }
 
     bool isNotBlack() {
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 18bfcc2..dceb285 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -189,9 +189,9 @@
         float amount, uint8_t*& dst) const {
     float oppAmount = 1.0f - amount;
     float a = start.a * oppAmount + end.a * amount;
-    *dst++ = uint8_t(a * OECF_sRGB((start.r * oppAmount + end.r * amount)) * 255.0f);
-    *dst++ = uint8_t(a * OECF_sRGB((start.g * oppAmount + end.g * amount)) * 255.0f);
-    *dst++ = uint8_t(a * OECF_sRGB((start.b * oppAmount + end.b * amount)) * 255.0f);
+    *dst++ = uint8_t(a * OECF(start.r * oppAmount + end.r * amount) * 255.0f);
+    *dst++ = uint8_t(a * OECF(start.g * oppAmount + end.g * amount) * 255.0f);
+    *dst++ = uint8_t(a * OECF(start.b * oppAmount + end.b * amount) * 255.0f);
     *dst++ = uint8_t(a * 255.0f);
 }
 
@@ -201,17 +201,14 @@
     float a = start.a * oppAmount + end.a * amount;
     float* d = (float*) dst;
 #ifdef ANDROID_ENABLE_LINEAR_BLENDING
+    // We want to stay linear
     *d++ = a * (start.r * oppAmount + end.r * amount);
     *d++ = a * (start.g * oppAmount + end.g * amount);
     *d++ = a * (start.b * oppAmount + end.b * amount);
 #else
-    // What we're doing to the alpha channel here is technically incorrect
-    // but reproduces Android's old behavior when the alpha was pre-multiplied
-    // with gamma-encoded colors
-    a = EOCF_sRGB(a);
-    *d++ = a * OECF_sRGB(start.r * oppAmount + end.r * amount);
-    *d++ = a * OECF_sRGB(start.g * oppAmount + end.g * amount);
-    *d++ = a * OECF_sRGB(start.b * oppAmount + end.b * amount);
+    *d++ = a * OECF(start.r * oppAmount + end.r * amount);
+    *d++ = a * OECF(start.g * oppAmount + end.g * amount);
+    *d++ = a * OECF(start.b * oppAmount + end.b * amount);
 #endif
     *d++ = a;
     dst += 4 * sizeof(float);
@@ -232,10 +229,10 @@
     ChannelMixer mix = gMixers[mUseFloatTexture];
 
     FloatColor start;
-    start.setUnPreMultipliedSRGB(colors[0]);
+    start.setUnPreMultiplied(colors[0]);
 
     FloatColor end;
-    end.setUnPreMultipliedSRGB(colors[1]);
+    end.setUnPreMultiplied(colors[1]);
 
     int currentPos = 1;
     float startPos = positions[0];
@@ -250,7 +247,7 @@
 
             currentPos++;
 
-            end.setUnPreMultipliedSRGB(colors[currentPos]);
+            end.setUnPreMultiplied(colors[currentPos]);
             distance = positions[currentPos] - startPos;
         }
 
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 40ab778..38c23e4 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -190,7 +190,7 @@
 // Dithering must be done in the quantization space
 // When we are writing to an sRGB framebuffer, we must do the following:
 //     EOTF(OETF(color) + dither)
-// The dithering pattern is generated with a triangle noise generator in the range [-0.0,1.0]
+// The dithering pattern is generated with a triangle noise generator in the range [-1.0,1.0]
 // TODO: Handle linear fp16 render targets
 const char* gFS_Gradient_Functions = R"__SHADER__(
         float triangleNoise(const highp vec2 n) {
@@ -202,23 +202,26 @@
 )__SHADER__";
 const char* gFS_Gradient_Preamble[2] = {
         // Linear framebuffer
-        "\nvec4 dither(const vec4 color) {\n"
-        "    return vec4(color.rgb + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0), color.a);\n"
-        "}\n"
-        "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
-        "    vec4 c = mix(a, b, v);\n"
-        "    c.a = EOTF_sRGB(c.a);\n" // This is technically incorrect but preserves compatibility
-        "    return vec4(OETF_sRGB(c.rgb) * c.a, c.a);\n"
-        "}\n",
+        R"__SHADER__(
+        vec4 dither(const vec4 color) {
+            return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
+        }
+        vec4 gradientMix(const vec4 a, const vec4 b, float v) {
+            vec4 c = mix(a, b, v);
+            return vec4(c.rgb * c.a, c.a);
+        }
+        )__SHADER__",
         // sRGB framebuffer
-        "\nvec4 dither(const vec4 color) {\n"
-        "    vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);\n"
-        "    return vec4(dithered * dithered, color.a);\n"
-        "}\n"
-        "\nvec4 gammaMix(const vec4 a, const vec4 b, float v) {\n"
-        "    vec4 c = mix(a, b, v);\n"
-        "    return vec4(c.rgb * c.a, c.a);\n"
-        "}\n"
+        R"__SHADER__(
+        vec4 dither(const vec4 color) {
+            vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
+            return vec4(dithered * dithered, color.a);
+        }
+        vec4 gradientMixMix(const vec4 a, const vec4 b, float v) {
+            vec4 c = mix(a, b, v);
+            return vec4(c.rgb * c.a, c.a);
+        }
+        )__SHADER__",
 };
 
 // Uses luminance coefficients from Rec.709 to choose the appropriate gamma
@@ -272,19 +275,19 @@
         // Linear
         "    vec4 gradientColor = texture2D(gradientSampler, linear);\n",
 
-        "    vec4 gradientColor = gammaMix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
+        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
 
         // Circular
         "    vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
 
-        "    vec4 gradientColor = gammaMix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
+        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
 
         // Sweep
         "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
         "    vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n",
 
         "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
-        "    vec4 gradientColor = gammaMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
+        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
 };
 const char* gFS_Main_FetchBitmap =
         "    vec4 bitmapColor = OETF(texture2D(bitmapSampler, outBitmapTexCoords));\n";
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 760c10c..4f7f9d7 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -173,8 +173,8 @@
         outData->gradientSampler = 0;
         outData->gradientTexture = nullptr;
 
-        outData->startColor.setUnPreMultipliedSRGB(gradInfo.fColors[0]);
-        outData->endColor.setUnPreMultipliedSRGB(gradInfo.fColors[1]);
+        outData->startColor.setUnPreMultiplied(gradInfo.fColors[0]);
+        outData->endColor.setUnPreMultiplied(gradInfo.fColors[1]);
     }
 
     return true;
diff --git a/libs/hwui/VkLayer.cpp b/libs/hwui/VkLayer.cpp
index 537b3ea..ef4784b 100644
--- a/libs/hwui/VkLayer.cpp
+++ b/libs/hwui/VkLayer.cpp
@@ -29,7 +29,7 @@
     SkImageInfo info = SkImageInfo::MakeS32(mWidth, mHeight, kPremul_SkAlphaType);
     surface = SkSurface::MakeRenderTarget(mRenderState.getGrContext(), SkBudgeted::kNo, info);
     surface->getCanvas()->clear(SK_ColorBLUE);
-    mImage = surface->makeImageSnapshot(SkBudgeted::kNo);
+    mImage = surface->makeImageSnapshot();
 }
 
 void VkLayer::onVkContextDestroyed() {
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 62fd395..c28aa5e 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1807,6 +1807,9 @@
          * {@link #TYPE_S_DMB}, and
          * {@link #TYPE_T_DMB}.
          *
+         * <p>This value cannot be changed once it's set. Trying to modify it will make the update
+         * fail.
+         *
          * <p>This is a required field.
          *
          * <p>Type: TEXT
diff --git a/packages/MtpDocumentsProvider/tests/Android.mk b/packages/MtpDocumentsProvider/tests/Android.mk
index e50d6fb..148cd0d 100644
--- a/packages/MtpDocumentsProvider/tests/Android.mk
+++ b/packages/MtpDocumentsProvider/tests/Android.mk
@@ -8,5 +8,6 @@
 LOCAL_PACKAGE_NAME := MtpDocumentsProviderTests
 LOCAL_INSTRUMENTATION_FOR := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 include $(BUILD_PACKAGE)
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.mk b/packages/PrintSpooler/tests/outofprocess/Android.mk
index d1d0ee4..3c02453 100644
--- a/packages/PrintSpooler/tests/outofprocess/Android.mk
+++ b/packages/PrintSpooler/tests/outofprocess/Android.mk
@@ -24,5 +24,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4
 
 LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/tests/integ/Android.mk b/packages/SettingsLib/tests/integ/Android.mk
index 60d1c77..7ace048 100644
--- a/packages/SettingsLib/tests/integ/Android.mk
+++ b/packages/SettingsLib/tests/integ/Android.mk
@@ -25,6 +25,7 @@
 LOCAL_JACK_FLAGS := --multi-dex native
 
 LOCAL_PACKAGE_NAME := SettingsLibTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 91a4e79..1f1c189 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -248,6 +248,9 @@
     @GuardedBy("mLock")
     private HandlerThread mHandlerThread;
 
+    @GuardedBy("mLock")
+    private Handler mHandler;
+
     // We have to call in the user manager with no lock held,
     private volatile UserManager mUserManager;
 
@@ -300,10 +303,13 @@
             mHandlerThread = new HandlerThread(LOG_TAG,
                     Process.THREAD_PRIORITY_BACKGROUND);
             mHandlerThread.start();
+            mHandler = new Handler(mHandlerThread.getLooper());
             mSettingsRegistry = new SettingsRegistry();
         }
-        registerBroadcastReceivers();
-        startWatchingUserRestrictionChanges();
+        mHandler.post(() -> {
+            registerBroadcastReceivers();
+            startWatchingUserRestrictionChanges();
+        });
         ServiceManager.addService("settings", new SettingsService(this));
         return true;
     }
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index acd552d..48b757c 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -16,6 +16,7 @@
     legacy-android-test \
 
 LOCAL_PACKAGE_NAME := ShellTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_INSTRUMENTATION_FOR := Shell
 
 LOCAL_CERTIFICATE := platform
diff --git a/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml b/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
index 2b75c36..696e9b1 100644
--- a/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
+++ b/packages/SystemUI/res/color/qs_user_detail_avatar_tint.xml
@@ -17,6 +17,6 @@
   -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false" android:color="@color/qs_tile_disabled_color" />
+    <item android:state_enabled="false" android:color="?android:attr/textColorPrimary" />
     <item android:color="@android:color/transparent" />
-</selector>
\ No newline at end of file
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_add_circle_qs.xml b/packages/SystemUI/res/drawable/ic_add_circle_qs.xml
index f296076..6415ecb4 100644
--- a/packages/SystemUI/res/drawable/ic_add_circle_qs.xml
+++ b/packages/SystemUI/res/drawable/ic_add_circle_qs.xml
@@ -17,14 +17,15 @@
         android:width="48.0dp"
         android:height="48.0dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
     <group
             android:scaleX="1.2"
             android:scaleY="1.2"
             android:pivotX="12.0"
             android:pivotY="12.0">
         <path
-            android:fillColor="@color/qs_user_detail_icon_muted"
+            android:fillColor="#FFFFFFFF"
             android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM17.000000,13.000000l-4.000000,0.000000l0.000000,4.000000l-2.000000,0.000000l0.000000,-4.000000L7.000000,13.000000l0.000000,-2.000000l4.000000,0.000000L11.000000,7.000000l2.000000,0.000000l0.000000,4.000000l4.000000,0.000000L17.000000,13.000000z"/>
     </group>
 </vector>
diff --git a/packages/SystemUI/res/layout/pip_menu_action.xml b/packages/SystemUI/res/layout/pip_menu_action.xml
index 77efc9b..9150a00 100644
--- a/packages/SystemUI/res/layout/pip_menu_action.xml
+++ b/packages/SystemUI/res/layout/pip_menu_action.xml
@@ -18,4 +18,5 @@
     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
+    android:background="?android:selectableItemBackgroundBorderless"
+    android:forceHasOverlappingRendering="false" />
\ 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 c6837fa..44ced17 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -23,7 +23,8 @@
   <FrameLayout
       android:id="@+id/menu_container"
       android:layout_width="match_parent"
-      android:layout_height="match_parent">
+      android:layout_height="match_parent"
+      android:forceHasOverlappingRendering="false">
 
       <ImageView
           android:id="@+id/dismiss"
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 8d1f9e4..9d1fb8f 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -14,24 +14,39 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="48dp"
+    android:paddingTop="8dp">
+    <LinearLayout
+        android:id="@+id/label_group"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:gravity="center_horizontal"
-        android:paddingTop="8dp"
-        android:paddingBottom="8dp">
-     <TextView android:id="@+id/tile_label"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/tile_label"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textColor="?android:attr/textColorPrimary"
-            android:gravity="center_horizontal"
-            android:minLines="2"
+            android:clickable="false"
+            android:maxLines="2"
             android:padding="0dp"
             android:textAppearance="@style/TextAppearance.QS.TileLabel"
-            android:clickable="false" />
-     <ImageView android:id="@+id/restricted_padlock"
+            android:textColor="?android:attr/textColorPrimary"/>
+
+        <ImageView
+            android:id="@+id/expand_indicator"
+            android:layout_marginStart="4dp"
+            android:layout_width="12dp"
+            android:layout_height="match_parent"
+            android:src="@drawable/qs_dual_tile_caret"
+            android:tint="?android:attr/textColorPrimary" />
+
+        <ImageView android:id="@+id/restricted_padlock"
             android:layout_width="@dimen/qs_tile_text_size"
             android:layout_height="match_parent"
             android:paddingBottom="@dimen/qs_tile_text_size"
@@ -39,4 +54,32 @@
             android:layout_marginLeft="@dimen/restricted_padlock_pading"
             android:scaleType="centerInside"
             android:visibility="gone" />
-</LinearLayout>
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/app_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignStart="@id/label_group"
+        android:layout_alignEnd="@id/label_group"
+        android:layout_below="@id/label_group"
+        android:clickable="false"
+        android:maxLines="1"
+        android:padding="0dp"
+        android:visibility="gone"
+        android:gravity="center"
+        android:textAppearance="@style/TextAppearance.QS.TileLabel"
+        android:textColor="?android:attr/textColorPrimary"/>
+
+    <View
+        android:id="@+id/underline"
+        android:layout_width="30dp"
+        android:layout_height="1dp"
+        android:layout_marginTop="2dp"
+        android:layout_alignStart="@id/label_group"
+        android:layout_alignEnd="@id/label_group"
+        android:layout_below="@id/label_group"
+        android:alpha="?android:attr/disabledAlpha"
+        android:background="?android:attr/colorForeground"/>
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index 8c6c7cf..c7bfaef 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -53,7 +53,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:textSize="@dimen/qs_detail_item_secondary_text_size"
-                android:textColor="@color/qs_user_detail_name"
+                android:textColor="?android:attr/textColorSecondary"
                 android:gravity="center_horizontal" />
         <ImageView
                 android:id="@+id/restricted_padlock"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index cbe822f..a549c73 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1160,7 +1160,8 @@
 
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
-                mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate);
+                mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
+                        && mDeviceInteractive);
                 adjustStatusBarLocked();
             }
         }
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 2f9c3fc..9cb518c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -19,8 +19,8 @@
 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 static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -33,13 +33,11 @@
 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.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -84,6 +82,8 @@
     private static final float MENU_BACKGROUND_ALPHA = 0.3f;
     private static final float DISMISS_BACKGROUND_ALPHA = 0.8f;
 
+    private static final float DISABLED_ACTION_ALPHA = 0.54f;
+
     private boolean mMenuVisible;
     private final List<RemoteAction> mActions = new ArrayList<>();
     private View mViewRoot;
@@ -249,6 +249,7 @@
 
     private void showMenu(Rect stackBounds, Rect movementBounds) {
         if (!mMenuVisible) {
+            setVisible(true);
             updateActionViews(stackBounds);
             if (mMenuContainerAnimator != null) {
                 mMenuContainerAnimator.cancel();
@@ -268,7 +269,10 @@
             mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
             mMenuContainerAnimator.start();
         } else {
+            // If we are already visible, then just start the delayed dismiss and unregister any
+            // existing input consumers from the previous drag
             repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+            notifyUnregisterInputConsumer();
         }
     }
 
@@ -292,9 +296,7 @@
                     if (animationFinishedRunnable != null) {
                         animationFinishedRunnable.run();
                     }
-                    if (getSystemService(AccessibilityManager.class).isEnabled()) {
-                        finish();
-                    }
+                    setVisible(false);
                 }
             });
             mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
@@ -369,13 +371,18 @@
                         actionView.setImageDrawable(d);
                     }, mHandler);
                     actionView.setContentDescription(action.getContentDescription());
-                    actionView.setOnClickListener(v -> {
-                        try {
-                            action.getActionIntent().send();
-                        } catch (CanceledException e) {
-                            Log.w(TAG, "Failed to send action", e);
-                        }
-                    });
+                    if (action.isEnabled()) {
+                        actionView.setOnClickListener(v -> {
+                            try {
+                                action.getActionIntent().send();
+                            } catch (CanceledException e) {
+                                Log.w(TAG, "Failed to send action", e);
+                            }
+                        });
+                    } else {
+                        actionView.setAlpha(DISABLED_ACTION_ALPHA);
+                        actionView.setEnabled(false);
+                    }
                     if (isLandscapePip && i > 0) {
                         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
                                 actionView.getLayoutParams();
@@ -398,6 +405,7 @@
     }
 
     private void updateDismissFraction(float fraction) {
+        setVisible(true);
         int alpha;
         if (mMenuVisible) {
             mMenuContainer.setAlpha(1-fraction);
@@ -416,6 +424,12 @@
         sendMessage(m, "Could not notify controller to register input consumer");
     }
 
+    private void notifyUnregisterInputConsumer() {
+        Message m = Message.obtain();
+        m.what = PipMenuActivityController.MESSAGE_UNREGISTER_INPUT_CONSUMER;
+        sendMessage(m, "Could not notify controller to unregister input consumer");
+    }
+
     private void notifyMenuVisibility(boolean visible) {
         mMenuVisible = visible;
         Message m = Message.obtain();
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 7dc455b..724f453 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -63,6 +63,7 @@
     public static final int MESSAGE_DISMISS_PIP = 103;
     public static final int MESSAGE_UPDATE_ACTIVITY_CALLBACK = 104;
     public static final int MESSAGE_REGISTER_INPUT_CONSUMER = 105;
+    public static final int MESSAGE_UNREGISTER_INPUT_CONSUMER = 106;
 
     /**
      * A listener interface to receive notification on changes in PIP.
@@ -135,6 +136,10 @@
                     mInputConsumerController.registerInputConsumer();
                     break;
                 }
+                case MESSAGE_UNREGISTER_INPUT_CONSUMER: {
+                    mInputConsumerController.unregisterInputConsumer();
+                    break;
+                }
                 case MESSAGE_UPDATE_ACTIVITY_CALLBACK: {
                     mToActivityMessenger = msg.replyTo;
                     mStartActivityRequested = false;
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 c52fc3e..f70d5b4 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -504,8 +504,8 @@
                 return false;
             }
 
-            try {
-                if (ENABLE_DISMISS_DRAG_TO_TARGET) {
+            if (ENABLE_DISMISS_DRAG_TO_TARGET) {
+                try {
                     mHandler.removeCallbacks(mShowDismissAffordance);
                     PointF vel = mTouchState.getVelocity();
                     final float velocity = PointF.length(vel.x, vel.y);
@@ -520,9 +520,9 @@
                             return true;
                         }
                     }
+                } finally {
+                    mDismissViewController.destroyDismissTarget();
                 }
-            } finally {
-                mDismissViewController.destroyDismissTarget();
             }
 
             if (touchState.isDragging()) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
index 0629d66..b080642 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
@@ -35,19 +35,13 @@
     protected void createLabel() {
         super.createLabel();
         mLabelMinLines = mLabel.getMinLines();
-        View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
-        mAppLabel = (TextView) view.findViewById(R.id.tile_label);
+        mAppLabel = findViewById(R.id.app_label);
         mAppLabel.setAlpha(.6f);
-        mAppLabel.setSingleLine(true);
-        addView(view);
     }
 
     public void setShowAppLabel(boolean showAppLabel) {
         mAppLabel.setVisibility(showAppLabel ? View.VISIBLE : View.GONE);
         mLabel.setSingleLine(showAppLabel);
-        if (!showAppLabel) {
-            mLabel.setMinLines(mLabelMinLines);
-        }
     }
 
     public void setAppLabel(CharSequence label) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index c0fb4d5..d8e5542 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -41,10 +41,10 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.qs.QSDetailClipper;
 import com.android.systemui.plugins.qs.QSTile;
-import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
+import com.android.systemui.qs.QSDetailClipper;
 import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitor.Callback;
 
@@ -74,6 +74,7 @@
     private boolean mFinishedFetchingTiles = false;
     private int mX;
     private int mY;
+    private boolean mOpening;
 
     public QSCustomizer(Context context, AttributeSet attrs) {
         super(new ContextThemeWrapper(context, R.style.edit_theme), attrs);
@@ -140,6 +141,7 @@
             mY = y;
             MetricsLogger.visible(getContext(), MetricsProto.MetricsEvent.QS_EDIT);
             isShown = true;
+            mOpening = true;
             setTileSpecs();
             setVisibility(View.VISIBLE);
             mClipper.animateCircularClip(x, y, true, mExpandAnimationListener);
@@ -226,7 +228,8 @@
     }
 
     private final Callback mKeyguardCallback = () -> {
-        if (Dependency.get(KeyguardMonitor.class).isShowing()) {
+        if (!isAttachedToWindow()) return;
+        if (Dependency.get(KeyguardMonitor.class).isShowing() && !mOpening) {
             hide(0, 0);
         }
     };
@@ -237,11 +240,13 @@
             if (isShown) {
                 setCustomizing(true);
             }
+            mOpening = false;
             mNotifQsContainer.setCustomizerAnimating(false);
         }
 
         @Override
         public void onAnimationCancel(Animator animation) {
+            mOpening = false;
             mNotifQsContainer.setCustomizerAnimating(false);
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 547bef7..2ac592f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -165,6 +165,7 @@
         }
         TileInfo info = new TileInfo();
         info.state = state;
+        info.state.dualTarget = false; // No dual targets in edit.
         info.state.expandedAccessibilityClassName =
                 Button.class.getName();
         info.spec = spec;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 5ac7891..948954c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -369,7 +369,6 @@
                         Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
                                 intent, 0);
                     } else {
-                        mAnnounceNextStateChange = true;
                         handleClick();
                     }
                 } else if (msg.what == SECONDARY_CLICK) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index 2c04e82..d2ae6e9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -36,11 +36,12 @@
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
 
-    private final View mDivider;
+    private View mDivider;
     protected TextView mLabel;
     private ImageView mPadLock;
     private int mState;
     private ViewGroup mLabelContainer;
+    private View mExpandIndicator;
 
     public QSTileView(Context context, QSIconView icon) {
         this(context, icon, false);
@@ -54,8 +55,6 @@
 
         setClickable(true);
         setId(View.generateViewId());
-        mDivider = LayoutInflater.from(context).inflate(R.layout.divider, this, false);
-        addView(mDivider);
         createLabel();
         setOrientation(VERTICAL);
         setGravity(Gravity.CENTER);
@@ -81,8 +80,10 @@
                 .inflate(R.layout.qs_tile_label, this, false);
         mLabelContainer.setClipChildren(false);
         mLabelContainer.setClipToPadding(false);
-        mLabel = (TextView) mLabelContainer.findViewById(R.id.tile_label);
-        mPadLock = (ImageView) mLabelContainer.findViewById(R.id.restricted_padlock);
+        mLabel = mLabelContainer.findViewById(R.id.tile_label);
+        mPadLock = mLabelContainer.findViewById(R.id.restricted_padlock);
+        mDivider = mLabelContainer.findViewById(R.id.underline);
+        mExpandIndicator = mLabelContainer.findViewById(R.id.expand_indicator);
 
         addView(mLabelContainer);
     }
@@ -101,6 +102,7 @@
             mLabel.setText(state.label);
         }
         mDivider.setVisibility(state.dualTarget ? View.VISIBLE : View.INVISIBLE);
+        mExpandIndicator.setVisibility(state.dualTarget ? View.VISIBLE : View.GONE);
         if (state.dualTarget != mLabelContainer.isClickable()) {
             mLabelContainer.setClickable(state.dualTarget);
             mLabelContainer.setLongClickable(state.dualTarget);
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 47468ae..ac24e2e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -67,6 +67,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.ArraySet;
+import android.util.LauncherIcons;
 import android.util.Log;
 import android.util.MutableBoolean;
 import android.view.Display;
@@ -142,6 +143,7 @@
     int mDummyThumbnailHeight;
     Paint mBgProtectionPaint;
     Canvas mBgProtectionCanvas;
+    LauncherIcons mLauncherIcons;
 
     private final Handler mHandler = new H();
 
@@ -299,6 +301,7 @@
             Collections.addAll(sRecentsBlacklist,
                     res.getStringArray(R.array.recents_blacklist_array));
         }
+        mLauncherIcons = new LauncherIcons(context);
     }
 
     /**
@@ -834,7 +837,7 @@
             return new ColorDrawable(0xFF666666);
         }
 
-        Drawable icon = info.loadIcon(mPm);
+        Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(info.loadIcon(mPm));
         return getBadgedIcon(icon, userId);
     }
 
@@ -850,7 +853,7 @@
             return new ColorDrawable(0xFF666666);
         }
 
-        Drawable icon = appInfo.loadIcon(mPm);
+        Drawable icon = mLauncherIcons.wrapIconDrawableWithShadow(appInfo.loadIcon(mPm));
         return getBadgedIcon(icon, userId);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 820638c..c30bb9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -74,7 +74,7 @@
         if (mUserListener == null) {
             return false;
         }
-        return mUserListener.getUserCount() > 1;
+        return mUserListener.getUserCount() != 0;
     }
 
     public void setUserSwitcherController(UserSwitcherController userSwitcherController) {
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 576299f..ddd8d7b 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -26,6 +26,7 @@
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
 
 LOCAL_PACKAGE_NAME := SystemUITests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     $(call all-Iaidl-files-under, src) \
@@ -46,7 +47,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     metrics-helper-lib \
     android-support-test \
-    mockito-updated-target-minus-junit4 \
+    mockito-target-minus-junit4 \
     SystemUI-proto \
     SystemUI-tags \
     legacy-android-test \
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 3800f29..8a3b9af 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -56,6 +56,12 @@
     // Type for APP_TRANSITION event: The transition brought an already existing activity to the
     // front.
     TYPE_TRANSITION_HOT_LAUNCH = 9;
+
+    // The action was successful
+    TYPE_SUCCESS = 10;
+
+    // The action failed
+    TYPE_FAILURE = 11;
   }
 
   // Known visual elements: views or controls.
@@ -1180,7 +1186,7 @@
     // OS: 6.0
     BRIGHTNESS_DIALOG = 220;
 
-    // OPEN: Settings > Apps > Configure Apps > Draw over other apps
+    // OPEN: Settings > Apps > Configure Apps > Display over other apps
     // CATEGORY: SETTINGS
     // OS: 6.0
     SYSTEM_ALERT_WINDOW_APPS = 221;
@@ -3227,7 +3233,7 @@
     // ACTION: Allow "Draw over other apps" for an app
     APP_SPECIAL_PERMISSION_APPDRAW_ALLOW = 770;
 
-    // ACTION: Deny "Draw over other apps" for an app
+    // ACTION: Deny "Display over other apps" for an app
     APP_SPECIAL_PERMISSION_APPDRAW_DENY = 771;
 
     // ACTION: Allow "VR helper services" for an app
@@ -3608,6 +3614,169 @@
     // CATEGORY: SETTINGS
     SETTINGS_LOCK_SCREEN_PREFERENCES = 882;
 
+    // ACTION: An app requested the app-op permission ACCESS_NOTIFICATIONS
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_REQUEST_ACCESS_NOTIFICATIONS = 883;
+
+    // ACTION: An app was granted the app-op permission ACCESS_NOTIFICATIONS
+    // PACKAGE: The package name of the app that was granted the permission
+    ACTION_APPOP_GRANT_ACCESS_NOTIFICATIONS = 884;
+
+    // ACTION: An app requested the app-op permission ACCESS_NOTIFICATIONS and the request was denied
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_DENIED_ACCESS_NOTIFICATIONS = 885;
+
+    // ACTION: The app-op permission ACCESS_NOTIFICATIONS was revoked for an app
+    // PACKAGE: The package name of the app the permission was revoked for
+    ACTION_APPOP_REVOKE_ACCESS_NOTIFICATIONS = 886;
+
+    // ACTION: An app requested the app-op permission SYSTEM_ALERT_WINDOW
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_REQUEST_SYSTEM_ALERT_WINDOW = 887;
+
+    // ACTION: An app was granted the app-op permission SYSTEM_ALERT_WINDOW
+    // PACKAGE: The package name of the app that was granted the permission
+    ACTION_APPOP_GRANT_SYSTEM_ALERT_WINDOW = 888;
+
+    // ACTION: An app requested the app-op permission SYSTEM_ALERT_WINDOW and the request was denied
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_DENIED_SYSTEM_ALERT_WINDOW = 889;
+
+    // ACTION: The app-op permission SYSTEM_ALERT_WINDOW was revoked for an app
+    // PACKAGE: The package name of the app the permission was revoked for
+    ACTION_APPOP_REVOKE_SYSTEM_ALERT_WINDOW = 890;
+
+    // ACTION: An app requested the app-op permission REQUEST_WRITE_SETTINGS
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_REQUEST_WRITE_SETTINGS = 891;
+
+    // ACTION: An app was granted the app-op permission REQUEST_WRITE_SETTINGS
+    // PACKAGE: The package name of the app that was granted the permission
+    ACTION_APPOP_GRANT_WRITE_SETTINGS = 892;
+
+    // ACTION: An app requested the app-op permission REQUEST_WRITE_SETTINGS and the request was denied
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_DENIED_WRITE_SETTINGS = 893;
+
+    // ACTION: The app-op permission REQUEST_WRITE_SETTINGS was revoked for an app
+    // PACKAGE: The package name of the app the permission was revoked for
+    ACTION_APPOP_REVOKE_WRITE_SETTINGS = 894;
+
+    // ACTION: An app requested the app-op permission REQUEST_INSTALL_PACKAGES
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_REQUEST_REQUEST_INSTALL_PACKAGES = 895;
+
+    // ACTION: An app was granted the app-op permission REQUEST_INSTALL_PACKAGES
+    // PACKAGE: The package name of the app that was granted the permission
+    ACTION_APPOP_GRANT_REQUEST_INSTALL_PACKAGES = 896;
+
+    // ACTION: An app requested the app-op permission REQUEST_INSTALL_PACKAGES and the request was denied
+    // PACKAGE: The package name of the app requesting the permission
+    ACTION_APPOP_DENIED_REQUEST_INSTALL_PACKAGES = 897;
+
+    // ACTION: The app-op permission REQUEST_INSTALL_PACKAGES was revoked for an app
+    // PACKAGE: The package name of the app the permission was revoked for
+    ACTION_APPOP_REVOKE_REQUEST_INSTALL_PACKAGES = 898;
+
+    // ACTION: Phase 1 of instant application resolution occurred
+    // OS: O
+    ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE = 899;
+
+    // ACTION: Phase 2 of instant application resolution occurred
+    // OS: O
+    ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO = 900;
+
+    // FIELD: The amount of time for an ephemeral resolution phase; in milliseconds
+    // OS: O
+    FIELD_INSTANT_APP_RESOLUTION_DELAY_MS = 901;
+
+    // FIELD: The status of an ephemeral resolution phase
+    // Value 0: success
+    // Value 1: no full hash match
+    // OS: O
+    FIELD_INSTANT_APP_RESOLUTION_STATUS = 902;
+
+    // FIELD - A token to identify all events that are part of the same instant application launch
+    // OS: O
+    FIELD_INSTANT_APP_LAUNCH_TOKEN = 903;
+
+    // FIELD - The name of the package responsible for launching the activity
+    // OS: O
+    APP_TRANSITION_CALLING_PACKAGE_NAME = 904;
+
+    // FIELD - Whether or not the launched activity is part of an instant application
+    // OS: O
+    APP_TRANSITION_IS_EPHEMERAL = 905;
+
+    // An autofill session was started
+    // Package: Package of app that is autofilled
+    AUTOFILL_SESSION_STARTED = 906;
+
+    // An autofill request was processed by a service
+    // Type TYPE_SUCCESS: The request succeeded
+    // Type TYPE_FAILURE: The request failed
+    // Package: Package of app that is autofilled
+    // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // Tag FIELD_AUTOFILL_NUM_DATASET: The number of datasets returned (only in success case)
+    AUTOFILL_REQUEST = 907;
+
+    // Tag of a field for a package of an autofill service
+    FIELD_AUTOFILL_SERVICE = 908;
+
+    // Tag of a field for the number of datasets
+    FIELD_AUTOFILL_NUM_DATASETS = 909;
+
+    // An autofill dataset selection UI was shown
+    // Type TYPE_DISMISS: UI was explicityly canceled by the user
+    // Type TYPE_CLOSE: UI was destroyed without influence of the user
+    // Type TYPE_ACTION: dataset was selected
+    // Type TYPE_DETAIL: authentication was selected
+    // Package: Package of app that was autofilled
+    // Tag FIELD_AUTOFILL_FILTERTEXT_LEN: The length of the filter text
+    // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets shown
+    AUTOFILL_FILL_UI = 910;
+
+    // Tag of a field for the length of the filter text
+    FIELD_AUTOFILL_FILTERTEXT_LEN = 911;
+
+    // An autofill authentification succeeded
+    // Package: Package of app that was autofilled
+    AUTOFILL_AUTHENTICATED = 912;
+
+    // An activity was autofilled and all values could be applied
+    // Package: Package of app that is autofilled
+    // Tag FIELD_AUTOFILL_NUM_VALUES: Number of values that were suggested to be autofilled
+    // Tag FIELD_AUTOFILL_NUM_VIEWS_FILLED: Number of views that could be filled
+    AUTOFILL_DATASET_APPLIED = 913;
+
+    // Tag of a field for the number values to be filled in
+    FIELD_AUTOFILL_NUM_VALUES = 914;
+
+    // Tag of a field for the number of views that were filled
+    FIELD_AUTOFILL_NUM_VIEWS_FILLED = 915;
+
+    // An autofill save UI was shown
+    // Type TYPE_DISMISS: UI was explicityly canceled by the user
+    // Type TYPE_CLOSE: UI was destroyed without influence of the user
+    // Type TYPE_ACTION: data was saved
+    // Package: Package of app that was autofilled
+    // Tag FIELD_AUTOFILL_NUM_ID: The number of ids that are saved
+    AUTOFILL_SAVE_UI = 916;
+
+    // Tag of a field for the number of saveable ids
+    FIELD_AUTOFILL_NUM_IDS = 917;
+
+    // ACTION: An autofill service was reqiested to save data
+    // Type TYPE_SUCCESS: The request succeeded
+    // Type TYPE_FAILURE: The request failed
+    // Package: Package of app that was autofilled
+    // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    AUTOFILL_DATA_SAVE_REQUEST = 918;
+
+    // An auto-fill session was finished
+    // Package: Package of app that was autofilled
+    AUTOFILL_SESSION_FINISHED = 919;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index af1193d..c7ba1ff 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -28,6 +28,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.graphics.Rect;
@@ -53,6 +54,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -316,13 +318,27 @@
         @Override
         public void startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
                 AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
-                boolean hasCallback, int flags) {
+                boolean hasCallback, int flags, String packageName) {
             // TODO(b/33197203): make sure it's called by resumed / focused activity
 
+            activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
+            appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
+            autofillId = Preconditions.checkNotNull(autofillId, "autoFillId");
+            bounds = Preconditions.checkNotNull(bounds, "bounds");
+            packageName = Preconditions.checkNotNull(packageName, "packageName");
+
+            Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId");
+
+            try {
+                mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, userId);
+            } catch (PackageManager.NameNotFoundException e) {
+                throw new IllegalArgumentException(packageName + " is not a valid package", e);
+            }
+
             synchronized (mLock) {
                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, windowToken, appCallback,
-                        autofillId, bounds, value, hasCallback, flags);
+                        autofillId, bounds, value, hasCallback, flags, packageName);
             }
         }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3e5ad82..df76009 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -28,6 +28,7 @@
 import static com.android.server.autofill.Helper.VERBOSE;
 import static com.android.server.autofill.Helper.findValue;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -43,6 +44,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.Rect;
+import android.metrics.LogMaker;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -67,7 +69,11 @@
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
+import android.view.autofill.AutofillManager.AutofillCallback;
+
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.IResultReceiver;
 import com.android.server.autofill.ui.AutoFillUI;
@@ -92,6 +98,7 @@
     private final Context mContext;
     private final Object mLock;
     private final AutoFillUI mUi;
+    private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     private RemoteCallbackList<IAutoFillManagerClient> mClients;
     private AutofillServiceInfo mInfo;
@@ -228,9 +235,8 @@
                 if (!hasService()) {
                     final int sessionCount = mSessions.size();
                     for (int i = sessionCount - 1; i >= 0; i--) {
-                        Session session = mSessions.valueAt(i);
-                        session.destroyLocked();
-                        mSessions.removeAt(i);
+                        final Session session = mSessions.valueAt(i);
+                        session.removeSelfLocked();
                     }
                 }
                 sendStateToClients();
@@ -284,9 +290,10 @@
         }
     }
 
-    void startSessionLocked(IBinder activityToken, IBinder windowToken, IBinder appCallbackToken,
-            AutofillId autofillId,  Rect bounds, AutofillValue value, boolean hasCallback,
-            int flags) {
+    void startSessionLocked(@NonNull IBinder activityToken, @Nullable IBinder windowToken,
+            @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId, @NonNull Rect bounds,
+            @Nullable AutofillValue value, boolean hasCallback, int flags,
+            @NonNull String packageName) {
         if (!hasService()) {
             return;
         }
@@ -305,7 +312,7 @@
         }
 
         final Session newSession = createSessionByTokenLocked(activityToken,
-                windowToken, appCallbackToken, hasCallback, flags);
+                windowToken, appCallbackToken, hasCallback, flags, packageName);
         newSession.updateLocked(autofillId, bounds, value, FLAG_START_SESSION);
     }
 
@@ -320,7 +327,13 @@
             return;
         }
 
-        session.showSaveLocked();
+        final boolean finished = session.showSaveLocked();
+        if (DEBUG) {
+            Log.d(TAG, "finishSessionLocked(): session finished on save? " + finished);
+        }
+        if (finished) {
+            session.removeSelf();
+        }
     }
 
     void cancelSessionLocked(IBinder activityToken) {
@@ -333,14 +346,14 @@
             Slog.w(TAG, "cancelSessionLocked(): no session for " + activityToken);
             return;
         }
-
-        session.destroyLocked();
+        session.removeSelfLocked();
     }
 
-    private Session createSessionByTokenLocked(IBinder activityToken, IBinder windowToken,
-            IBinder appCallbackToken, boolean hasCallback, int flags) {
+    private Session createSessionByTokenLocked(@NonNull IBinder activityToken,
+            @Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
+            int flags, @NonNull String packageName) {
         final Session newSession = new Session(mContext, activityToken,
-                windowToken, appCallbackToken, hasCallback, flags);
+                windowToken, appCallbackToken, hasCallback, flags, packageName);
         mSessions.put(activityToken, newSession);
 
         /*
@@ -351,7 +364,6 @@
          * - display disclosure if needed
          */
         try {
-            // TODO(b/33197203): add MetricsLogger call
             final Bundle receiverExtras = new Bundle();
             receiverExtras.putBinder(EXTRA_ACTIVITY_TOKEN, activityToken);
             final long identity = Binder.clearCallingIdentity();
@@ -371,7 +383,6 @@
 
     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) {
             if (VERBOSE) {
@@ -595,6 +606,9 @@
         private final IBinder mActivityToken;
         private final IBinder mWindowToken;
 
+        /** Package name of the app that is auto-filled */
+        @NonNull private final String mPackageName;
+
         @GuardedBy("mLock")
         private final Map<AutofillId, ViewState> mViewStates = new ArrayMap<>();
 
@@ -634,15 +648,16 @@
          * Flags used to start the session.
          */
         private int mFlags;
-
-        private Session(Context context, IBinder activityToken, IBinder windowToken,
-                IBinder client, boolean hasCallback, int flags) {
+        private Session(@NonNull Context context, @NonNull IBinder activityToken,
+                @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
+                int flags, @NonNull String packageName) {
             mRemoteFillService = new RemoteFillService(context,
                     mInfo.getServiceInfo().getComponentName(), mUserId, this);
             mActivityToken = activityToken;
             mWindowToken = windowToken;
             mHasCallback = hasCallback;
             mFlags = flags;
+            mPackageName = packageName;
 
             mClient = IAutoFillManagerClient.Stub.asInterface(client);
             try {
@@ -656,41 +671,82 @@
             } catch (RemoteException e) {
                 Slog.w(TAG, "linkToDeath() on mClient failed: " + e);
             }
+
+            mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
         }
 
         // FillServiceCallbacks
         @Override
-        public void onFillRequestSuccess(FillResponse response) {
-            // TODO(b/33197203): add MetricsLogger call
+        public void onFillRequestSuccess(@Nullable FillResponse response,
+                @NonNull String servicePackageName) {
             if (response == null) {
+                // Nothing to be done, but need to notify client.
+                notifyUnavailableToClient();
                 removeSelf();
                 return;
             }
+
+            if ((response.getDatasets() == null || response.getDatasets().isEmpty())
+                            && response.getAuthentication() == null) {
+                // Response is "empty" from an UI point of view, need to notify client.
+                notifyUnavailableToClient();
+            }
             synchronized (mLock) {
                 processResponseLocked(response);
             }
+
+            LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST))
+                    .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS)
+                    .setPackageName(mPackageName)
+                    .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
+                            response.getDatasets() == null ? 0 : response.getDatasets().size())
+                    .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
+                            servicePackageName);
+            mMetricsLogger.write(log);
         }
 
         // FillServiceCallbacks
         @Override
-        public void onFillRequestFailure(CharSequence message) {
-            // TODO(b/33197203): add MetricsLogger call
+        public void onFillRequestFailure(@Nullable CharSequence message,
+                @NonNull String servicePackageName) {
+            LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_REQUEST))
+                    .setType(MetricsProto.MetricsEvent.TYPE_FAILURE)
+                    .setPackageName(mPackageName)
+                    .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
+                            servicePackageName);
+            mMetricsLogger.write(log);
+
             getUiForShowing().showError(message);
             removeSelf();
         }
 
         // FillServiceCallbacks
         @Override
-        public void onSaveRequestSuccess() {
-            // TODO(b/33197203): add MetricsLogger call
+        public void onSaveRequestSuccess(@NonNull String servicePackageName) {
+            LogMaker log = (new LogMaker(
+                    MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
+                    .setType(MetricsProto.MetricsEvent.TYPE_SUCCESS)
+                    .setPackageName(mPackageName)
+                    .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
+                            servicePackageName);
+            mMetricsLogger.write(log);
+
             // Nothing left to do...
             removeSelf();
         }
 
         // FillServiceCallbacks
         @Override
-        public void onSaveRequestFailure(CharSequence message) {
-            // TODO(b/33197203): add MetricsLogger call
+        public void onSaveRequestFailure(@Nullable CharSequence message,
+                @NonNull String servicePackageName) {
+            LogMaker log = (new LogMaker(
+                    MetricsProto.MetricsEvent.AUTOFILL_DATA_SAVE_REQUEST))
+                    .setType(MetricsProto.MetricsEvent.TYPE_FAILURE)
+                    .setPackageName(mPackageName)
+                    .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_SERVICE,
+                            servicePackageName);
+            mMetricsLogger.write(log);
+
             getUiForShowing().showError(message);
             removeSelf();
         }
@@ -702,9 +758,7 @@
             synchronized (mLock) {
                 fillInIntent = createAuthFillInIntent(mStructure);
             }
-            mHandlerCaller.getHandler().post(() -> {
-                startAuthentication(intent, fillInIntent);
-            });
+            mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
         }
 
         // FillServiceCallbacks
@@ -724,8 +778,7 @@
                 Binder.restoreCallingIdentity(identity);
             }
             synchronized (mLock) {
-                destroyLocked();
-                mSessions.remove(this);
+                removeSelfLocked();
             }
         }
 
@@ -738,9 +791,7 @@
         // AutoFillUiCallback
         @Override
         public void fill(Dataset dataset) {
-            mHandlerCaller.getHandler().post(() -> {
-                autoFill(dataset);
-            });
+            mHandlerCaller.getHandler().post(() -> autoFill(dataset));
         }
 
         // AutoFillUiCallback
@@ -753,17 +804,13 @@
         // AutoFillUiCallback
         @Override
         public void cancelSave() {
-            mHandlerCaller.getHandler().post(() -> {
-                removeSelf();
-            });
+            mHandlerCaller.getHandler().post(() -> removeSelf());
         }
 
         // AutoFillUiCallback
         @Override
         public void onEvent(AutofillId id, int event) {
-            mHandlerCaller.getHandler().post(() -> {
-                notifyChangeToClient(id, event);
-            });
+            mHandlerCaller.getHandler().post(() -> notifyChangeToClient(id, event));
         }
 
         public void setAuthenticationResultLocked(Bundle data) {
@@ -773,6 +820,9 @@
                 Parcelable result = data.getParcelable(
                         AutofillManager.EXTRA_AUTHENTICATION_RESULT);
                 if (result instanceof FillResponse) {
+                    mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_AUTHENTICATED,
+                            mPackageName);
+
                     mCurrentResponse = (FillResponse) result;
                     processResponseLocked(mCurrentResponse);
                 } else if (result instanceof Dataset) {
@@ -790,12 +840,14 @@
         }
 
         /**
-         * Show the save UI, when session can be saved.
+         * Shows the save UI, when session can be saved.
+         *
+         * @return {@code true} if session is done, or {@code false} if it's pending user action.
          */
-        public void showSaveLocked() {
+        public boolean showSaveLocked() {
             if (mStructure == null) {
                 Slog.wtf(TAG, "showSaveLocked(): no mStructure");
-                return;
+                return true;
             }
             if (mCurrentResponse == null) {
                 // Happens when the activity / session was finished before the service replied, or
@@ -803,7 +855,7 @@
                 if (DEBUG) {
                     Slog.d(TAG, "showSaveLocked(): no mCurrentResponse");
                 }
-                return;
+                return true;
             }
             final SaveInfo saveInfo = mCurrentResponse.getSaveInfo();
             if (DEBUG) {
@@ -819,13 +871,13 @@
              */
 
             if (saveInfo == null) {
-                return;
+                return true;
             }
 
             final AutofillId[] requiredIds = saveInfo.getRequiredIds();
             if (requiredIds == null || requiredIds.length == 0) {
                 Slog.w(TAG, "showSaveLocked(): no required ids on saveInfo");
-                return;
+                return true;
             }
 
             boolean allRequiredAreNotEmpty = true;
@@ -894,8 +946,8 @@
                 if (atLeastOneChanged) {
                     getUiForShowing().showSaveUi(
                             mInfo.getServiceInfo().loadLabel(mContext.getPackageManager()),
-                            saveInfo);
-                    return;
+                            saveInfo, mPackageName);
+                    return false;
                 }
             }
             // Nothing changed...
@@ -904,7 +956,7 @@
                         + "allRequiredAreNotNull=" + allRequiredAreNotEmpty
                         + ", atLeastOneChanged=" + atLeastOneChanged);
             }
-            removeSelf();
+            return true;
         }
 
         /**
@@ -946,7 +998,7 @@
                 mStructure.dump();
             }
 
-            mRemoteFillService.onSaveRequest(mStructure, extras);
+            mRemoteFillService.onSaveRequest(mStructure, extras, () -> removeSelf());
         }
 
         void updateLocked(AutofillId id, Rect bounds, AutofillValue value, int flags) {
@@ -1034,7 +1086,7 @@
                 filterText = value.getTextValue().toString();
             }
 
-            getUiForShowing().showFillUi(filledId, response, bounds, filterText);
+            getUiForShowing().showFillUi(filledId, response, bounds, filterText, mPackageName);
         }
 
         private void notifyChangeToClient(AutofillId id, int event) {
@@ -1046,17 +1098,24 @@
             }
         }
 
+        private void notifyUnavailableToClient() {
+            if (mCurrentViewState == null) {
+                // TODO(b/33197203): temporary sanity check; should never happen
+                Slog.w(TAG, "notifyUnavailable(): mCurrentViewState is null");
+                return;
+            }
+            notifyChangeToClient(mCurrentViewState.mId, AutofillCallback.EVENT_INPUT_UNAVAILABLE);
+        }
+
         private void processResponseLocked(FillResponse response) {
             if (DEBUG) {
                 Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication()
                     + "):" + response);
             }
 
-            // TODO(b/33197203): add MetricsLogger calls
-
             if (mCurrentViewState == null) {
                 // TODO(b/33197203): temporary sanity check; should never happen
-                Slog.w(TAG, "processResponseLocked(): mCurrentResponse is null");
+                Slog.w(TAG, "processResponseLocked(): mCurrentViewState is null");
                 return;
             }
 
@@ -1188,17 +1247,23 @@
         private void destroyLocked() {
             mRemoteFillService.destroy();
             mUi.setCallback(null, null);
+
+            mMetricsLogger.action(MetricsProto.MetricsEvent.AUTOFILL_SESSION_FINISHED,
+                    mPackageName);
         }
 
-        private void removeSelf() {
-            if (VERBOSE) {
-                Slog.v(TAG, "removeSelf()");
-            }
-
+        void removeSelf() {
             synchronized (mLock) {
-                destroyLocked();
-                mSessions.remove(mActivityToken);
+                removeSelfLocked();
             }
         }
+
+        private void removeSelfLocked() {
+            if (VERBOSE) {
+                Slog.v(TAG, "removeSelfLocked()");
+            }
+            destroyLocked();
+            mSessions.remove(mActivityToken);
+        }
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index b1cc89b..d1c8b4f8 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.autofill;
 
+import static com.android.server.autofill.Helper.DEBUG;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.assist.AssistStructure;
@@ -38,8 +40,10 @@
 import android.service.autofill.ISaveCallback;
 import android.text.format.DateUtils;
 import android.util.Slog;
+
 import com.android.internal.os.HandlerCaller;
 import com.android.server.FgThread;
+import com.android.server.autofill.AutofillManagerServiceImpl.Session;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -55,8 +59,6 @@
 final class RemoteFillService implements DeathRecipient {
     private static final String LOG_TAG = "RemoteFillService";
 
-    private static final boolean DEBUG = Helper.DEBUG;
-
     // How long after the last interaction with the service we would unbind
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
@@ -87,10 +89,10 @@
     private PendingRequest mPendingRequest;
 
     public interface FillServiceCallbacks {
-        void onFillRequestSuccess(FillResponse response);
-        void onFillRequestFailure(CharSequence message);
-        void onSaveRequestSuccess();
-        void onSaveRequestFailure(CharSequence message);
+        void onFillRequestSuccess(@Nullable FillResponse response, @NonNull String servicePackageName);
+        void onFillRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName);
+        void onSaveRequestSuccess(@NonNull String servicePackageName);
+        void onSaveRequestFailure(@Nullable CharSequence message, @NonNull String servicePackageName);
         void onServiceDied(RemoteFillService service);
         void onDisableSelf();
     }
@@ -139,9 +141,10 @@
         mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
     }
 
-    public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
+    public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras,
+            @Nullable Runnable finalizer) {
         cancelScheduledUnbind();
-        final PendingSaveRequest request = new PendingSaveRequest(structure, extras, this);
+        final PendingSaveRequest request = new PendingSaveRequest(structure, extras, this, finalizer);
         mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
     }
 
@@ -262,7 +265,7 @@
             FillResponse response) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
-                mCallbacks.onFillRequestSuccess(response);
+                mCallbacks.onFillRequestSuccess(response, mComponentName.getPackageName());
             }
         });
     }
@@ -271,7 +274,7 @@
             CharSequence message) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
-                mCallbacks.onFillRequestFailure(message);
+                mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName());
             }
         });
     }
@@ -279,7 +282,7 @@
     private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
-                mCallbacks.onSaveRequestSuccess();
+                mCallbacks.onSaveRequestSuccess(mComponentName.getPackageName());
             }
         });
     }
@@ -288,7 +291,7 @@
             CharSequence message) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
-                mCallbacks.onSaveRequestFailure(message);
+                mCallbacks.onSaveRequestFailure(message, mComponentName.getPackageName());
             }
         });
     }
@@ -414,8 +417,8 @@
     private static final class PendingFillRequest extends PendingRequest {
         private final Object mLock = new Object();
         private final WeakReference<RemoteFillService> mWeakService;
-        private AssistStructure mStructure;
-        private Bundle mExtras;
+        private final AssistStructure mStructure;
+        private final Bundle mExtras;
         private final IFillCallback mCallback;
         private ICancellationSignal mCancellation;
         private boolean mCancelled;
@@ -473,10 +476,6 @@
                 try {
                     remoteService.mAutoFillService.onFillRequest(mStructure,
                             mExtras, mCallback, mFlags);
-                    synchronized (mLock) {
-                        mStructure = null;
-                        mExtras = null;
-                    }
                 } catch (RemoteException e) {
                     Slog.e(LOG_TAG, "Error calling on fill request", e);
                     cancel();
@@ -506,17 +505,18 @@
     }
 
     private static final class PendingSaveRequest extends PendingRequest {
-        private final Object mLock = new Object();
         private final WeakReference<RemoteFillService> mWeakService;
-        private AssistStructure mStructure;
-        private Bundle mExtras;
+        private final AssistStructure mStructure;
+        private final Bundle mExtras;
         private final ISaveCallback mCallback;
+        private final Runnable mFinalizer;
 
-        public PendingSaveRequest(@NonNull AssistStructure structure,
-                @Nullable Bundle extras, @NonNull RemoteFillService service) {
+        public PendingSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras,
+                @NonNull RemoteFillService service, @Nullable Runnable finalizer) {
             mStructure = structure;
             mExtras = extras;
             mWeakService = new WeakReference<>(service);
+            mFinalizer = finalizer;
             mCallback = new ISaveCallback.Stub() {
                 @Override
                 public void onSuccess() {
@@ -540,19 +540,17 @@
 
         @Override
         public void run() {
-            RemoteFillService service = mWeakService.get();
+            final RemoteFillService service = mWeakService.get();
             if (service != null) {
                 try {
-                    service.mAutoFillService.onSaveRequest(mStructure,
-                            mExtras, mCallback);
-                    synchronized (mLock) {
-                        mStructure = null;
-                        mExtras = null;
-                    }
+                    service.mAutoFillService.onSaveRequest(mStructure, mExtras, mCallback);
                 } catch (RemoteException e) {
                     Slog.e(LOG_TAG, "Error calling on save request", e);
                 }
             }
+            if (mFinalizer != null) {
+              mFinalizer.run();
+            }
         }
 
         @Override
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 c7e59a3..776fa1e 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.IntentSender;
 import android.graphics.Rect;
+import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.IBinder;
 import android.service.autofill.Dataset;
@@ -34,6 +35,8 @@
 import android.view.autofill.AutofillId;
 import android.widget.Toast;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.server.UiThread;
 
 import java.io.PrintWriter;
@@ -60,6 +63,7 @@
     private @Nullable IBinder mWindowToken;
 
     private int mSaveTimeoutMs = (int) (5 * DateUtils.SECOND_IN_MILLIS);
+    private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
         void authenticate(@NonNull IntentSender intent);
@@ -152,9 +156,17 @@
      * @param response the current fill response
      * @param anchorBounds bounds of the focused view
      * @param filterText text of the view to be filled
+     * @param packageName package name of the activity that is filled
      */
     public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
-            @NonNull Rect anchorBounds, @Nullable String filterText) {
+            @NonNull Rect anchorBounds, @Nullable String filterText, @NonNull String packageName) {
+        LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_FILL_UI))
+                .setPackageName(packageName)
+                .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_FILTERTEXT_LEN,
+                        filterText == null ? 0 : filterText.length())
+                .addTaggedData(MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
+                        response.getDatasets() == null ? 0 : response.getDatasets().size());
+
         mHandler.post(() -> {
             if (!hasCallback()) {
                 return;
@@ -164,6 +176,7 @@
                     mWindowToken, anchorBounds, filterText, new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
+                    log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
                     hideFillUiUiThread();
                     if (mCallback != null) {
                         mCallback.authenticate(response.getAuthentication());
@@ -172,17 +185,25 @@
 
                 @Override
                 public void onDatasetPicked(Dataset dataset) {
+                    log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
                     hideFillUiUiThread();
                     if (mCallback != null) {
                         mCallback.fill(dataset);
                     }
-                    // TODO(b/33197203): add MetricsLogger call
                 }
 
                 @Override
                 public void onCanceled() {
+                    log.setType(MetricsProto.MetricsEvent.TYPE_DISMISS);
                     hideFillUiUiThread();
-                    // TODO(b/33197203): add MetricsLogger call
+                }
+
+                @Override
+                public void onDestroy() {
+                    if (log.getType() == MetricsProto.MetricsEvent.TYPE_UNKNOWN) {
+                        log.setType(MetricsProto.MetricsEvent.TYPE_CLOSE);
+                    }
+                    mMetricsLogger.write(log);
                 }
             });
             mCallback.onEvent(focusedId, EVENT_INPUT_SHOWN);
@@ -192,7 +213,16 @@
     /**
      * Shows the UI asking the user to save for autofill.
      */
-    public void showSaveUi(@NonNull CharSequence providerLabel, @NonNull SaveInfo info) {
+    public void showSaveUi(@NonNull CharSequence providerLabel, @NonNull SaveInfo info,
+            @NonNull String packageName) {
+        int numIds = 0;
+        numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
+        numIds += info.getOptionalIds() == null ? 0 : info.getOptionalIds().length;
+
+        LogMaker log = (new LogMaker(MetricsProto.MetricsEvent.AUTOFILL_SAVE_UI))
+                .setPackageName(packageName).addTaggedData(
+                        MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_IDS, numIds);
+
         mHandler.post(() -> {
             if (!hasCallback()) {
                 return;
@@ -202,16 +232,16 @@
                     new SaveUi.OnSaveListener() {
                 @Override
                 public void onSave() {
+                    log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
                     hideSaveUiUiThread();
                     if (mCallback != null) {
                         mCallback.save();
                     }
-                    // TODO(b/33197203): add MetricsLogger call
                 }
 
                 @Override
                 public void onCancel(IntentSender listener) {
-                    // TODO(b/33197203): add MetricsLogger call
+                    log.setType(MetricsProto.MetricsEvent.TYPE_DISMISS);
                     hideSaveUiUiThread();
                     if (listener != null) {
                         try {
@@ -225,6 +255,14 @@
                         mCallback.cancelSave();
                     }
                 }
+
+                @Override
+                public void onDestroy() {
+                    if (log.getType() == MetricsProto.MetricsEvent.TYPE_UNKNOWN) {
+                        log.setType(MetricsProto.MetricsEvent.TYPE_CLOSE);
+                    }
+                    mMetricsLogger.write(log);
+                }
             }, mSaveTimeoutMs);
         });
     }
@@ -247,11 +285,17 @@
     }
 
     public void dump(PrintWriter pw) {
-        pw.println("AufoFill UI");
+        pw.println("Autofill UI");
         final String prefix = "  ";
-        pw.print(prefix); pw.print("showsFillUi: "); pw.println(mFillUi != null);
+        final String prefix2 = "    ";
         pw.print(prefix); pw.print("showsSaveUi: "); pw.println(mSaveUi != null);
         pw.print(prefix); pw.print("save timeout: "); pw.println(mSaveTimeoutMs);
+        if (mFillUi != null) {
+            pw.print(prefix); pw.println("showsFillUi: true");
+            mFillUi.dump(pw, prefix2);
+        } else {
+            pw.print(prefix); pw.println("showsFillUi: false");
+        }
     }
 
     @android.annotation.UiThread
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 a7d9fe9..a8c8752 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -39,6 +39,7 @@
 import com.android.internal.R;
 import libcore.util.Objects;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 final class FillUi {
@@ -50,6 +51,7 @@
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
         void onCanceled();
+        void onDestroy();
     }
 
     private final Rect mAnchorBounds = new Rect();
@@ -63,6 +65,7 @@
     private final @Nullable ArrayAdapter<ViewItem> mAdapter;
 
     private @Nullable String mFilterText;
+    private final String mAccessibilityTitle;
 
     private int mContentWidth;
     private int mContentHeight;
@@ -76,6 +79,8 @@
         mAnchorBounds.set(anchorBounds);
         mCallback = callback;
 
+        mAccessibilityTitle = context.getString(R.string.autofill_picker_accessibility_title);
+
         if (response.getAuthentication() != null) {
             mListView = null;
             mAdapter = null;
@@ -201,6 +206,7 @@
 
     public void destroy() {
         throwIfDestroyed();
+        mCallback.onDestroy();
         mWindow.hide();
         mDestroyed = true;
     }
@@ -319,6 +325,7 @@
 
         public void show(int desiredWidth, int desiredHeight, Rect anchorBounds) {
             final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+
             params.setTitle("FillUi");
             params.token = mActivityToken;
             params.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -327,6 +334,7 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                     | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+            params.accessibilityTitle = mAccessibilityTitle;
 
             mWm.getDefaultDisplay().getRealSize(mTempPoint);
             final int screenWidth = mTempPoint.x;
@@ -377,4 +385,16 @@
             }
         }
     }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mAnchorBounds: "); pw.println(mAnchorBounds);
+        pw.print(prefix); pw.print("mCallback: "); pw.println(mCallback != null);
+        pw.print(prefix); pw.print("mListView: "); pw.println(mListView);
+        pw.print(prefix); pw.print("mAdapter: "); pw.println(mAdapter != null);
+        pw.print(prefix); pw.print("mFilterText: "); pw.println(mFilterText);
+        pw.print(prefix); pw.print("mAccessibilityTitle: "); pw.println(mAccessibilityTitle);
+        pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
+        pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
+        pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/ui/Helper.java b/services/autofill/java/com/android/server/autofill/ui/Helper.java
new file mode 100644
index 0000000..996e421
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/ui/Helper.java
@@ -0,0 +1,26 @@
+/*
+ * 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.autofill.ui;
+
+final class Helper {
+
+    static final boolean DEBUG = true; // TODO(b/33197203): set to false when stable
+    static final boolean VERBOSE = false;
+    private Helper() {
+        throw new UnsupportedOperationException("contains static members only");
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 3f409ad..509351b 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -16,6 +16,8 @@
 
 package com.android.server.autofill.ui;
 
+import static com.android.server.autofill.ui.Helper.DEBUG;
+
 import android.annotation.NonNull;
 import android.app.Dialog;
 import android.content.Context;
@@ -23,6 +25,7 @@
 import android.os.Handler;
 import android.service.autofill.SaveInfo;
 import android.text.format.DateUtils;
+import android.util.Slog;
 import android.view.Gravity;
 import android.view.Window;
 import android.view.WindowManager;
@@ -37,22 +40,66 @@
  * Autofill Save Prompt
  */
 final class SaveUi {
+
+    private static final String TAG = "SaveUi";
+
     public interface OnSaveListener {
         void onSave();
         void onCancel(IntentSender listener);
+        void onDestroy();
+    }
+
+    private class OneTimeListener implements OnSaveListener {
+
+        private final OnSaveListener mRealListener;
+        private boolean mDone;
+
+        OneTimeListener(OnSaveListener realListener) {
+            mRealListener = realListener;
+        }
+
+        @Override
+        public void onSave() {
+            if (DEBUG) Slog.d(TAG, "onSave(): " + mDone);
+            if (mDone) {
+                return;
+            }
+            mDone = true;
+            mRealListener.onSave();
+        }
+
+        @Override
+        public void onCancel(IntentSender listener) {
+            if (DEBUG) Slog.d(TAG, "onCancel(): " + mDone);
+            if (mDone) {
+                return;
+            }
+            mDone = true;
+            mRealListener.onCancel(listener);
+        }
+
+        @Override
+        public void onDestroy() {
+            if (DEBUG) Slog.d(TAG, "onDestroy(): " + mDone);
+            if (mDone) {
+                return;
+            }
+            mDone = true;
+            mRealListener.onDestroy();
+        }
     }
 
     private final Handler mHandler = UiThread.getHandler();
 
     private final @NonNull Dialog mDialog;
 
-    private final @NonNull OnSaveListener mListener;
+    private final @NonNull OneTimeListener mListener;
 
     private boolean mDestroyed;
 
     SaveUi(@NonNull Context context, @NonNull CharSequence providerLabel, @NonNull SaveInfo info,
             @NonNull OnSaveListener listener, int lifeTimeMs) {
-        mListener = listener;
+        mListener = new OneTimeListener(listener);
 
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view = inflater.inflate(R.layout.autofill_save, null);
@@ -117,11 +164,17 @@
 
         mDialog.show();
 
-        mHandler.postDelayed(() -> mListener.onCancel(null), lifeTimeMs);
+        mHandler.postDelayed(() -> {
+            if (!mListener.mDone) {
+                mListener.onCancel(null);
+                Slog.d(TAG, "Save snackbar timed out after " + lifeTimeMs + "ms");
+            }
+        }, lifeTimeMs);
     }
 
     void destroy() {
         throwIfDestroyed();
+        mListener.onDestroy();
         mHandler.removeCallbacksAndMessages(mListener);
         mDialog.dismiss();
         mDestroyed = true;
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 1864d34..794ece6 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -23,7 +23,9 @@
     android.hardware.power@1.0-java \
     android.hardware.tv.cec@1.0-java
 
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2 \
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    tzdata_shared2 \
+    tzdata_update2 \
     android.hidl.base@1.0-java-static \
     android.hardware.biometrics.fingerprint@2.1-java-static \
 
diff --git a/services/core/java/com/android/server/BackgroundDexOptJobService.java b/services/core/java/com/android/server/BackgroundDexOptJobService.java
deleted file mode 100644
index 69e6ac5..0000000
--- a/services/core/java/com/android/server/BackgroundDexOptJobService.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
-
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
-import android.os.Environment;
-import android.os.ServiceManager;
-import android.os.storage.StorageManager;
-import android.util.ArraySet;
-import android.util.Log;
-import com.android.server.pm.PackageManagerService;
-
-import java.io.File;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.TimeUnit;
-
-public class BackgroundDexOptJobService extends JobService {
-    private static final String TAG = "BackgroundDexOptJobService";
-
-    private static final boolean DEBUG = false;
-
-    private static final int JOB_IDLE_OPTIMIZE = 800;
-    private static final int JOB_POST_BOOT_UPDATE = 801;
-
-    private static final long IDLE_OPTIMIZATION_PERIOD = DEBUG
-            ? TimeUnit.MINUTES.toMillis(1)
-            : TimeUnit.DAYS.toMillis(1);
-
-    private static ComponentName sDexoptServiceName = new ComponentName(
-            "android",
-            BackgroundDexOptJobService.class.getName());
-
-    /**
-     * Set of failed packages remembered across job runs.
-     */
-    static final ArraySet<String> sFailedPackageNames = new ArraySet<String>();
-
-    /**
-     * Atomics set to true if the JobScheduler requests an abort.
-     */
-    final AtomicBoolean mAbortPostBootUpdate = new AtomicBoolean(false);
-    final AtomicBoolean mAbortIdleOptimization = new AtomicBoolean(false);
-
-    /**
-     * Atomic set to true if one job should exit early because another job was started.
-     */
-    final AtomicBoolean mExitPostBootUpdate = new AtomicBoolean(false);
-
-    private final File mDataDir = Environment.getDataDirectory();
-
-    public static void schedule(Context context) {
-        JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
-
-        // Schedule a one-off job which scans installed packages and updates
-        // out-of-date oat files.
-        js.schedule(new JobInfo.Builder(JOB_POST_BOOT_UPDATE, sDexoptServiceName)
-                    .setMinimumLatency(TimeUnit.MINUTES.toMillis(1))
-                    .setOverrideDeadline(TimeUnit.MINUTES.toMillis(1))
-                    .build());
-
-        // Schedule a daily job which scans installed packages and compiles
-        // those with fresh profiling data.
-        js.schedule(new JobInfo.Builder(JOB_IDLE_OPTIMIZE, sDexoptServiceName)
-                    .setRequiresDeviceIdle(true)
-                    .setRequiresCharging(true)
-                    .setPeriodic(IDLE_OPTIMIZATION_PERIOD)
-                    .build());
-
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "Jobs scheduled");
-        }
-    }
-
-    public static void notifyPackageChanged(String packageName) {
-        // The idle maintanance job skips packages which previously failed to
-        // compile. The given package has changed and may successfully compile
-        // now. Remove it from the list of known failing packages.
-        synchronized (sFailedPackageNames) {
-            sFailedPackageNames.remove(packageName);
-        }
-    }
-
-    // Returns the current battery level as a 0-100 integer.
-    private int getBatteryLevel() {
-        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-        Intent intent = registerReceiver(null, filter);
-        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
-        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
-
-        if (level < 0 || scale <= 0) {
-            // Battery data unavailable. This should never happen, so assume the worst.
-            return 0;
-        }
-
-        return (100 * level / scale);
-    }
-
-    private long getLowStorageThreshold() {
-        @SuppressWarnings("deprecation")
-        final long lowThreshold = StorageManager.from(this).getStorageLowBytes(mDataDir);
-        if (lowThreshold == 0) {
-            Log.e(TAG, "Invalid low storage threshold");
-        }
-
-        return lowThreshold;
-    }
-
-    private boolean runPostBootUpdate(final JobParameters jobParams,
-            final PackageManagerService pm, final ArraySet<String> pkgs) {
-        if (mExitPostBootUpdate.get()) {
-            // This job has already been superseded. Do not start it.
-            return false;
-        }
-        new Thread("BackgroundDexOptService_PostBootUpdate") {
-            @Override
-            public void run() {
-                postBootUpdate(jobParams, pm, pkgs);
-            }
-
-        }.start();
-        return true;
-    }
-
-    private void postBootUpdate(JobParameters jobParams, PackageManagerService pm,
-            ArraySet<String> pkgs) {
-        // Load low battery threshold from the system config. This is a 0-100 integer.
-        final int lowBatteryThreshold = getResources().getInteger(
-                com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        final long lowThreshold = getLowStorageThreshold();
-
-        mAbortPostBootUpdate.set(false);
-
-        for (String pkg : pkgs) {
-            if (mAbortPostBootUpdate.get()) {
-                // JobScheduler requested an early abort.
-                return;
-            }
-            if (mExitPostBootUpdate.get()) {
-                // Different job, which supersedes this one, is running.
-                break;
-            }
-            if (getBatteryLevel() < lowBatteryThreshold) {
-                // Rather bail than completely drain the battery.
-                break;
-            }
-            long usableSpace = mDataDir.getUsableSpace();
-            if (usableSpace < lowThreshold) {
-                // Rather bail than completely fill up the disk.
-                Log.w(TAG, "Aborting background dex opt job due to low storage: " +
-                        usableSpace);
-                break;
-            }
-
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "Updating package " + pkg);
-            }
-
-            // Update package if needed. Note that there can be no race between concurrent
-            // jobs because PackageDexOptimizer.performDexOpt is synchronized.
-
-            // checkProfiles is false to avoid merging profiles during boot which
-            // might interfere with background compilation (b/28612421).
-            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
-            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
-            // trade-off worth doing to save boot time work.
-            pm.performDexOpt(pkg,
-                    /* checkProfiles */ false,
-                    PackageManagerService.REASON_BOOT,
-                    /* force */ false);
-        }
-        // Ran to completion, so we abandon our timeslice and do not reschedule.
-        jobFinished(jobParams, /* reschedule */ false);
-    }
-
-    private boolean runIdleOptimization(final JobParameters jobParams,
-            final PackageManagerService pm, final ArraySet<String> pkgs) {
-        new Thread("BackgroundDexOptService_IdleOptimization") {
-            @Override
-            public void run() {
-                idleOptimization(jobParams, pm, pkgs);
-            }
-        }.start();
-        return true;
-    }
-
-    private void idleOptimization(JobParameters jobParams, PackageManagerService pm,
-            ArraySet<String> pkgs) {
-        Log.i(TAG, "Performing idle optimizations");
-        // If post-boot update is still running, request that it exits early.
-        mExitPostBootUpdate.set(true);
-
-        mAbortIdleOptimization.set(false);
-
-        final long lowThreshold = getLowStorageThreshold();
-        for (String pkg : pkgs) {
-            if (mAbortIdleOptimization.get()) {
-                // JobScheduler requested an early abort.
-                return;
-            }
-
-            synchronized (sFailedPackageNames) {
-                if (sFailedPackageNames.contains(pkg)) {
-                    // Skip previously failing package
-                    continue;
-                }
-            }
-
-            long usableSpace = mDataDir.getUsableSpace();
-            if (usableSpace < lowThreshold) {
-                // Rather bail than completely fill up the disk.
-                Log.w(TAG, "Aborting background dex opt job due to low storage: " +
-                        usableSpace);
-                break;
-            }
-
-            // Conservatively add package to the list of failing ones in case performDexOpt
-            // never returns.
-            synchronized (sFailedPackageNames) {
-                sFailedPackageNames.add(pkg);
-            }
-            // Optimize package if needed. Note that there can be no race between
-            // concurrent jobs because PackageDexOptimizer.performDexOpt is synchronized.
-            if (pm.performDexOpt(pkg,
-                    /* checkProfiles */ true,
-                    PackageManagerService.REASON_BACKGROUND_DEXOPT,
-                    /* force */ false)) {
-                // Dexopt succeeded, remove package from the list of failing ones.
-                synchronized (sFailedPackageNames) {
-                    sFailedPackageNames.remove(pkg);
-                }
-            }
-        }
-        // Ran to completion, so we abandon our timeslice and do not reschedule.
-        jobFinished(jobParams, /* reschedule */ false);
-    }
-
-    @Override
-    public boolean onStartJob(JobParameters params) {
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "onStartJob");
-        }
-
-        // NOTE: PackageManagerService.isStorageLow uses a different set of criteria from
-        // the checks above. This check is not "live" - the value is determined by a background
-        // restart with a period of ~1 minute.
-        PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
-        if (pm.isStorageLow()) {
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "Low storage, skipping this run");
-            }
-            return false;
-        }
-
-        final ArraySet<String> pkgs = pm.getOptimizablePackages();
-        if (pkgs == null || pkgs.isEmpty()) {
-            if (DEBUG_DEXOPT) {
-                Log.i(TAG, "No packages to optimize");
-            }
-            return false;
-        }
-
-        if (params.getJobId() == JOB_POST_BOOT_UPDATE) {
-            return runPostBootUpdate(params, pm, pkgs);
-        } else {
-            return runIdleOptimization(params, pm, pkgs);
-        }
-    }
-
-    @Override
-    public boolean onStopJob(JobParameters params) {
-        if (DEBUG_DEXOPT) {
-            Log.i(TAG, "onStopJob");
-        }
-
-        if (params.getJobId() == JOB_POST_BOOT_UPDATE) {
-            mAbortPostBootUpdate.set(true);
-        } else {
-            mAbortIdleOptimization.set(true);
-        }
-        return false;
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 34c73d2..c946d09 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -1488,7 +1488,7 @@
             return VerifyCredentialResponse.OK;
         }
 
-        if (TextUtils.isEmpty(credential)) {
+        if (storedHash == null || TextUtils.isEmpty(credential)) {
             return VerifyCredentialResponse.ERROR;
         }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 3667ecd..8e6310f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2721,7 +2721,7 @@
      */
     @Override
     public int getPasswordType() {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
         waitForReady();
@@ -2747,7 +2747,7 @@
      */
     @Override
     public void setField(String field, String contents) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
         waitForReady();
@@ -2767,7 +2767,7 @@
      */
     @Override
     public String getField(String field) throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
         waitForReady();
@@ -2793,7 +2793,7 @@
      */
     @Override
     public boolean isConvertibleToFBE() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
         waitForReady();
@@ -2809,7 +2809,7 @@
 
     @Override
     public String getPassword() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
                 "only keyguard can retrieve password");
 
         if (!isReady()) {
@@ -2834,7 +2834,7 @@
 
     @Override
     public void clearPassword() throws RemoteException {
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.STORAGE_INTERNAL,
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
                 "only keyguard can clear password");
 
         if (!isReady()) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index accae0d..f954f75 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -35,7 +35,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
-import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.INotificationManager;
 import android.app.Notification;
@@ -64,7 +63,6 @@
 import android.content.pm.UserInfo;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteStatement;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -80,7 +78,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -113,7 +110,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -158,6 +154,11 @@
         public void onUnlockUser(int userHandle) {
             mService.onUnlockUser(userHandle);
         }
+
+        @Override
+        public void onCleanupUser(int userHandle) {
+            mService.onCleanupUser(userHandle);
+        }
     }
 
     final Context mContext;
@@ -303,18 +304,6 @@
             }
         }, intentFilter);
 
-        IntentFilter userFilter = new IntentFilter();
-        userFilter.addAction(Intent.ACTION_USER_REMOVED);
-        mContext.registerReceiverAsUser(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                if (Intent.ACTION_USER_REMOVED.equals(action)) {
-                    onUserRemoved(intent);
-                }
-            }
-        }, UserHandle.ALL, userFilter, null, null);
-
         injector.addLocalService(new AccountManagerInternalImpl());
 
         // Need to cancel account request notifications if the update/install can access the account
@@ -1133,16 +1122,12 @@
         }
     }
 
-    private void onUserRemoved(Intent intent) {
-        int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-        if (userId < 1) return;
-
+    private void onCleanupUser(int userId) {
+        Log.i(TAG, "onCleanupUser " + userId);
         UserAccounts accounts;
-        boolean userUnlocked;
         synchronized (mUsers) {
             accounts = mUsers.get(userId);
             mUsers.remove(userId);
-            userUnlocked = mLocalUnlockedUsers.get(userId);
             mLocalUnlockedUsers.delete(userId);
         }
         if (accounts != null) {
@@ -1150,18 +1135,6 @@
                 accounts.accountsDb.close();
             }
         }
-        Log.i(TAG, "Removing database files for user " + userId);
-        File dbFile = new File(mInjector.getDeDatabaseName(userId));
-
-        AccountsDb.deleteDbFileWarnIfFailed(dbFile);
-        // Remove CE file if user is unlocked, or FBE is not enabled
-        boolean fbeEnabled = StorageManager.isFileEncryptedNativeOrEmulated();
-        if (!fbeEnabled || userUnlocked) {
-            File ceDb = new File(mInjector.getCeDatabaseName(userId));
-            if (ceDb.exists()) {
-                AccountsDb.deleteDbFileWarnIfFailed(ceDb);
-            }
-        }
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 100d821..df250b1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -105,16 +105,16 @@
     }
 
     private void updateConstants() {
+        final String setting = Settings.Global.getString(mResolver,
+                Settings.Global.ACTIVITY_MANAGER_CONSTANTS);
         synchronized (mService) {
             try {
-                mParser.setString(Settings.Global.getString(mResolver,
-                        Settings.Global.ACTIVITY_MANAGER_CONSTANTS));
+                mParser.setString(setting);
             } catch (IllegalArgumentException e) {
                 // Failed to parse the settings string, log this and move on
                 // with defaults.
                 Slog.e("ActivityManagerConstants", "Bad activity manager config settings", e);
             }
-
             ENFORCE_BG_CHECK = mParser.getBoolean(KEY_ENFORCE_BG_CHECK, DEFAULT_ENFORCE_BG_CHECK);
             MAX_CACHED_PROCESSES = mParser.getInt(KEY_MAX_CACHED_PROCESSES,
                     DEFAULT_MAX_CACHED_PROCESSES);
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index ebbce02..918747b 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -251,7 +251,8 @@
      *                       ActivityManagerInternal.APP_TRANSITION_* reasons.
      */
     void notifyTransitionStarting(SparseIntArray stackIdReasons) {
-        if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
+        // TODO (b/36339388): Figure out why stackIdReasons can be null
+        if (stackIdReasons == null || !isAnyTransitionActive() || mLoggedTransitionStarting) {
             return;
         }
         mCurrentTransitionDelayMs = calculateCurrentDelay();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 2e26bed..2b2471b 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1953,11 +1953,6 @@
     }
 
     void setRequestedOrientation(int requestedOrientation) {
-        if (task != null && (!task.mFullscreen || !task.getStack().mFullscreen)) {
-            // Fixed screen orientation isn't supported when activities aren't in full screen mode.
-            return;
-        }
-
         final int displayId = getDisplayId();
         final Configuration displayConfig =
                 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 42efe0b..217515b 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
@@ -1612,8 +1613,8 @@
             return true;
         }
 
-        // Check if the caller can launch anything.
-        final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
+        // Check if the caller can manage activity stacks.
+        final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
                 callingUid);
         if (startAnyPerm == PERMISSION_GRANTED) {
             if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 36a913f..f927cce 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -857,17 +857,26 @@
 
         ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
 
-        String[] nativeProcs = NATIVE_STACKS_OF_INTEREST;
-        // don't dump native PIDs for background ANRs
-        File tracesFile = null;
+        // don't dump native PIDs for background ANRs unless it is the process of interest
+        String[] nativeProcs = null;
         if (isSilentANR) {
-            tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids,
-                null);
+            for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
+                if (NATIVE_STACKS_OF_INTEREST[i].equals(app.processName)) {
+                    nativeProcs = new String[] { app.processName };
+                    break;
+                }
+            }
         } else {
-            tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
-                nativeProcs);
+            nativeProcs = NATIVE_STACKS_OF_INTEREST;
         }
 
+        // For background ANRs, don't pass the ProcessCpuTracker to
+        // avoid spending 1/2 second collecting stats to rank lastPids.
+        File tracesFile = mService.dumpStackTraces(true, firstPids,
+                                                   (isSilentANR) ? null : processCpuTracker,
+                                                   (isSilentANR) ? null : lastPids,
+                                                   nativeProcs);
+
         String cpuInfo = null;
         if (ActivityManagerService.MONITOR_CPU_USAGE) {
             mService.updateCpuStatsNow();
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 2787895..dd3d4e0 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1152,17 +1152,14 @@
                     skip = true;
                 }
             }
-            final boolean visibleToInstantApps =
-                    (r.intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
             if (!skip && info.activityInfo.applicationInfo.isInstantApp()
-                    && !visibleToInstantApps
                     && r.callingUid != info.activityInfo.applicationInfo.uid) {
                 Slog.w(TAG, "Instant App Denial: receiving "
                         + r.intent
                         + " to " + component.flattenToShortString()
                         + " due to sender " + r.callerPackage
                         + " (uid " + r.callingUid + ")"
-                        + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
+                        + " Instant Apps do not support manifest receivers");
                 skip = true;
             }
             if (!skip && r.callerInstantApp
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
index dec2f77..8c6430c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity.tethering;
 
+import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+
 import android.net.INetd;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
@@ -48,7 +50,6 @@
 public class IPv6TetheringInterfaceServices {
     private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName();
     private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
-    private static final int RFC7421_IP_PREFIX_LENGTH = 64;
 
     private final String mIfName;
     private final INetworkManagementService mNMService;
@@ -124,7 +125,7 @@
             params.hasDefaultRoute = v6only.hasIPv6DefaultRoute();
 
             for (LinkAddress linkAddr : v6only.getLinkAddresses()) {
-                if (linkAddr.getPrefixLength() != RFC7421_IP_PREFIX_LENGTH) continue;
+                if (linkAddr.getPrefixLength() != RFC7421_PREFIX_LENGTH) continue;
 
                 final IpPrefix prefix = new IpPrefix(
                         linkAddr.getAddress(), linkAddr.getPrefixLength());
@@ -206,7 +207,7 @@
             for (Inet6Address dns : deprecatedDnses) {
                 final String dnsString = dns.getHostAddress();
                 try {
-                    netd.interfaceDelAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH);
+                    netd.interfaceDelAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
                 } catch (ServiceSpecificException | RemoteException e) {
                     Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e);
                 }
@@ -223,7 +224,7 @@
             for (Inet6Address dns : addedDnses) {
                 final String dnsString = dns.getHostAddress();
                 try {
-                    netd.interfaceAddAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH);
+                    netd.interfaceAddAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
                 } catch (ServiceSpecificException | RemoteException e) {
                     Log.e(TAG, "Failed to add local dns IP: " + dnsString, e);
                     newDnses.remove(dns);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 3262151..bdba64f 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -97,7 +97,6 @@
     static final String TAG = "FingerprintService";
     static final boolean DEBUG = true;
     private static final String FP_DATA_DIR = "fpdata";
-    private static final String FINGERPRINT_HIDL = "fingerprint_hal";
     private static final int MSG_USER_SWITCHING = 10;
     private static final String ACTION_LOCKOUT_RESET =
             "com.android.server.fingerprint.ACTION_LOCKOUT_RESET";
@@ -219,7 +218,7 @@
     public synchronized IBiometricsFingerprint getFingerprintDaemon() {
         if (mDaemon == null) {
             try {
-                mDaemon = IBiometricsFingerprint.getService(FINGERPRINT_HIDL);
+                mDaemon = IBiometricsFingerprint.getService();
             } catch (java.util.NoSuchElementException e) {
                 // Service doesn't exist or cannot be opened. Logged below.
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7285a4c..3dcc5d9 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -22,10 +22,10 @@
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
 import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED;
-import static android.service.notification.NotificationListenerService.REASON_DELEGATE_CANCEL;
-import static android.service.notification.NotificationListenerService.REASON_DELEGATE_CANCEL_ALL;
-import static android.service.notification.NotificationListenerService.REASON_DELEGATE_CLICK;
-import static android.service.notification.NotificationListenerService.REASON_DELEGATE_ERROR;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL;
+import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
+import static android.service.notification.NotificationListenerService.REASON_CLICK;
+import static android.service.notification.NotificationListenerService.REASON_ERROR;
 import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
 import static android.service.notification.NotificationListenerService.REASON_LISTENER_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_LISTENER_CANCEL_ALL;
@@ -88,7 +88,6 @@
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
 import android.media.IRingtonePlayer;
-import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -179,7 +178,6 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -543,7 +541,7 @@
         @Override
         public void onClearAll(int callingUid, int callingPid, int userId) {
             synchronized (mNotificationLock) {
-                cancelAllLocked(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null,
+                cancelAllLocked(callingUid, callingPid, userId, REASON_CANCEL_ALL, null,
                         /*includeCurrentProfiles*/ true);
             }
         }
@@ -567,7 +565,7 @@
                 cancelNotification(callingUid, callingPid, sbn.getPackageName(), sbn.getTag(),
                         sbn.getId(), Notification.FLAG_AUTO_CANCEL,
                         Notification.FLAG_FOREGROUND_SERVICE, false, r.getUserId(),
-                        REASON_DELEGATE_CLICK, null);
+                        REASON_CLICK, null);
             }
         }
 
@@ -596,7 +594,7 @@
                 String pkg, String tag, int id, int userId) {
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
                     Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
-                    true, userId, REASON_DELEGATE_CANCEL, null);
+                    true, userId, REASON_CANCEL, null);
         }
 
         @Override
@@ -631,7 +629,7 @@
             Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
                     + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
-                    REASON_DELEGATE_ERROR, null);
+                    REASON_ERROR, null);
             long ident = Binder.clearCallingIdentity();
             try {
                 ActivityManager.getService().crashApplication(uid, initialPid, pkg, -1,
@@ -1658,8 +1656,7 @@
         public NotificationChannel getNotificationChannelForPackage(String pkg, int uid,
                 String channelId, boolean includeDeleted) {
             checkCallerIsSystem();
-            return mRankingHelper.getNotificationChannel
-                    (pkg, uid, channelId, includeDeleted);
+            return mRankingHelper.getNotificationChannel(pkg, uid, channelId, includeDeleted);
         }
 
         @Override
@@ -1675,6 +1672,27 @@
         }
 
         @Override
+        public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(
+                String pkg) {
+            checkCallerIsSystemOrSameApp(pkg);
+            return new ParceledListSlice<>(new ArrayList(
+                    mRankingHelper.getNotificationChannelGroups(pkg, Binder.getCallingUid())));
+        }
+
+        @Override
+        public void deleteNotificationChannelGroup(String pkg, String channelGroupId) {
+            checkCallerIsSystemOrSameApp(pkg);
+
+            List<String> deletedChannelIds = mRankingHelper.deleteNotificationChannelGroup(
+                    pkg, Binder.getCallingUid(), channelGroupId);
+            for (int i = 0; i < deletedChannelIds.size(); i++) {
+                cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannelIds.get(i), 0, 0, true,
+                        UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, null);
+            }
+            savePolicyFile();
+        }
+
+        @Override
         public void updateNotificationChannelForPackage(String pkg, int uid,
                 NotificationChannel channel) {
             enforceSystemOrSystemUI("Caller not system or systemui");
@@ -3355,7 +3373,7 @@
                         Slog.e(TAG, "Not posting notification without small icon: " + notification);
                         if (old != null && !old.isCanceled) {
                             mListeners.notifyRemovedLocked(n,
-                                    NotificationListenerService.REASON_DELEGATE_ERROR);
+                                    NotificationListenerService.REASON_ERROR);
                             mHandler.post(new Runnable() {
                                 @Override
                                 public void run() {
@@ -4002,8 +4020,8 @@
         // Record usage stats
         // TODO: add unbundling stats?
         switch (reason) {
-            case REASON_DELEGATE_CANCEL:
-            case REASON_DELEGATE_CANCEL_ALL:
+            case REASON_CANCEL:
+            case REASON_CANCEL_ALL:
             case REASON_LISTENER_CANCEL:
             case REASON_LISTENER_CANCEL_ALL:
                 mUsageStats.registerDismissedByUser(r);
@@ -4063,7 +4081,7 @@
 
                         // Ideally we'd do this in the caller of this method. However, that would
                         // require the caller to also find the notification.
-                        if (reason == REASON_DELEGATE_CLICK) {
+                        if (reason == REASON_CLICK) {
                             mUsageStats.registerClickedByUser(r);
                         }
 
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index e239164..02f92fe 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -15,8 +15,6 @@
  */
 package com.android.server.notification;
 
-import static android.app.NotificationManager.IMPORTANCE_NONE;
-
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
@@ -654,8 +652,6 @@
 
     @Override
     public void deleteNotificationChannel(String pkg, int uid, String channelId) {
-        Preconditions.checkNotNull(pkg);
-        Preconditions.checkNotNull(channelId);
         Record r = getRecord(pkg, uid);
         if (r == null) {
             return;
@@ -667,6 +663,7 @@
         LogMaker lm = getChannelLog(channel, pkg);
         lm.setType(MetricsProto.MetricsEvent.TYPE_CLOSE);
         MetricsLogger.action(lm);
+        updateConfig();
     }
 
     @Override
@@ -679,6 +676,7 @@
             return;
         }
         r.channels.remove(channelId);
+        updateConfig();
     }
 
     @Override
@@ -695,6 +693,7 @@
                 r.channels.remove(key);
             }
         }
+        updateConfig();
     }
 
     public NotificationChannelGroup getNotificationChannelGroup(String groupId, String pkg,
@@ -719,12 +718,15 @@
             final NotificationChannel nc = r.channels.valueAt(i);
             if (includeDeleted || !nc.isDeleted()) {
                 if (nc.getGroup() != null) {
-                    NotificationChannelGroup ncg = groups.get(nc.getGroup());
-                    if (ncg == null ) {
-                        ncg = r.groups.get(nc.getGroup()).clone();
-                        groups.put(nc.getGroup(), ncg);
+                    if (r.groups.get(nc.getGroup()) != null) {
+                        NotificationChannelGroup ncg = groups.get(nc.getGroup());
+                        if (ncg == null) {
+                            ncg = r.groups.get(nc.getGroup()).clone();
+                            groups.put(nc.getGroup(), ncg);
+
+                        }
+                        ncg.addChannel(nc);
                     }
-                    ncg.addChannel(nc);
                 } else {
                     nonGrouped.addChannel(nc);
                 }
@@ -736,8 +738,29 @@
         return new ParceledListSlice<>(new ArrayList<>(groups.values()));
     }
 
+    public List<String> deleteNotificationChannelGroup(String pkg, int uid,
+            String groupId) {
+        List<String> deletedChannelIds = new ArrayList<>();
+        Record r = getRecord(pkg, uid);
+        if (r == null || TextUtils.isEmpty(groupId)) {
+            return deletedChannelIds;
+        }
+
+        r.groups.remove(groupId);
+
+        int N = r.channels.size();
+        for (int i = 0; i < N; i++) {
+            final NotificationChannel nc = r.channels.valueAt(i);
+            if (groupId.equals(nc.getGroup())) {
+                nc.setDeleted(true);
+                deletedChannelIds.add(nc.getId());
+            }
+        }
+        updateConfig();
+        return deletedChannelIds;
+    }
+
     @Override
-    @VisibleForTesting
     public Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid) {
         Record r = getRecord(pkg, uid);
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 7aa96cf..d8900c0 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -49,8 +49,6 @@
 
     private static final boolean DEBUG = false;
 
-    private static final long RETRY_LATENCY = 4 * AlarmManager.INTERVAL_HOUR;
-
     private static final int JOB_IDLE_OPTIMIZE = 800;
     private static final int JOB_POST_BOOT_UPDATE = 801;
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4ac1cce..1d1bf0d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -260,7 +260,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.server.AttributeCache;
-import com.android.server.BackgroundDexOptJobService;
 import com.android.server.DeviceIdleController;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
@@ -272,6 +271,7 @@
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.Watchdog;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.pm.BackgroundDexOptService;
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.pm.PermissionsState.PermissionState;
 import com.android.server.pm.Settings.DatabaseVersion;
@@ -2038,12 +2038,15 @@
         final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
                 >= Build.VERSION_CODES.M;
 
+        final boolean instantApp = isInstantApp(pkg.packageName, userId);
+
         for (String permission : pkg.requestedPermissions) {
             final BasePermission bp;
             synchronized (mPackages) {
                 bp = mSettings.mPermissions.get(permission);
             }
             if (bp != null && (bp.isRuntime() || bp.isDevelopment())
+                    && (!instantApp || bp.isInstant())
                     && (grantedPermissions == null
                            || ArrayUtils.contains(grantedPermissions, permission))) {
                 final int flags = permissionsState.getPermissionFlags(permission, userId);
@@ -3348,7 +3351,7 @@
         //   * The system/shell/root can see metadata for any app
         //   * An installed app can see metadata for 1) other installed apps
         //     and 2) ephemeral apps that have explicitly interacted with it
-        //   * Ephemeral apps can only see their own metadata
+        //   * Ephemeral apps can only see their own data and exposed installed apps
         //   * Holding a signature permission allows seeing instant apps
         final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
         if (callingAppId != Process.SYSTEM_UID
@@ -3358,8 +3361,10 @@
                         Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
             final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
             if (instantAppPackageName != null) {
-                // ephemeral apps can only get information on themselves
-                if (!instantAppPackageName.equals(p.packageName)) {
+                // ephemeral apps can only get information on themselves or
+                // installed apps that are exposed.
+                if (!instantAppPackageName.equals(p.packageName)
+                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
                     return null;
                 }
             } else {
@@ -16850,11 +16855,11 @@
                     mDexManager.isUsedByOtherApps(pkg.packageName));
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
-            // Notify BackgroundDexOptJobService that the package has been changed.
+            // Notify BackgroundDexOptService that the package has been changed.
             // If this is an update of a package which used to fail to compile,
             // BDOS will remove it from its blacklist.
             // TODO: Layering violation
-            BackgroundDexOptJobService.notifyPackageChanged(pkg.packageName);
+            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
         }
 
         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index a7349fc..751d9af 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -147,6 +147,8 @@
                     return runSetHomeActivity();
                 case "get-privapp-permissions":
                     return runGetPrivappPermissions();
+                case "has-feature":
+                    return runHasFeature();
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -1268,6 +1270,28 @@
         return 0;
     }
 
+    private int runHasFeature() {
+        final PrintWriter err = getErrPrintWriter();
+        final String featureName = getNextArg();
+        if (featureName == null) {
+            err.println("Error: expected FEATURE name");
+            return 1;
+        }
+        final String versionString = getNextArg();
+        try {
+            final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
+            final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
+            getOutPrintWriter().println(hasFeature);
+            return hasFeature ? 0 : 1;
+        } catch (NumberFormatException e) {
+            err.println("Error: illegal version number " + versionString);
+            return 1;
+        } catch (RemoteException e) {
+            err.println(e.toString());
+            return 1;
+        }
+    }
+
     private static String checkAbiArgument(String abi) {
         if (TextUtils.isEmpty(abi)) {
             throw new IllegalArgumentException("Missing ABI argument");
@@ -1649,6 +1673,9 @@
         pw.println("    Unsuspends the specified package (as user).");
         pw.println("  set-home-activity [--user USER_ID] TARGET-COMPONENT");
         pw.println("    set the default home activity (aka launcher).");
+        pw.println("  has-feature FEATURE_NAME [version]");
+        pw.println("   prints true and returns exit status 0 when system has a FEATURE_NAME,");
+        pw.println("   otherwise prints false and returns exit status 1");
         pw.println();
         Intent.printIntentArgsHelp(pw , "");
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b9fcf4e..a31258c3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1493,6 +1493,10 @@
                     listeners[i].onUserRestrictionsChanged(userId,
                             newRestrictionsFinal, prevRestrictionsFinal);
                 }
+
+                final Intent broadcast = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                mContext.sendBroadcastAsUser(broadcast, UserHandle.of(userId));
             }
         });
     }
@@ -1810,8 +1814,8 @@
                             if (type == XmlPullParser.START_TAG) {
                                 if (parser.getName().equals(TAG_RESTRICTIONS)) {
                                     synchronized (mGuestRestrictions) {
-                                        mGuestRestrictions.putAll(
-                                                UserRestrictionsUtils.readRestrictions(parser));
+                                        UserRestrictionsUtils
+                                                .readRestrictions(parser, mGuestRestrictions);
                                     }
                                 }
                                 break;
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 36eba8e..cb2ed6e 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -207,6 +207,7 @@
     }
 
     public static void readRestrictions(XmlPullParser parser, Bundle restrictions) {
+        restrictions.clear();
         for (String key : USER_RESTRICTIONS) {
             final String value = parser.getAttributeValue(null, key);
             if (value != null) {
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
index 5e17daa..8f95cc7 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
@@ -1,6 +1,8 @@
 
 package com.android.server.vr;
 
+import static android.view.Display.INVALID_DISPLAY;
+
 import android.app.Service;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -86,10 +88,8 @@
                 startVirtualDisplay();
             }
         } else {
-            // TODO: Remove conditional when launching apps 2D doesn't force VrMode to stop.
-            if (!DEBUG) {
-                stopVirtualDisplay();
-            }
+            // Stop virtual display to test exit condition
+            stopVirtualDisplay();
         }
     }
 
@@ -138,6 +138,19 @@
         }
     }
 
+    public int getVirtualDisplayId() {
+        synchronized(vdLock) {
+            if (mVirtualDisplay != null) {
+                int virtualDisplayId = mVirtualDisplay.getDisplay().getDisplayId();
+                if (DEBUG) {
+                    Log.e(TAG, "VD id: " + virtualDisplayId);
+                }
+                return virtualDisplayId;
+            }
+        }
+        return INVALID_DISPLAY;
+    }
+
     private void startVirtualDisplay() {
         if (DEBUG) {
             Log.d(TAG, "Request to start VD, DM:" + mDisplayManager);
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 58e4bdc..210aa44 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -90,6 +90,15 @@
     public abstract void setPersistentVrModeEnabled(boolean enabled);
 
     /**
+     * Return {@link android.view.Display.INVALID_DISPLAY} if there exists no virtual display
+     * currently or the display id of the current virtual display.
+     *
+     * @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
+     * currently, else return the display id of the virtual display
+     */
+    public abstract int getCompatibilityDisplayId();
+
+    /**
      * Adds listener that reports state changes to persistent VR mode.
      */
     public abstract void addPersistentVrModeStateListener(PersistentVrStateListener listener);
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 8a23173..a00115c 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.vr;
 
+import static android.view.Display.INVALID_DISPLAY;
+
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
@@ -392,6 +394,11 @@
         }
 
         @Override
+        public int getCompatibilityDisplayId() {
+            return VrManagerService.this.getCompatibilityDisplayId();
+        }
+
+        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -495,6 +502,11 @@
         }
 
         @Override
+        public int getCompatibilityDisplayId() {
+            return VrManagerService.this.getCompatibilityDisplayId();
+        }
+
+        @Override
         public void addPersistentVrModeStateListener(PersistentVrStateListener listener) {
             VrManagerService.this.addPersistentVrModeStateListener(listener);
         }
@@ -1054,6 +1066,14 @@
         }
     }
 
+    private int getCompatibilityDisplayId() {
+        if (mCompatibilityDisplay != null) {
+            return mCompatibilityDisplay.getVirtualDisplayId();
+        }
+        Slog.w(TAG, "CompatibilityDisplay is null!");
+        return INVALID_DISPLAY;
+    }
+
     private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
         if (mPersistentVrModeEnabled == enabled) {
             return;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 4df513e..30e0ded 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -28,7 +28,6 @@
 
 import android.content.ClipData;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
@@ -39,6 +38,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.view.Display;
 import android.view.IWindow;
@@ -216,13 +216,13 @@
             int requestedWidth, int requestedHeight, int viewFlags,
             int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
             Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
-            Configuration outConfig, Surface outSurface) {
+            MergedConfiguration mergedConfiguration, Surface outSurface) {
         if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         int res = mService.relayoutWindow(this, window, seq, attrs,
                 requestedWidth, requestedHeight, viewFlags, flags,
                 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
-                outStableInsets, outsets, outBackdropFrame, outConfig, outSurface);
+                outStableInsets, outsets, outBackdropFrame, mergedConfiguration, outSurface);
         if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
         return res;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index c0598ca..04403e2 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -27,7 +27,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.app.ActivityManager.TaskDescription;
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -38,6 +37,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.view.IWindowSession;
 import android.view.Surface;
@@ -78,7 +78,7 @@
         final Surface surface = new Surface();
         final Rect tmpRect = new Rect();
         final Rect tmpFrame = new Rect();
-        final Configuration tmpConfiguration = new Configuration();
+        final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
         int fillBackgroundColor = Color.WHITE;
         synchronized (service.mWindowMap) {
             layoutParams.type = TYPE_APPLICATION_STARTING;
@@ -122,7 +122,7 @@
         window.setOuter(snapshotSurface);
         try {
             session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, tmpFrame,
-                    tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpConfiguration,
+                    tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpMergedConfiguration,
                     surface);
         } catch (RemoteException e) {
             // Local call.
@@ -221,9 +221,9 @@
 
         @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
-                Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig,
-                Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar,
-                int displayId) {
+                Rect stableInsets, Rect outsets, boolean reportDraw,
+                MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
+                boolean alwaysConsumeNavBar, int displayId) {
             if (reportDraw) {
                 sHandler.obtainMessage(MSG_REPORT_DRAW, mOuter).sendToTarget();
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5551afe..7539cd4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -150,6 +150,7 @@
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.ArraySet;
+import android.util.MergedConfiguration;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -1813,7 +1814,7 @@
             int requestedHeight, int viewVisibility, int flags,
             Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
             Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
-            Configuration outConfig, Surface outSurface) {
+            MergedConfiguration mergedConfiguration, Surface outSurface) {
         int result = 0;
         boolean configChanged;
         boolean hasStatusBarPermission =
@@ -1925,7 +1926,7 @@
             if (viewVisibility == View.VISIBLE &&
                     (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
                             || !win.mAppToken.clientHidden)) {
-                result = win.relayoutVisibleWindow(outConfig, result, attrChanges,
+                result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
                         oldVisibility);
                 try {
                     result = createSurfaceControl(outSurface, result, win, winAnimator);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4e593d8..ca5d551 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -114,6 +114,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.util.MergedConfiguration;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -2265,7 +2266,7 @@
         }
     }
 
-    void prepareWindowToDisplayDuringRelayout(Configuration outConfig) {
+    void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration) {
         if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
                 == SOFT_INPUT_ADJUST_RESIZE) {
             mLayoutNeeded = true;
@@ -2278,10 +2279,13 @@
             mTurnOnScreen = true;
         }
         if (isConfigChanged()) {
-            outConfig.setTo(getConfiguration());
-            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: "
-                    + outConfig);
-            mLastReportedConfiguration.setTo(outConfig);
+            final Configuration globalConfig = mService.mRoot.getConfiguration();
+            final Configuration overrideConfig = getMergedOverrideConfiguration();
+            mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
+            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
+                    + " visible with new global config: " + globalConfig
+                    + " merged override config: " + overrideConfig);
+            mLastReportedConfiguration.setTo(getConfiguration());
         }
     }
 
@@ -3027,12 +3031,13 @@
         try {
             if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
                     + ": " + mCompatFrame);
-            final Configuration newConfig;
+            final MergedConfiguration mergedConfiguration;
             if (isConfigChanged()) {
-                newConfig = new Configuration(getConfiguration());
-                mLastReportedConfiguration.setTo(newConfig);
+                mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(),
+                        getMergedOverrideConfiguration());
+                mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration());
             } else {
-                newConfig = null;
+                mergedConfiguration = null;
             }
             if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
                 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
@@ -3054,7 +3059,7 @@
                     public void run() {
                         try {
                             dispatchResized(frame, overscanInsets, contentInsets, visibleInsets,
-                                    stableInsets, outsets, reportDraw, newConfig,
+                                    stableInsets, outsets, reportDraw, mergedConfiguration,
                                     reportOrientation, displayId);
                         } catch (RemoteException e) {
                             // Not a remote call, RemoteException won't be raised.
@@ -3063,7 +3068,7 @@
                 });
             } else {
                 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
-                        outsets, reportDraw, newConfig, reportOrientation, displayId);
+                        outsets, reportDraw, mergedConfiguration, reportOrientation, displayId);
             }
 
             //TODO (multidisplay): Accessibility supported only for the default display.
@@ -3120,14 +3125,14 @@
 
     private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
             Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-            Configuration newConfig, boolean reportOrientation, int displayId)
+            MergedConfiguration mergedConfiguration, boolean reportOrientation, int displayId)
             throws RemoteException {
         final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing
                 || reportOrientation;
 
         mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
-                reportDraw, newConfig, getBackdropFrame(frame),
-                forceRelayout, mPolicy.isNavBarForcedShownLw(this), displayId);
+                reportDraw, mergedConfiguration, getBackdropFrame(frame), forceRelayout,
+                mPolicy.isNavBarForcedShownLw(this), displayId);
         mDragResizingChangeReported = true;
     }
 
@@ -4341,8 +4346,8 @@
         return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
     }
 
-    int relayoutVisibleWindow(Configuration outConfig, int result,
-            int attrChanges, int oldVisibility) {
+    int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges,
+            int oldVisibility) {
         result |= !isVisibleLw() ? RELAYOUT_RES_FIRST_TIME : 0;
         if (mAnimatingExit) {
             Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit="
@@ -4363,7 +4368,7 @@
 
         mWinAnimator.mEnteringAnimation = true;
         if ((result & RELAYOUT_RES_FIRST_TIME) != 0) {
-            prepareWindowToDisplayDuringRelayout(outConfig);
+            prepareWindowToDisplayDuringRelayout(mergedConfiguration);
         }
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index ac95db5..b5ed266 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -65,6 +65,7 @@
     libinputflinger \
     libinputservice \
     libsensorservice \
+    libsensorservicehidl \
     libskia \
     libgui \
     libusbhost \
@@ -88,5 +89,6 @@
     android.hardware.tv.input@1.0 \
     android.hardware.vibrator@1.0 \
     android.hardware.vr@1.0 \
+    android.frameworks.sensorservice@1.0 \
 
-LOCAL_STATIC_LIBRARIES += libscrypt_static
\ No newline at end of file
+LOCAL_STATIC_LIBRARIES += libscrypt_static
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 3120af5..8ad88ed 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -17,7 +17,10 @@
 #include <jni.h>
 #include <JNIHelp.h>
 
+#include <hidl/HidlTransportSupport.h>
+
 #include <sensorservice/SensorService.h>
+#include <sensorservicehidl/SensorManager.h>
 
 #include <cutils/properties.h>
 #include <utils/Log.h>
@@ -32,6 +35,21 @@
     if (strcmp(propBuf, "1") == 0) {
         SensorService::instantiate();
     }
+
+}
+
+static void android_server_SystemServer_startHidlServices(JNIEnv* /* env */, jobject /* clazz */) {
+    using ::android::frameworks::sensorservice::V1_0::ISensorManager;
+    using ::android::frameworks::sensorservice::V1_0::implementation::SensorManager;
+    using ::android::hardware::configureRpcThreadpool;
+
+    configureRpcThreadpool(1, false /* callerWillJoin */);
+    sp<ISensorManager> sensorService = new SensorManager();
+    status_t err = sensorService->registerAsService();
+    if (err != OK) {
+        ALOGE("Cannot register ::android::frameworks::sensorservice::V1_0::"
+              "implementation::SensorManager: %d", err);
+    }
 }
 
 /*
@@ -40,6 +58,7 @@
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
     { "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService },
+    { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
 };
 
 int register_android_server_SystemServer(JNIEnv* env)
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a8423e2..e6e0242 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -86,6 +86,7 @@
 import com.android.server.om.OverlayManagerService;
 import com.android.server.os.DeviceIdentifiersPolicyService;
 import com.android.server.os.SchedulingPolicyService;
+import com.android.server.pm.BackgroundDexOptService;
 import com.android.server.pm.Installer;
 import com.android.server.pm.LauncherAppsService;
 import com.android.server.pm.OtaDexoptService;
@@ -235,16 +236,24 @@
     private final boolean mRuntimeRestart;
 
     private static final String START_SENSOR_SERVICE = "StartSensorService";
+    private static final String START_HIDL_SERVICES = "StartHidlServices";
+
+
     private Future<?> mSensorServiceStart;
     private Future<?> mZygotePreload;
 
-
     /**
      * Start the sensor service. This is a blocking call and can take time.
      */
     private static native void startSensorService();
 
     /**
+     * Start all HIDL services that are run inside the system server. This
+     * may take some time.
+     */
+    private static native void startHidlServices();
+
+    /**
      * The main entry point from zygote.
      */
     public static void main(String[] args) {
@@ -610,6 +619,7 @@
             startSensorService();
             traceLog.traceEnd();
         }, START_SENSOR_SERVICE);
+
     }
 
     /**
@@ -637,6 +647,14 @@
         traceBeginAndSlog("StartWebViewUpdateService");
         mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
         traceEnd();
+
+        // Start receiving calls from HIDL services. Start in in a separate thread
+        // because it need to connect to SensorManager.
+        SystemServerInitThreadPool.get().submit(() -> {
+            traceBeginAndSlog(START_HIDL_SERVICES);
+            startHidlServices();
+            traceEnd();
+        }, START_HIDL_SERVICES);
     }
 
     /**
@@ -1428,11 +1446,11 @@
                     traceEnd();
                 }
 
-                traceBeginAndSlog("StartBackgroundDexOptJobService");
+                traceBeginAndSlog("StartBackgroundDexOptService");
                 try {
-                    BackgroundDexOptJobService.schedule(context);
+                    BackgroundDexOptService.schedule(context);
                 } catch (Throwable e) {
-                    reportWtf("starting StartBackgroundDexOptJobService", e);
+                    reportWtf("starting StartBackgroundDexOptService", e);
                 }
                 traceEnd();
 
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 3e3a19b..c670782 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -16,6 +16,8 @@
 
 package android.net.ip;
 
+import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.WakeupMessage;
 
@@ -42,6 +44,7 @@
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.LocalLog;
 import android.util.Log;
@@ -1028,15 +1031,36 @@
         return true;
     }
 
-    private boolean startIPv6() {
-        // Set privacy extensions.
+    private void enableInterfaceIPv6PrivacyExtensions() {
         final String PREFER_TEMPADDRS = "2";
+        NetdService.run((INetd netd) -> {
+                netd.setProcSysNet(
+                        INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr", PREFER_TEMPADDRS);
+            });
+    }
+
+    private void setInterfaceIPv6RaRtInfoMaxPlen(int plen) {
+        // Setting RIO max plen is best effort. Catch and ignore most exceptions.
         try {
             NetdService.run((INetd netd) -> {
-                netd.setProcSysNet(
-                        INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr",
-                        PREFER_TEMPADDRS);
-            });
+                    netd.setProcSysNet(
+                            INetd.IPV6, INetd.CONF, mInterfaceName, "accept_ra_rt_info_max_plen",
+                            Integer.toString(plen));
+                });
+        } catch (ServiceSpecificException e) {
+            // Old kernel versions without support for RIOs do not export accept_ra_rt_info_max_plen
+            // in the /proc filesystem. If the kernel supports RIOs we should never see any other
+            // type of error.
+            if (e.errorCode != OsConstants.ENOENT) {
+                logError("unexpected error setting accept_ra_rt_info_max_plen %s", e);
+            }
+        }
+    }
+
+    private boolean startIPv6() {
+        try {
+            enableInterfaceIPv6PrivacyExtensions();
+            setInterfaceIPv6RaRtInfoMaxPlen(RFC7421_PREFIX_LENGTH);
             mNwService.enableIpv6(mInterfaceName);
         } catch (IllegalStateException|RemoteException|ServiceSpecificException e) {
             logError("Unable to change interface settings: %s", e);
diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java
index 362f757..26f3050 100644
--- a/services/net/java/android/net/util/NetworkConstants.java
+++ b/services/net/java/android/net/util/NetworkConstants.java
@@ -97,6 +97,7 @@
     public static final int IPV6_SRC_ADDR_OFFSET = 8;
     public static final int IPV6_DST_ADDR_OFFSET = 24;
     public static final int IPV6_ADDR_LEN = 16;
+    public static final int RFC7421_PREFIX_LENGTH = 64;
 
     /**
      * ICMPv6 constants.
diff --git a/services/tests/notification/Android.mk b/services/tests/notification/Android.mk
index de9553a..a5d5570 100644
--- a/services/tests/notification/Android.mk
+++ b/services/tests/notification/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_JACK_FLAGS := --multi-dex native
 
 LOCAL_PACKAGE_NAME := FrameworksNotificationTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index b538453..27b9a88 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -854,6 +854,43 @@
     }
 
     @Test
+    public void testDeleteGroup() throws Exception {
+        NotificationChannelGroup notDeleted = new NotificationChannelGroup("not", "deleted");
+        NotificationChannelGroup deleted = new NotificationChannelGroup("totally", "deleted");
+        NotificationChannel nonGroupedNonDeletedChannel =
+                new NotificationChannel("no group", "so not deleted", IMPORTANCE_HIGH);
+        NotificationChannel groupedButNotDeleted =
+                new NotificationChannel("not deleted", "belongs to notDeleted", IMPORTANCE_DEFAULT);
+        groupedButNotDeleted.setGroup("not");
+        NotificationChannel groupedAndDeleted =
+                new NotificationChannel("deleted", "belongs to deleted", IMPORTANCE_DEFAULT);
+        groupedAndDeleted.setGroup("totally");
+
+        mHelper.createNotificationChannelGroup(pkg, uid, notDeleted, true);
+        mHelper.createNotificationChannelGroup(pkg, uid, deleted, true);
+        mHelper.createNotificationChannel(pkg, uid, nonGroupedNonDeletedChannel, true);
+        mHelper.createNotificationChannel(pkg, uid, groupedAndDeleted, true);
+        mHelper.createNotificationChannel(pkg, uid, groupedButNotDeleted, true);
+
+        mHelper.deleteNotificationChannelGroup(pkg, uid, deleted.getId());
+
+        assertNull(mHelper.getNotificationChannelGroup(deleted.getId(), pkg, uid));
+        assertNotNull(mHelper.getNotificationChannelGroup(notDeleted.getId(), pkg, uid));
+
+        assertNull(mHelper.getNotificationChannel(pkg, uid, groupedAndDeleted.getId(), false));
+        compareChannels(groupedAndDeleted,
+                mHelper.getNotificationChannel(pkg, uid, groupedAndDeleted.getId(), true));
+
+        compareChannels(groupedButNotDeleted,
+                mHelper.getNotificationChannel(pkg, uid, groupedButNotDeleted.getId(), false));
+        compareChannels(nonGroupedNonDeletedChannel, mHelper.getNotificationChannel(
+                pkg, uid, nonGroupedNonDeletedChannel.getId(), false));
+
+        // notDeleted
+        assertEquals(1, mHelper.getNotificationChannelGroups(pkg, uid).size());
+    }
+
+    @Test
     public void testOnPackageChanged_packageRemoval() throws Exception {
         // Deleted
         NotificationChannel channel1 =
@@ -889,7 +926,7 @@
 
         mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{pkg}, new int[]{uid});
 
-        assertEquals(0, mHelper.getNotificationChannelGroups(pkg, uid, true).getList().size());
+        assertEquals(0, mHelper.getNotificationChannelGroups(pkg, uid).size());
     }
 
     @Test
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 15c61f6..2a8f4a3 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_PACKAGE_NAME := FrameworksServicesTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 9f50a2c..921e0e3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -126,8 +126,6 @@
     }
 
     @Test
-    @Ignore
-    // TODO(b/35034729): Need to fix before re-enabling
     public void testLandscapeSeascapeRotationByPolicy() throws Exception {
         // Some plumbing to get the service ready for rotation updates.
         sWm.mDisplayReady = true;
@@ -145,15 +143,20 @@
         appWindowToken.addWindow(appWindow);
 
         // Set initial orientation and update.
-        ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = Surface.ROTATION_90;
-        sWm.updateRotation(false, false);
+        performRotation(Surface.ROTATION_90);
         appWindow.resizeReported = false;
 
         // Update the rotation to perform 180 degree rotation and check that resize was reported.
-        ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = Surface.ROTATION_270;
-        sWm.updateRotation(false, false);
-        sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+        performRotation(Surface.ROTATION_270);
         assertTrue(appWindow.resizeReported);
         appWindow.removeImmediately();
     }
+
+    private void performRotation(int rotationToReport) {
+        ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = rotationToReport;
+        sWm.updateRotation(false, false);
+        // Simulate animator finishing orientation change
+        sWm.mRoot.mOrientationChangeComplete = true;
+        sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
index b6dc9a5..0a644b60 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
@@ -18,11 +18,11 @@
 
 import com.android.internal.os.IResultReceiver;
 
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.util.MergedConfiguration;
 import android.view.DragEvent;
 import android.view.IWindow;
 
@@ -36,7 +36,7 @@
 
     @Override
     public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
-            Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig,
+            Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfig,
             Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId)
             throws RemoteException {
 
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 911050a..65efd9c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -71,7 +71,10 @@
     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;
+    // The default display is removed in {@link #setUp} and then we iterate over all displays to
+    // make sure we don't collide with any existing display. If we run into no other display, the
+    // added display should be treated as default.
+    private static int sNextDisplayId = Display.DEFAULT_DISPLAY;
     static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
     private static int sNextTaskId = 0;
 
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 40bdaa5..03d8241 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -25,8 +25,8 @@
 import android.media.AudioSystem;
 import android.media.IAudioService;
 import android.media.midi.MidiDeviceInfo;
-import android.os.FileObserver;
 import android.os.Bundle;
+import android.os.FileObserver;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -41,10 +41,7 @@
 import libcore.io.IoUtils;
 
 import java.io.File;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
 import java.util.HashMap;
-import java.util.ArrayList;
 
 /**
  * UsbAlsaManager manages USB audio and MIDI devices.
@@ -219,23 +216,23 @@
         AlsaDevice testDevice = new AlsaDevice(type, card, device);
 
         // This value was empirically determined.
-        final int kWaitTime = 2500; // ms
+        final int kWaitTimeMs = 2500;
 
         synchronized(mAlsaDevices) {
-            long timeout = SystemClock.elapsedRealtime() + kWaitTime;
+            long timeoutMs = SystemClock.elapsedRealtime() + kWaitTimeMs;
             do {
                 if (mAlsaDevices.values().contains(testDevice)) {
                     return testDevice;
                 }
-                long waitTime = timeout - SystemClock.elapsedRealtime();
-                if (waitTime > 0) {
+                long waitTimeMs = timeoutMs - SystemClock.elapsedRealtime();
+                if (waitTimeMs > 0) {
                     try {
-                        mAlsaDevices.wait(waitTime);
+                        mAlsaDevices.wait(waitTimeMs);
                     } catch (InterruptedException e) {
                         Slog.d(TAG, "usb: InterruptedException while waiting for ALSA file.");
                     }
                 }
-            } while (timeout > SystemClock.elapsedRealtime());
+            } while (timeoutMs > SystemClock.elapsedRealtime());
         }
 
         Slog.e(TAG, "waitForAlsaDevice failed for " + testDevice);
@@ -498,6 +495,7 @@
     // Devices List
     //
 /*
+    //import java.util.ArrayList;
     public ArrayList<UsbAudioDevice> getConnectedDevices() {
         ArrayList<UsbAudioDevice> devices = new ArrayList<UsbAudioDevice>(mAudioDevices.size());
         for (HashMap.Entry<UsbDevice,UsbAudioDevice> entry : mAudioDevices.entrySet()) {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
index 808b5d3..a7bdabd 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
@@ -138,7 +138,7 @@
             mSaturation = saturation;
             final ColorMatrixColorFilter filter =
                     (ColorMatrixColorFilter) mColorMatrixPaint.getColorFilter();
-            final ColorMatrix m = filter.getColorMatrix();
+            final ColorMatrix m = new ColorMatrix();
             m.setSaturation(saturation);
             filter.setColorMatrix(m);
             invalidate();
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index 79f6e4d..504d54e 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -24,6 +24,7 @@
     android.test.runner
 
 LOCAL_PACKAGE_NAME := FrameworksNetTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/tests/testables/Android.mk b/tests/testables/Android.mk
index 58399fd..759bc35 100644
--- a/tests/testables/Android.mk
+++ b/tests/testables/Android.mk
@@ -25,7 +25,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
-    mockito-updated-target-minus-junit4 \
+    mockito-target-minus-junit4 \
     legacy-android-test
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/tests/testables/tests/Android.mk b/tests/testables/tests/Android.mk
index 752d536..a123d80 100644
--- a/tests/testables/tests/Android.mk
+++ b/tests/testables/tests/Android.mk
@@ -27,7 +27,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
-    mockito-updated-target-minus-junit4 \
+    mockito-target-minus-junit4 \
     legacy-android-test \
 	testables
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
index b1e71b2..cc71053 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
@@ -24,6 +24,7 @@
 import com.android.ninepatch.NinePatchChunk;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.annotation.Nullable;
 import android.text.TextUtils;
 
 import java.awt.*;
@@ -31,6 +32,8 @@
 import java.awt.geom.Arc2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
 
 public class BaseCanvas_Delegate {
     // ---- delegate manager ----
@@ -646,9 +649,15 @@
         forceSrcMode[0] = false;
 
         // if the bitmap config is alpha_8, then we erase all color value from it
-        // before drawing it.
+        // before drawing it or apply the texture from the shader if present.
         if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
-            fixAlpha8Bitmap(image);
+            Shader_Delegate shader = paint.getShader();
+            java.awt.Paint javaPaint = null;
+            if (shader instanceof BitmapShader_Delegate) {
+                javaPaint = shader.getJavaPaint();
+            }
+
+            fixAlpha8Bitmap(image, javaPaint);
         } else if (!bitmap.hasAlpha()) {
             // hasAlpha is merely a rendering hint. There can in fact be alpha values
             // in the bitmap but it should be ignored at drawing time.
@@ -672,16 +681,37 @@
         return image;
     }
 
-    private static void fixAlpha8Bitmap(final BufferedImage image) {
+    /**
+     * This method will apply the correct color to the passed "only alpha" image. Colors on the
+     * passed image will be destroyed.
+     * If the passed javaPaint is null, the color will be set to 0. If a paint is passed, it will
+     * be used to obtain the color that will be applied.
+     * <p/>
+     * This will destroy the passed image color channel.
+     */
+    private static void fixAlpha8Bitmap(final BufferedImage image,
+            @Nullable java.awt.Paint javaPaint) {
         int w = image.getWidth();
         int h = image.getHeight();
+
+        DataBuffer texture = null;
+        if (javaPaint != null) {
+            PaintContext context = javaPaint.createContext(ColorModel.getRGBdefault(), null, null,
+                    new AffineTransform(), null);
+            texture = context.getRaster(0, 0, w, h).getDataBuffer();
+        }
+
         int[] argb = new int[w * h];
         image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
 
         final int length = argb.length;
-        for (int i = 0 ; i < length; i++) {
+        for (int i = 0; i < length; i++) {
             argb[i] &= 0xFF000000;
+            if (texture != null) {
+                argb[i] |= texture.getElem(i) & 0x00FFFFFF;
+            }
         }
+
         image.setRGB(0, 0, w, h, argb, 0, w);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
index bd934d0..cb013b6 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
@@ -66,7 +66,7 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static void destroyFilter(long native_instance) {
+    /*package*/ static void nSafeUnref(long native_instance) {
         sManager.removeJavaReferenceFor(native_instance);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index ff5a5e9..aaff5d5 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -16,7 +16,6 @@
 
 package android.graphics;
 
-import android.text.FontConfig;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
@@ -293,12 +292,16 @@
 
     @LayoutlibDelegate
     /*package*/ static boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
-            int ttcIndex, List<FontConfig.Axis> listOfAxis,
-            int weight, boolean isItalic) {
+            int ttcIndex, int weight, boolean isItalic) {
         assert false : "The only client of this method has been overriden.";
         return false;
     }
 
+    @LayoutlibDelegate
+    /*package*/ static void nAddAxisValue(long builderPtr, int tag, float value) {
+        assert false : "The only client of this method has been overriden.";
+    }
+
     static boolean addFont(long builderPtr, final String path, final int weight,
             final boolean isItalic) {
         final FontFamily_Delegate delegate = getDelegate(builderPtr);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index aa1f00d..1bb56e3 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -964,8 +964,9 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, char[] text,
-            int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
+    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
+            char[] text, int contextStart, int contextLength, int flags, int offset,
+            int cursorOpt) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
@@ -973,8 +974,8 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, String text,
-            int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
+    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
+            String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextRunCursor is not supported.", null, null /*data*/);
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java
deleted file mode 100644
index 7e9432d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.drawable.AdaptiveIconDrawable.LayerState;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * AdaptiveIconDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of AdaptiveIconDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class AdaptiveIconDrawable_Delegate {
-    @LayoutlibDelegate
-    /*package*/ static void draw(AdaptiveIconDrawable thisDrawable, Canvas canvas) {
-        // This is a workaround for the broken BitmapShader in layoutlib. This new draw methods
-        // avoids the use of the shader.
-
-        for (int i = 0; i < LayerState.N_CHILDREN; i++) {
-            if (thisDrawable.mLayerState.mChildren[i] == null) {
-                continue;
-            }
-            final Drawable dr = thisDrawable.mLayerState.mChildren[i].mDrawable;
-            if (dr != null) {
-                dr.draw(canvas);
-            }
-        }
-
-        if (thisDrawable.mMaskBitmap != null) {
-            Rect bounds = thisDrawable.getBounds();
-            Paint paint = new Paint();
-            paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
-            canvas.drawBitmap(thisDrawable.mMaskBitmap, bounds.left, bounds.top, paint);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 4689491..ffbe7c4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -18,12 +18,12 @@
 
 import com.android.internal.os.IResultReceiver;
 
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.util.MergedConfiguration;
 import android.view.DragEvent;
 import android.view.IWindow;
 
@@ -50,7 +50,7 @@
 
     @Override
     public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
-            boolean b, Configuration configuration, Rect rect7, boolean b2, boolean b3, int i0)
+            boolean b, MergedConfiguration mergedConfig, Rect rect7, boolean b2, boolean b3, int i0)
             throws RemoteException {
         // pass for now.
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 4dfe47b..2c88394 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -17,12 +17,12 @@
 package com.android.layoutlib.bridge.android;
 
 import android.content.ClipData;
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.util.MergedConfiguration;
 import android.view.IWindow;
 import android.view.IWindowId;
 import android.view.IWindowSession;
@@ -89,7 +89,7 @@
     @Override
     public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
             int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
-            Rect rect6, Rect rect7, Configuration configuration, Surface surface)
+            Rect rect6, Rect rect7, MergedConfiguration mergedConfig, Surface surface)
             throws RemoteException {
         // pass for now.
         return 0;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 4f226cb..b0aa3c2 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -163,7 +163,6 @@
         "android.content.res.TypedArray#obtain",
         "android.graphics.BitmapFactory#finishDecode",
         "android.graphics.BitmapFactory#setDensityFromOptions",
-        "android.graphics.drawable.AdaptiveIconDrawable#draw",
         "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
         "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw",
         "android.graphics.drawable.GradientDrawable#buildRing",
@@ -333,8 +332,6 @@
      * needed when access from the delegate classes is needed.
      */
     private final static String[] PROMOTED_FIELDS = new String[] {
-        "android.graphics.drawable.AdaptiveIconDrawable#mMaskBitmap",
-        "android.graphics.drawable.AdaptiveIconDrawable#mPaint",
         "android.graphics.drawable.VectorDrawable#mVectorState",
         "android.view.Choreographer#mLastFrameTimeNanos",
         "android.graphics.FontFamily#mBuilderPtr"
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index a1099f8..04f9059 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -281,7 +281,9 @@
     public int apChannel = 0;
 
     /**
-     * Pre-shared key for use with WPA-PSK.
+     * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in
+     * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or
+     * a string of 64 hex digits for raw PSK.
      * <p/>
      * When the value of this key is read, the actual key is
      * not returned, just a "*" if the key has a value, or the null
@@ -305,7 +307,7 @@
     /**
      * Priority determines the preference given to a network by {@code wpa_supplicant}
      * when choosing an access point with which to associate.
-     * @deprecated Priority is no longer used.
+     * @deprecated This field does not exist anymore.
      */
     @Deprecated
     public int priority;
@@ -434,6 +436,13 @@
     public int dtimInterval = 0;
 
     /**
+     * Flag indicating if this configuration represents a legacy Passpoint configuration
+     * (Release N or older).  This is used for migrating Passpoint configuration from N to O.
+     * This will no longer be needed after O.
+     * @hide
+     */
+    public boolean isLegacyPasspointConfig = false;
+    /**
      * @hide
      * Uid of app creating the configuration
      */
@@ -1961,6 +1970,7 @@
             mCachedConfigKey = null; //force null configKey
             selfAdded = source.selfAdded;
             validatedInternetAccess = source.validatedInternetAccess;
+            isLegacyPasspointConfig = source.isLegacyPasspointConfig;
             ephemeral = source.ephemeral;
             meteredHint = source.meteredHint;
             meteredOverride = source.meteredOverride;
@@ -2037,6 +2047,7 @@
         dest.writeInt(selfAdded ? 1 : 0);
         dest.writeInt(didSelfAdd ? 1 : 0);
         dest.writeInt(validatedInternetAccess ? 1 : 0);
+        dest.writeInt(isLegacyPasspointConfig ? 1 : 0);
         dest.writeInt(ephemeral ? 1 : 0);
         dest.writeInt(meteredHint ? 1 : 0);
         dest.writeInt(meteredOverride ? 1 : 0);
@@ -2103,6 +2114,7 @@
                 config.selfAdded = in.readInt() != 0;
                 config.didSelfAdd = in.readInt() != 0;
                 config.validatedInternetAccess = in.readInt() != 0;
+                config.isLegacyPasspointConfig = in.readInt() != 0;
                 config.ephemeral = in.readInt() != 0;
                 config.meteredHint = in.readInt() != 0;
                 config.meteredOverride = in.readInt() != 0;
diff --git a/wifi/tests/Android.mk b/wifi/tests/Android.mk
index eac49d2..8dc244f 100644
--- a/wifi/tests/Android.mk
+++ b/wifi/tests/Android.mk
@@ -58,5 +58,6 @@
 	android.test.runner \
 
 LOCAL_PACKAGE_NAME := FrameworksWifiApiTests
+LOCAL_COMPATIBILITY_SUITE := device-tests
 
 include $(BUILD_PACKAGE)