Merge "Ensuring that isPictureInPictureMode() mirrors dispatched mode." into oc-dev
diff --git a/Android.mk b/Android.mk
index 991d185..28d1d64 100644
--- a/Android.mk
+++ b/Android.mk
@@ -908,7 +908,6 @@
 	ext \
 	icu4j \
 	framework \
-	telephony-common \
 	voip-common
 
 framework_docs_LOCAL_JAVA_LIBRARIES := \
@@ -923,6 +922,7 @@
 # Conscrypt (com.android.org.conscrypt) is an implementation detail and should
 # not be referenced in the documentation.
 framework_docs_LOCAL_DROIDDOC_OPTIONS := \
+    -android \
     -knowntags ./frameworks/base/docs/knowntags.txt \
     -knowntags ./libcore/known_oj_tags.txt \
     -hidePackage com.android.org.conscrypt \
@@ -952,8 +952,8 @@
     -since $(SRC_API_DIR)/24.txt 24 \
     -since $(SRC_API_DIR)/25.txt 25 \
     -since ./frameworks/base/api/current.txt O \
-		-werror -hide 111 -hide 113 \
-		-overview $(LOCAL_PATH)/core/java/overview.html
+    -werror -hide 111 -hide 113 -hide 121 \
+    -overview $(LOCAL_PATH)/core/java/overview.html \
 
 # Allow the support library to add its own droiddoc options.
 include $(LOCAL_PATH)/../support/droiddoc.mk
diff --git a/api/current.txt b/api/current.txt
index f1be178..0fbb51b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -362,7 +362,7 @@
     field public static final int canControlMagnification = 16844039; // 0x1010507
     field public static final int canPerformGestures = 16844045; // 0x101050d
     field public static final int canRecord = 16844060; // 0x101051c
-    field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
+    field public static final deprecated int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
@@ -2837,7 +2837,7 @@
     field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
     field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
     field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
-    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final deprecated int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
     field public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 8; // 0x8
     field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
     field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
@@ -2855,7 +2855,7 @@
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
     field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
     field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
-    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final deprecated int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 64; // 0x40
@@ -3635,7 +3635,6 @@
     method public boolean isInMultiWindowMode();
     method public boolean isInPictureInPictureMode();
     method public boolean isLocalVoiceInteractionSupported();
-    method public boolean isOverlayWithDecorCaptionEnabled();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3760,7 +3759,6 @@
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setMediaController(android.media.session.MediaController);
-    method public void setOverlayWithDecorCaptionEnabled(boolean);
     method public void setPictureInPictureArgs(android.app.PictureInPictureArgs);
     method public final deprecated void setProgress(int);
     method public final deprecated void setProgressBarIndeterminate(boolean);
@@ -5125,6 +5123,7 @@
     method public int getBadgeIconType();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
+    method public int getGroupAlertBehavior();
     method public android.graphics.drawable.Icon getLargeIcon();
     method public java.lang.CharSequence getSettingsText();
     method public java.lang.String getShortcutId();
@@ -5200,6 +5199,9 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final deprecated int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
     field public static final java.lang.String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final deprecated int PRIORITY_DEFAULT = 0; // 0x0
     field public static final deprecated int PRIORITY_HIGH = 1; // 0x1
@@ -5346,6 +5348,7 @@
     method public android.app.Notification.Builder setExtras(android.os.Bundle);
     method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method public android.app.Notification.Builder setGroup(java.lang.String);
+    method public android.app.Notification.Builder setGroupAlertBehavior(int);
     method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
@@ -6660,8 +6663,8 @@
     method public int getTextStyle();
     method public int getTop();
     method public android.graphics.Matrix getTransformation();
-    method public java.lang.String getUrl();
     method public int getVisibility();
+    method public java.lang.String getWebDomain();
     method public int getWidth();
     method public boolean isAccessibilityFocused();
     method public boolean isActivated();
@@ -8934,7 +8937,7 @@
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
-    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
+    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companiondevice";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
     field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -13779,7 +13782,6 @@
   }
 
   public class Typeface {
-    method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
     method public static android.graphics.Typeface create(java.lang.String, int);
     method public static android.graphics.Typeface create(android.graphics.Typeface, int);
     method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -13814,17 +13816,6 @@
     method public android.graphics.Typeface.Builder setWeight(int);
   }
 
-  public static abstract deprecated interface Typeface.FontRequestCallback {
-    method public abstract void onTypefaceRequestFailed(int);
-    method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
-    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
-  }
-
   public class Xfermode {
     ctor public Xfermode();
   }
@@ -23646,7 +23637,7 @@
 
   public static final class VolumeShaper.Configuration implements android.os.Parcelable {
     method public int describeContents();
-    method public double getDurationMillis();
+    method public long getDuration();
     method public int getInterpolatorType();
     method public static int getMaximumCurvePoints();
     method public float[] getTimes();
@@ -23672,7 +23663,7 @@
     method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
-    method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
+    method public android.media.VolumeShaper.Configuration.Builder setDuration(long);
     method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
   }
 
@@ -26740,10 +26731,10 @@
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
   }
 
-  public class DiscoverySession {
+  public class DiscoverySession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
-    method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
 
@@ -26795,8 +26786,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
-    field public static final int MATCH_STYLE_ALL = 1; // 0x1
-    field public static final int MATCH_STYLE_FIRST_ONLY = 0; // 0x0
     field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
     field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
   }
@@ -26805,7 +26794,6 @@
     ctor public SubscribeConfig.Builder();
     method public android.net.wifi.aware.SubscribeConfig build();
     method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(java.util.List<byte[]>);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
     method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
@@ -26827,10 +26815,10 @@
     field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
   }
 
-  public class WifiAwareSession {
+  public class WifiAwareSession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
-    method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
   }
@@ -34945,6 +34933,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_REQUEST_SET_AUTOFILL_SERVICE = "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -37036,15 +37025,12 @@
 
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
-    method public final deprecated void disableSelf();
     method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
-    method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
-    method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
+    method public abstract void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
+    method public abstract void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
@@ -37118,7 +37104,6 @@
     method public android.service.autofill.FillResponse build();
     method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
-    method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -40240,10 +40225,12 @@
     method public void sendDialerSpecialCode(java.lang.String);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
+    method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
     method public void setDataEnabled(boolean);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
+    method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
@@ -40334,8 +40321,6 @@
     method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
     method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
     method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
-    method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
-    method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
   }
 
@@ -46592,8 +46577,9 @@
     method public abstract void setTextLines(int[], int[]);
     method public abstract void setTextStyle(float, int, int, int);
     method public abstract void setTransformation(android.graphics.Matrix);
-    method public abstract void setUrl(java.lang.String);
+    method public abstract deprecated void setUrl(java.lang.String);
     method public abstract void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -47156,7 +47142,9 @@
 
   public final class AccessibilityManager {
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
+    method public void addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
+    method public void addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler);
     method public deprecated java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
@@ -47837,6 +47825,8 @@
     method public void cancel();
     method public void commit();
     method public void disableOwnedAutofillServices();
+    method public boolean hasEnabledAutofillServices();
+    method public boolean isAutofillSupported();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
     method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
@@ -47851,7 +47841,6 @@
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
     field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
-    field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
   public static abstract class AutofillManager.AutofillCallback {
diff --git a/api/removed.txt b/api/removed.txt
index dc9c54e..c132385 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,7 +1,6 @@
 package android.app {
 
   public class Notification implements android.os.Parcelable {
-    method public deprecated int getBadgeIcon();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
@@ -351,10 +350,6 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
-  public static final class FontsContract.Columns implements android.provider.BaseColumns {
-    field public static final java.lang.String STYLE = "font_style";
-  }
-
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 4f26fad..be1887d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -174,6 +174,7 @@
     field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
     field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
     field public static final java.lang.String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
+    field public static final java.lang.String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
     field public static final java.lang.String READ_CALENDAR = "android.permission.READ_CALENDAR";
     field public static final java.lang.String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
@@ -480,7 +481,7 @@
     field public static final int canControlMagnification = 16844039; // 0x1010507
     field public static final int canPerformGestures = 16844045; // 0x101050d
     field public static final int canRecord = 16844060; // 0x101051c
-    field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
+    field public static final deprecated int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
@@ -2964,7 +2965,7 @@
     field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
     field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
     field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
-    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final deprecated int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
     field public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 8; // 0x8
     field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
     field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
@@ -2982,7 +2983,7 @@
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
     field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
     field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
-    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final deprecated int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 64; // 0x40
@@ -3766,7 +3767,6 @@
     method public boolean isInMultiWindowMode();
     method public boolean isInPictureInPictureMode();
     method public boolean isLocalVoiceInteractionSupported();
-    method public boolean isOverlayWithDecorCaptionEnabled();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3893,7 +3893,6 @@
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setMediaController(android.media.session.MediaController);
-    method public void setOverlayWithDecorCaptionEnabled(boolean);
     method public void setPictureInPictureArgs(android.app.PictureInPictureArgs);
     method public final deprecated void setProgress(int);
     method public final deprecated void setProgressBarIndeterminate(boolean);
@@ -5304,6 +5303,7 @@
     method public int getBadgeIconType();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
+    method public int getGroupAlertBehavior();
     method public android.graphics.drawable.Icon getLargeIcon();
     method public static java.lang.Class<? extends android.app.Notification.Style> getNotificationStyleClass(java.lang.String);
     method public java.lang.CharSequence getSettingsText();
@@ -5383,6 +5383,9 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final deprecated int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
     field public static final java.lang.String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final deprecated int PRIORITY_DEFAULT = 0; // 0x0
     field public static final deprecated int PRIORITY_HIGH = 1; // 0x1
@@ -5529,6 +5532,7 @@
     method public android.app.Notification.Builder setExtras(android.os.Bundle);
     method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method public android.app.Notification.Builder setGroup(java.lang.String);
+    method public android.app.Notification.Builder setGroupAlertBehavior(int);
     method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
@@ -6905,8 +6909,8 @@
     method public int getTextStyle();
     method public int getTop();
     method public android.graphics.Matrix getTransformation();
-    method public java.lang.String getUrl();
     method public int getVisibility();
+    method public java.lang.String getWebDomain();
     method public int getWidth();
     method public boolean isAccessibilityFocused();
     method public boolean isActivated();
@@ -9438,7 +9442,7 @@
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
-    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
+    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companiondevice";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
     field public static final java.lang.String CONTEXTHUB_SERVICE = "contexthub";
@@ -14553,7 +14557,6 @@
   }
 
   public class Typeface {
-    method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
     method public static android.graphics.Typeface create(java.lang.String, int);
     method public static android.graphics.Typeface create(android.graphics.Typeface, int);
     method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -14588,17 +14591,6 @@
     method public android.graphics.Typeface.Builder setWeight(int);
   }
 
-  public static abstract deprecated interface Typeface.FontRequestCallback {
-    method public abstract void onTypefaceRequestFailed(int);
-    method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
-    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
-  }
-
   public class Xfermode {
     ctor public Xfermode();
   }
@@ -25493,7 +25485,7 @@
 
   public static final class VolumeShaper.Configuration implements android.os.Parcelable {
     method public int describeContents();
-    method public double getDurationMillis();
+    method public long getDuration();
     method public int getInterpolatorType();
     method public static int getMaximumCurvePoints();
     method public float[] getTimes();
@@ -25519,7 +25511,7 @@
     method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
-    method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
+    method public android.media.VolumeShaper.Configuration.Builder setDuration(long);
     method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
   }
 
@@ -27967,13 +27959,13 @@
     ctor public deprecated NetworkRecommendationProvider(android.os.Handler);
     ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor);
     method public final android.os.IBinder getBinder();
-    method public abstract void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
+    method public deprecated void onRequestRecommendation(android.net.RecommendationRequest, android.net.NetworkRecommendationProvider.ResultCallback);
     method public abstract void onRequestScores(android.net.NetworkKey[]);
-    field public static final java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
-    field public static final java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
+    field public static final deprecated java.lang.String EXTRA_RECOMMENDATION_RESULT = "android.net.extra.RECOMMENDATION_RESULT";
+    field public static final deprecated java.lang.String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
   }
 
-  public static class NetworkRecommendationProvider.ResultCallback {
+  public static deprecated class NetworkRecommendationProvider.ResultCallback {
     method public void onResult(android.net.RecommendationResult);
   }
 
@@ -28040,7 +28032,7 @@
     field public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
   }
 
-  public final class RecommendationRequest implements android.os.Parcelable {
+  public final deprecated class RecommendationRequest implements android.os.Parcelable {
     ctor protected RecommendationRequest(android.os.Parcel);
     method public int describeContents();
     method public android.net.wifi.WifiConfiguration[] getConnectableConfigs();
@@ -28055,7 +28047,7 @@
     field public static final android.os.Parcelable.Creator<android.net.RecommendationRequest> CREATOR;
   }
 
-  public static final class RecommendationRequest.Builder {
+  public static final deprecated class RecommendationRequest.Builder {
     ctor public RecommendationRequest.Builder();
     method public android.net.RecommendationRequest build();
     method public android.net.RecommendationRequest.Builder setConnectableConfigs(android.net.wifi.WifiConfiguration[]);
@@ -28065,7 +28057,7 @@
     method public android.net.RecommendationRequest.Builder setScanResults(android.net.wifi.ScanResult[]);
   }
 
-  public final class RecommendationResult implements android.os.Parcelable {
+  public final deprecated class RecommendationResult implements android.os.Parcelable {
     method public static android.net.RecommendationResult createConnectRecommendation(android.net.wifi.WifiConfiguration);
     method public static android.net.RecommendationResult createDoNotConnectRecommendation();
     method public int describeContents();
@@ -29483,11 +29475,11 @@
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
   }
 
-  public class DiscoverySession {
+  public class DiscoverySession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
     method public android.net.NetworkSpecifier createNetworkSpecifierPmk(android.net.wifi.aware.PeerHandle, byte[]);
-    method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
 
@@ -29539,8 +29531,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
-    field public static final int MATCH_STYLE_ALL = 1; // 0x1
-    field public static final int MATCH_STYLE_FIRST_ONLY = 0; // 0x0
     field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
     field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
   }
@@ -29549,7 +29539,6 @@
     ctor public SubscribeConfig.Builder();
     method public android.net.wifi.aware.SubscribeConfig build();
     method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(java.util.List<byte[]>);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
     method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
@@ -29571,11 +29560,11 @@
     field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
   }
 
-  public class WifiAwareSession {
+  public class WifiAwareSession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
     method public android.net.NetworkSpecifier createNetworkSpecifierPmk(int, byte[], byte[]);
-    method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
   }
@@ -38037,6 +38026,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_REQUEST_SET_AUTOFILL_SERVICE = "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -38097,7 +38087,6 @@
     field public static final java.lang.String BOOT_COUNT = "boot_count";
     field public static final java.lang.String CONTACT_METADATA_SYNC_ENABLED = "contact_metadata_sync_enabled";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String CURATE_SAVED_OPEN_NETWORKS = "curate_saved_open_networks";
     field public static final java.lang.String DATA_ROAMING = "data_roaming";
     field public static final java.lang.String DEBUG_APP = "debug_app";
     field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
@@ -40151,15 +40140,12 @@
 
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
-    method public final deprecated void disableSelf();
     method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
-    method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
-    method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
+    method public abstract void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
+    method public abstract void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
@@ -40233,7 +40219,6 @@
     method public android.service.autofill.FillResponse build();
     method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
-    method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -40769,6 +40754,7 @@
     method public void onPredictSharingProbabilities(java.util.List<android.service.resolver.ResolverTarget>);
     method public void onTrainRankingModel(java.util.List<android.service.resolver.ResolverTarget>, int);
     field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
+    field public static final java.lang.String HOLD_PERMISSION = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
   }
 
@@ -43733,6 +43719,7 @@
     method public java.lang.String getSubscriberId();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
     method public java.lang.String getVisualVoicemailPackageName();
+    method public android.os.Bundle getVisualVoicemailSettings();
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public int getVoiceNetworkType();
@@ -43768,6 +43755,7 @@
     method public void sendDialerSpecialCode(java.lang.String);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
+    method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method public void setDataEnabled(boolean);
     method public void setDataEnabled(int, boolean);
@@ -43777,6 +43765,7 @@
     method public boolean setRadio(boolean);
     method public boolean setRadioPower(boolean);
     method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
@@ -43824,7 +43813,9 @@
     field public static final java.lang.String EXTRA_STATE_IDLE;
     field public static final java.lang.String EXTRA_STATE_OFFHOOK;
     field public static final java.lang.String EXTRA_STATE_RINGING;
+    field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final java.lang.String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER";
+    field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
     field public static final java.lang.String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU";
     field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
     field public static final int NETWORK_TYPE_CDMA = 4; // 0x4
@@ -50170,8 +50161,9 @@
     method public abstract void setTextLines(int[], int[]);
     method public abstract void setTextStyle(float, int, int, int);
     method public abstract void setTransformation(android.graphics.Matrix);
-    method public abstract void setUrl(java.lang.String);
+    method public abstract deprecated void setUrl(java.lang.String);
     method public abstract void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -50737,7 +50729,9 @@
 
   public final class AccessibilityManager {
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
+    method public void addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
+    method public void addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler);
     method public deprecated java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
@@ -51418,6 +51412,8 @@
     method public void cancel();
     method public void commit();
     method public void disableOwnedAutofillServices();
+    method public boolean hasEnabledAutofillServices();
+    method public boolean isAutofillSupported();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
     method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
@@ -51432,7 +51428,6 @@
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
     field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
-    field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
   public static abstract class AutofillManager.AutofillCallback {
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 4862bb7..039cd74 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -1,7 +1,6 @@
 package android.app {
 
   public class Notification implements android.os.Parcelable {
-    method public deprecated int getBadgeIcon();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
@@ -345,10 +344,6 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
-  public static final class FontsContract.Columns implements android.provider.BaseColumns {
-    field public static final java.lang.String STYLE = "font_style";
-  }
-
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 7769446..51314c9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -362,7 +362,7 @@
     field public static final int canControlMagnification = 16844039; // 0x1010507
     field public static final int canPerformGestures = 16844045; // 0x101050d
     field public static final int canRecord = 16844060; // 0x101051c
-    field public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
+    field public static final deprecated int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
     field public static final int canRequestFilterKeyEvents = 16843737; // 0x10103d9
     field public static final int canRequestTouchExplorationMode = 16843735; // 0x10103d7
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
@@ -2837,7 +2837,7 @@
     field public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 64; // 0x40
     field public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 16; // 0x10
     field public static final int CAPABILITY_CAN_PERFORM_GESTURES = 32; // 0x20
-    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final deprecated int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
     field public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 8; // 0x8
     field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
     field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
@@ -2855,7 +2855,7 @@
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
     field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
     field public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 256; // 0x100
-    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final deprecated int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 64; // 0x40
@@ -3637,7 +3637,6 @@
     method public boolean isInMultiWindowMode();
     method public boolean isInPictureInPictureMode();
     method public boolean isLocalVoiceInteractionSupported();
-    method public boolean isOverlayWithDecorCaptionEnabled();
     method public boolean isTaskRoot();
     method public boolean isVoiceInteraction();
     method public boolean isVoiceInteractionRoot();
@@ -3762,7 +3761,6 @@
     method public void setImmersive(boolean);
     method public void setIntent(android.content.Intent);
     method public final void setMediaController(android.media.session.MediaController);
-    method public void setOverlayWithDecorCaptionEnabled(boolean);
     method public void setPictureInPictureArgs(android.app.PictureInPictureArgs);
     method public final deprecated void setProgress(int);
     method public final deprecated void setProgressBarIndeterminate(boolean);
@@ -5138,6 +5136,7 @@
     method public int getBadgeIconType();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
+    method public int getGroupAlertBehavior();
     method public android.graphics.drawable.Icon getLargeIcon();
     method public java.lang.CharSequence getSettingsText();
     method public java.lang.String getShortcutId();
@@ -5213,6 +5212,9 @@
     field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
     field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
     field public static final deprecated int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
     field public static final java.lang.String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
     field public static final deprecated int PRIORITY_DEFAULT = 0; // 0x0
     field public static final deprecated int PRIORITY_HIGH = 1; // 0x1
@@ -5359,6 +5361,7 @@
     method public android.app.Notification.Builder setExtras(android.os.Bundle);
     method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method public android.app.Notification.Builder setGroup(java.lang.String);
+    method public android.app.Notification.Builder setGroupAlertBehavior(int);
     method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
@@ -6690,8 +6693,8 @@
     method public int getTextStyle();
     method public int getTop();
     method public android.graphics.Matrix getTransformation();
-    method public java.lang.String getUrl();
     method public int getVisibility();
+    method public java.lang.String getWebDomain();
     method public int getWidth();
     method public boolean isAccessibilityFocused();
     method public boolean isActivated();
@@ -8967,7 +8970,7 @@
     field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CARRIER_CONFIG_SERVICE = "carrier_config";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
-    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companion_device";
+    field public static final java.lang.String COMPANION_DEVICE_SERVICE = "companiondevice";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
     field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
     field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -13821,7 +13824,6 @@
   }
 
   public class Typeface {
-    method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback);
     method public static android.graphics.Typeface create(java.lang.String, int);
     method public static android.graphics.Typeface create(android.graphics.Typeface, int);
     method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String);
@@ -13856,17 +13858,6 @@
     method public android.graphics.Typeface.Builder setWeight(int);
   }
 
-  public static abstract deprecated interface Typeface.FontRequestCallback {
-    method public abstract void onTypefaceRequestFailed(int);
-    method public abstract void onTypefaceRetrieved(android.graphics.Typeface);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
-    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
-  }
-
   public class Xfermode {
     ctor public Xfermode();
   }
@@ -23754,7 +23745,7 @@
 
   public static final class VolumeShaper.Configuration implements android.os.Parcelable {
     method public int describeContents();
-    method public double getDurationMillis();
+    method public long getDuration();
     method public int getInterpolatorType();
     method public static int getMaximumCurvePoints();
     method public float[] getTimes();
@@ -23780,7 +23771,7 @@
     method public android.media.VolumeShaper.Configuration.Builder scaleToEndVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder scaleToStartVolume(float);
     method public android.media.VolumeShaper.Configuration.Builder setCurve(float[], float[]);
-    method public android.media.VolumeShaper.Configuration.Builder setDurationMillis(double);
+    method public android.media.VolumeShaper.Configuration.Builder setDuration(long);
     method public android.media.VolumeShaper.Configuration.Builder setInterpolatorType(int);
   }
 
@@ -26848,10 +26839,10 @@
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.Characteristics> CREATOR;
   }
 
-  public class DiscoverySession {
+  public class DiscoverySession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(android.net.wifi.aware.PeerHandle);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(android.net.wifi.aware.PeerHandle, java.lang.String);
-    method public void destroy();
     method public void sendMessage(android.net.wifi.aware.PeerHandle, int, byte[]);
   }
 
@@ -26903,8 +26894,6 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.wifi.aware.SubscribeConfig> CREATOR;
-    field public static final int MATCH_STYLE_ALL = 1; // 0x1
-    field public static final int MATCH_STYLE_FIRST_ONLY = 0; // 0x0
     field public static final int SUBSCRIBE_TYPE_ACTIVE = 1; // 0x1
     field public static final int SUBSCRIBE_TYPE_PASSIVE = 0; // 0x0
   }
@@ -26913,7 +26902,6 @@
     ctor public SubscribeConfig.Builder();
     method public android.net.wifi.aware.SubscribeConfig build();
     method public android.net.wifi.aware.SubscribeConfig.Builder setMatchFilter(java.util.List<byte[]>);
-    method public android.net.wifi.aware.SubscribeConfig.Builder setMatchStyle(int);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceName(java.lang.String);
     method public android.net.wifi.aware.SubscribeConfig.Builder setServiceSpecificInfo(byte[]);
     method public android.net.wifi.aware.SubscribeConfig.Builder setSubscribeType(int);
@@ -26935,10 +26923,10 @@
     field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
   }
 
-  public class WifiAwareSession {
+  public class WifiAwareSession implements java.lang.AutoCloseable {
+    method public void close();
     method public android.net.NetworkSpecifier createNetworkSpecifierOpen(int, byte[]);
     method public android.net.NetworkSpecifier createNetworkSpecifierPassphrase(int, byte[], java.lang.String);
-    method public void destroy();
     method public void publish(android.net.wifi.aware.PublishConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
     method public void subscribe(android.net.wifi.aware.SubscribeConfig, android.net.wifi.aware.DiscoverySessionCallback, android.os.Handler);
   }
@@ -35082,6 +35070,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_REQUEST_SET_AUTOFILL_SERVICE = "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -37190,15 +37179,12 @@
 
   public abstract class AutofillService extends android.app.Service {
     ctor public AutofillService();
-    method public final deprecated void disableSelf();
     method public final android.service.autofill.FillEventHistory getFillEventHistory();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
     method public void onDisconnected();
-    method public void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public abstract deprecated void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, int, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
-    method public abstract deprecated void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
+    method public abstract void onFillRequest(android.service.autofill.FillRequest, android.os.CancellationSignal, android.service.autofill.FillCallback);
+    method public abstract void onSaveRequest(android.service.autofill.SaveRequest, android.service.autofill.SaveCallback);
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
     field public static final java.lang.String SERVICE_META_DATA = "android.autofill";
   }
@@ -37272,7 +37258,6 @@
     method public android.service.autofill.FillResponse build();
     method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
-    method public deprecated android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -40435,10 +40420,12 @@
     method public void sendDialerSpecialCode(java.lang.String);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
     method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
+    method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
     method public void setDataEnabled(boolean);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
+    method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
@@ -40529,8 +40516,6 @@
     method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
     method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
     method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
-    method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
-    method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
     field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
   }
 
@@ -46967,8 +46952,9 @@
     method public abstract void setTextLines(int[], int[]);
     method public abstract void setTextStyle(float, int, int, int);
     method public abstract void setTransformation(android.graphics.Matrix);
-    method public abstract void setUrl(java.lang.String);
+    method public abstract deprecated void setUrl(java.lang.String);
     method public abstract void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -47533,7 +47519,9 @@
 
   public final class AccessibilityManager {
     method public boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener);
+    method public void addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener, android.os.Handler);
     method public boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener);
+    method public void addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener, android.os.Handler);
     method public deprecated java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
     method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
@@ -48216,6 +48204,8 @@
     method public void cancel();
     method public void commit();
     method public void disableOwnedAutofillServices();
+    method public boolean hasEnabledAutofillServices();
+    method public boolean isAutofillSupported();
     method public boolean isEnabled();
     method public void notifyValueChanged(android.view.View);
     method public void notifyValueChanged(android.view.View, int, android.view.autofill.AutofillValue);
@@ -48230,7 +48220,6 @@
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
     field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
-    field public static final deprecated int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
   public static abstract class AutofillManager.AutofillCallback {
diff --git a/api/test-removed.txt b/api/test-removed.txt
index dc9c54e..c132385 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -1,7 +1,6 @@
 package android.app {
 
   public class Notification implements android.os.Parcelable {
-    method public deprecated int getBadgeIcon();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
@@ -351,10 +350,6 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
-  public static final class FontsContract.Columns implements android.provider.BaseColumns {
-    field public static final java.lang.String STYLE = "font_style";
-  }
-
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index 3fb40fb..bf97bba 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -16,6 +16,7 @@
 
 package com.android.commands.vr;
 
+import android.app.CompatibilityDisplayProperties;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -36,7 +37,10 @@
       (new Vr()).run(args);
     }
 
-    private static final String COMMAND_SET_PERSISTENT_VR_MODE_ENABLED = "set-persistent-vr-mode-enabled";
+    private static final String COMMAND_SET_PERSISTENT_VR_MODE_ENABLED =
+        "set-persistent-vr-mode-enabled";
+    private static final String COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES =
+        "set-display-props";
 
     private IVrManager mVrService;
 
@@ -44,7 +48,8 @@
     public void onShowUsage(PrintStream out) {
         out.println(
                 "usage: vr [subcommand]\n" +
-                "usage: vr set-persistent-vr-mode-enabled [true|false]\n"
+                "usage: vr set-persistent-vr-mode-enabled [true|false]\n" +
+                "usage: vr set-display-props [width] [height] [dpi]\n"
                 );
     }
 
@@ -58,6 +63,9 @@
 
         String command = nextArgRequired();
         switch (command) {
+            case COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES:
+                runSetCompatibilityDisplayProperties();
+                break;
             case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
                 runSetPersistentVrModeEnabled();
                 break;
@@ -66,6 +74,26 @@
         }
     }
 
+    private void runSetCompatibilityDisplayProperties() throws RemoteException {
+        String widthStr = nextArgRequired();
+        int width = Integer.parseInt(widthStr);
+
+        String heightStr = nextArgRequired();
+        int height = Integer.parseInt(heightStr);
+
+        String dpiStr = nextArgRequired();
+        int dpi = Integer.parseInt(dpiStr);
+
+        CompatibilityDisplayProperties compatDisplayProperties =
+                new CompatibilityDisplayProperties(width, height, dpi);
+
+        try {
+            mVrService.setCompatibilityDisplayProperties(compatDisplayProperties);
+        } catch (RemoteException re) {
+            System.err.println("Error: Can't set persistent mode " + re);
+        }
+    }
+
     private void runSetPersistentVrModeEnabled() throws RemoteException {
         String enableStr = nextArg();
         boolean enabled = Boolean.parseBoolean(enableStr);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 5937dd9..3cda489 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -95,9 +95,7 @@
     public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
 
     /**
-     * Capability: This accessibility service can request enhanced web accessibility
-     * enhancements. For example, installing scripts to make app content more accessible.
-     * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
+     * @deprecated No longer used
      */
     public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
 
@@ -237,22 +235,7 @@
     public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
 
     /**
-     * This flag requests from the system to enable web accessibility enhancing
-     * extensions. Such extensions aim to provide improved accessibility support
-     * for content presented in a {@link android.webkit.WebView}. An example of such
-     * an extension is injecting JavaScript from a secure source. The system will enable
-     * enhanced web accessibility if there is at least one accessibility service
-     * that has this flag set. Hence, clearing this flag does not guarantee that the
-     * device will not have enhanced web accessibility enabled since there may be
-     * another enabled service that requested it.
-     * <p>
-     * Services that want to set this flag have to declare this capability
-     * in their meta-data by setting the attribute {@link android.R.attr
-     * #canRequestEnhancedWebAccessibility canRequestEnhancedWebAccessibility} to
-     * true, otherwise this flag will be ignored. For how to declare the meta-data
-     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
-     * </p>
-     * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
+     * @deprecated No longer used
      */
     public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
 
@@ -526,10 +509,6 @@
                 mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
             }
             if (asAttributes.getBoolean(com.android.internal.R.styleable
-                        .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
-                    mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
-            }
-            if (asAttributes.getBoolean(com.android.internal.R.styleable
                     .AccessibilityService_canRequestFilterKeyEvents, false)) {
                 mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
             }
@@ -659,7 +638,6 @@
      *
      * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
      * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
-     * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
      * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
      * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
      * @see #CAPABILITY_CAN_PERFORM_GESTURES
@@ -676,7 +654,6 @@
      *
      * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
      * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
-     * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
      * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
      * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
      * @see #CAPABILITY_CAN_PERFORM_GESTURES
@@ -1074,10 +1051,6 @@
                     new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
                             R.string.capability_title_canRequestTouchExploration,
                             R.string.capability_desc_canRequestTouchExploration));
-            sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
-                    new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
-                            R.string.capability_title_canRequestEnhancedWebAccessibility,
-                            R.string.capability_desc_canRequestEnhancedWebAccessibility));
             sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
                     new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
                             R.string.capability_title_canRequestFilterKeyEvents,
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index b320d5d..06b09c0 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -345,7 +345,13 @@
         "android.accounts.LOGIN_ACCOUNTS_CHANGED";
 
     /**
-     * Action sent as a broadcast Intent by the AccountsService when any account is removed.
+     * Action sent as a broadcast Intent by the AccountsService when any account is removed
+     * or renamed. Only applications which were able to see the account will receive the intent.
+     * Intent extra will include the following fields:
+     * <ul>
+     * <li> {@link #KEY_ACCOUNT_NAME} - the name of the removed account
+     * <li> {@link #KEY_ACCOUNT_TYPE} - the type of the account
+     * </ul>
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @BroadcastBehavior(includeBackground = true)
diff --git a/core/java/android/annotation/BroadcastBehavior.java b/core/java/android/annotation/BroadcastBehavior.java
index 9b2ca31..70d82cb 100644
--- a/core/java/android/annotation/BroadcastBehavior.java
+++ b/core/java/android/annotation/BroadcastBehavior.java
@@ -53,4 +53,9 @@
      * @see Intent#FLAG_RECEIVER_INCLUDE_BACKGROUND
      */
     boolean includeBackground() default false;
+
+    /**
+     * This broadcast is protected and can only be sent by the OS.
+     */
+    boolean protectedBroadcast() default false;
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 1b972f7..cdfb52b1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -696,9 +696,6 @@
     private static final String TAG = "Activity";
     private static final boolean DEBUG_LIFECYCLE = false;
 
-    // TODO(b/33197203): set to false once stable
-    private static final boolean DEBUG_AUTO_FILL = true;
-
     /** Standard activity result: operation canceled. */
     public static final int RESULT_CANCELED    = 0;
     /** Standard activity result: operation succeeded. */
@@ -5844,7 +5841,7 @@
      * @return Returns the single SharedPreferences instance that can be used
      *         to retrieve and modify the preference values.
      */
-    public SharedPreferences getPreferences(int mode) {
+    public SharedPreferences getPreferences(@Context.PreferencesMode int mode) {
         return getSharedPreferences(getLocalClassName(), mode);
     }
 
@@ -7323,6 +7320,7 @@
      * @return True if caption is displayed on content, false if it pushes the content down.
      *
      * @see #setOverlayWithDecorCaptionEnabled(boolean)
+     * @hide
      */
     public boolean isOverlayWithDecorCaptionEnabled() {
         return mWindow.isOverlayWithDecorCaptionEnabled();
@@ -7334,6 +7332,7 @@
      * This affects only freeform windows since they display the caption and only the main
      * window of the activity. The caption is used to drag the window around and also shows
      * maximize and close action buttons.
+     * @hide
      */
     public void setOverlayWithDecorCaptionEnabled(boolean enabled) {
         mWindow.setOverlayWithDecorCaptionEnabled(enabled);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 62f2144..1ab45b5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2350,6 +2350,14 @@
         }
     }
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "MOVE_TASK_" }, value = {
+            MOVE_TASK_WITH_HOME,
+            MOVE_TASK_NO_USER_ACTION,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MoveTaskFlags {}
+
     /**
      * Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
      * activity along with the task, so it is positioned immediately behind
@@ -2370,28 +2378,26 @@
      *
      * @param taskId The identifier of the task to be moved, as found in
      * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
-     * @param flags Additional operational flags, 0 or more of
-     * {@link #MOVE_TASK_WITH_HOME}, {@link #MOVE_TASK_NO_USER_ACTION}.
+     * @param flags Additional operational flags.
      */
-    public void moveTaskToFront(int taskId, int flags) {
+    @RequiresPermission(android.Manifest.permission.REORDER_TASKS)
+    public void moveTaskToFront(int taskId, @MoveTaskFlags int flags) {
         moveTaskToFront(taskId, flags, null);
     }
 
     /**
      * Ask that the task associated with a given task ID be moved to the
-     * front of the stack, so it is now visible to the user.  Requires that
-     * the caller hold permission {@link android.Manifest.permission#REORDER_TASKS}
-     * or a SecurityException will be thrown.
+     * front of the stack, so it is now visible to the user.
      *
      * @param taskId The identifier of the task to be moved, as found in
      * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
-     * @param flags Additional operational flags, 0 or more of
-     * {@link #MOVE_TASK_WITH_HOME}, {@link #MOVE_TASK_NO_USER_ACTION}.
+     * @param flags Additional operational flags.
      * @param options Additional options for the operation, either null or
      * as per {@link Context#startActivity(Intent, android.os.Bundle)
      * Context.startActivity(Intent, Bundle)}.
      */
-    public void moveTaskToFront(int taskId, int flags, Bundle options) {
+    @RequiresPermission(android.Manifest.permission.REORDER_TASKS)
+    public void moveTaskToFront(int taskId, @MoveTaskFlags int flags, Bundle options) {
         try {
             getService().moveTaskToFront(taskId, flags, options);
         } catch (RemoteException e) {
@@ -3637,13 +3643,10 @@
      * processes to reclaim memory; the system will take care of restarting
      * these processes in the future as needed.
      *
-     * <p>You must hold the permission
-     * {@link android.Manifest.permission#KILL_BACKGROUND_PROCESSES} to be able to
-     * call this method.
-     *
      * @param packageName The name of the package whose processes are to
      * be killed.
      */
+    @RequiresPermission(Manifest.permission.KILL_BACKGROUND_PROCESSES)
     public void killBackgroundProcesses(String packageName) {
         try {
             getService().killBackgroundProcesses(packageName,
@@ -4015,13 +4018,13 @@
      * Perform a system dump of various state associated with the given application
      * package name.  This call blocks while the dump is being performed, so should
      * not be done on a UI thread.  The data will be written to the given file
-     * descriptor as text.  An application must hold the
-     * {@link android.Manifest.permission#DUMP} permission to make this call.
+     * descriptor as text.
      * @param fd The file descriptor that the dump should be written to.  The file
      * descriptor is <em>not</em> closed by this function; the caller continues to
      * own it.
      * @param packageName The name of the package that is to be dumped.
      */
+    @RequiresPermission(Manifest.permission.DUMP)
     public void dumpPackageState(FileDescriptor fd, String packageName) {
         dumpPackageStateStatic(fd, packageName);
     }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5022d7d..195ba24 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -51,7 +51,6 @@
 import android.database.sqlite.SQLiteDebug.DbStats;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Typeface;
 import android.hardware.display.DisplayManagerGlobal;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
@@ -90,6 +89,7 @@
 import android.provider.CallLog;
 import android.provider.ContactsContract;
 import android.provider.Downloads;
+import android.provider.FontsContract;
 import android.provider.Settings;
 import android.security.NetworkSecurityPolicy;
 import android.security.net.config.NetworkSecurityConfigProvider;
@@ -3004,7 +3004,7 @@
         // - it needs an IAutoFillCallback
         boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL;
 
-        // TODO(b/33197203): decide if lastSessionId logic applies to autofill sessions
+        // TODO: decide if lastSessionId logic applies to autofill sessions
         if (mLastSessionId != cmd.sessionId) {
             // Clear the existing structures
             mLastSessionId = cmd.sessionId;
@@ -3032,8 +3032,6 @@
             if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) {
                 structure = new AssistStructure(r.activity, forAutofill);
                 Intent activityIntent = r.activity.getIntent();
-                // TODO(b/33197203): re-evaluate conditions below for autofill. In particular,
-                // FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE)
                 boolean notSecure = r.window == null ||
                         (r.window.getAttributes().flags
                                 & WindowManager.LayoutParams.FLAG_SECURE) == 0;
@@ -3059,7 +3057,7 @@
             structure = new AssistStructure();
         }
 
-        // TODO(b/33197203): decide if lastSessionId logic applies to autofill sessions
+        // TODO: decide if lastSessionId logic applies to autofill sessions
 
         structure.setAcquisitionStartTime(startTime);
         structure.setAcquisitionEndTime(SystemClock.uptimeMillis());
@@ -5795,7 +5793,7 @@
         }
 
         // Preload fonts resources
-        Typeface.setApplicationContext(appContext);
+        FontsContract.setApplicationContextForResources(appContext);
         try {
             final ApplicationInfo info =
                     getPackageManager().getApplicationInfo(
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index c561a19..3221c5d 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.content.Context;
@@ -34,6 +35,8 @@
 import libcore.util.ZoneInfoDB;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * This class provides access to the system alarm services.  These allow you
@@ -78,6 +81,16 @@
 public class AlarmManager {
     private static final String TAG = "AlarmManager";
 
+    /** @hide */
+    @IntDef(prefix = { "RTC", "ELAPSED" }, value = {
+            RTC_WAKEUP,
+            RTC,
+            ELAPSED_REALTIME_WAKEUP,
+            ELAPSED_REALTIME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AlarmType {}
+
     /**
      * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
      * (wall clock time in UTC), which will wake up the device when
@@ -311,8 +324,7 @@
      * will be treated as exact.
      * </div>
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should go
      * off, using the appropriate clock (depending on the alarm type).
      * @param operation Action to perform when the alarm goes off;
@@ -332,7 +344,7 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void set(int type, long triggerAtMillis, PendingIntent operation) {
+    public void set(@AlarmType int type, long triggerAtMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, legacyExactLength(), 0, 0, operation, null, null,
                 null, null, null);
     }
@@ -346,8 +358,7 @@
      * invoked via the specified target Handler, or on the application's main looper
      * if {@code null} is passed as the {@code targetHandler} parameter.
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *         {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should go
      *         off, using the appropriate clock (depending on the alarm type).
      * @param tag string describing the alarm, used for logging and battery-use
@@ -360,7 +371,7 @@
      * @param targetHandler {@link Handler} on which to execute the listener's onAlarm()
      *         callback, or {@code null} to run that callback on the main looper.
      */
-    public void set(int type, long triggerAtMillis, String tag, OnAlarmListener listener,
+    public void set(@AlarmType int type, long triggerAtMillis, String tag, OnAlarmListener listener,
             Handler targetHandler) {
         setImpl(type, triggerAtMillis, legacyExactLength(), 0, 0, null, listener, tag,
                 targetHandler, null, null);
@@ -399,8 +410,7 @@
      * whose {@code targetSdkVersion} is earlier than API 19 will continue to have all
      * of their alarms, including repeating alarms, treated as exact.
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should first
      * go off, using the appropriate clock (depending on the alarm type).
      * @param intervalMillis interval in milliseconds between subsequent repeats
@@ -422,7 +432,7 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void setRepeating(int type, long triggerAtMillis,
+    public void setRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, 0, operation,
                 null, null, null, null, null);
@@ -448,8 +458,7 @@
      * at precisely-specified times with no acceptable variation, applications can use
      * {@link #setExact(int, long, PendingIntent)}.
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param windowStartMillis The earliest time, in milliseconds, that the alarm should
      *        be delivered, expressed in the appropriate clock's units (depending on the alarm
      *        type).
@@ -473,7 +482,7 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
+    public void setWindow(@AlarmType int type, long windowStartMillis, long windowLengthMillis,
             PendingIntent operation) {
         setImpl(type, windowStartMillis, windowLengthMillis, 0, 0, operation,
                 null, null, null, null, null);
@@ -488,7 +497,7 @@
      * invoked via the specified target Handler, or on the application's main looper
      * if {@code null} is passed as the {@code targetHandler} parameter.
      */
-    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
+    public void setWindow(@AlarmType int type, long windowStartMillis, long windowLengthMillis,
             String tag, OnAlarmListener listener, Handler targetHandler) {
         setImpl(type, windowStartMillis, windowLengthMillis, 0, 0, null, listener, tag,
                 targetHandler, null, null);
@@ -508,8 +517,7 @@
      * scheduled as exact.  Applications are strongly discouraged from using exact
      * alarms unnecessarily as they reduce the OS's ability to minimize battery use.
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should go
      *        off, using the appropriate clock (depending on the alarm type).
      * @param operation Action to perform when the alarm goes off;
@@ -528,7 +536,7 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
+    public void setExact(@AlarmType int type, long triggerAtMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, operation, null, null, null,
                 null, null);
     }
@@ -542,8 +550,8 @@
      * invoked via the specified target Handler, or on the application's main looper
      * if {@code null} is passed as the {@code targetHandler} parameter.
      */
-    public void setExact(int type, long triggerAtMillis, String tag, OnAlarmListener listener,
-            Handler targetHandler) {
+    public void setExact(@AlarmType int type, long triggerAtMillis, String tag,
+            OnAlarmListener listener, Handler targetHandler) {
         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, null, listener, tag,
                 targetHandler, null, null);
     }
@@ -553,8 +561,8 @@
      * the given time.
      * @hide
      */
-    public void setIdleUntil(int type, long triggerAtMillis, String tag, OnAlarmListener listener,
-            Handler targetHandler) {
+    public void setIdleUntil(@AlarmType int type, long triggerAtMillis, String tag,
+            OnAlarmListener listener, Handler targetHandler) {
         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_IDLE_UNTIL, null,
                 listener, tag, targetHandler, null, null);
     }
@@ -590,8 +598,8 @@
 
     /** @hide */
     @SystemApi
-    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
-            PendingIntent operation, WorkSource workSource) {
+    public void set(@AlarmType int type, long triggerAtMillis, long windowMillis,
+            long intervalMillis, PendingIntent operation, WorkSource workSource) {
         setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, operation, null, null,
                 null, workSource, null);
     }
@@ -606,8 +614,9 @@
      *
      * @hide
      */
-    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
-            String tag, OnAlarmListener listener, Handler targetHandler, WorkSource workSource) {
+    public void set(@AlarmType int type, long triggerAtMillis, long windowMillis,
+            long intervalMillis, String tag, OnAlarmListener listener, Handler targetHandler,
+            WorkSource workSource) {
         setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, null, listener, tag,
                 targetHandler, workSource, null);
     }
@@ -623,15 +632,17 @@
      * @hide
      */
     @SystemApi
-    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
-            OnAlarmListener listener, Handler targetHandler, WorkSource workSource) {
+    public void set(@AlarmType int type, long triggerAtMillis, long windowMillis,
+            long intervalMillis, OnAlarmListener listener, Handler targetHandler,
+            WorkSource workSource) {
         setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, null, listener, null,
                 targetHandler, workSource, null);
     }
 
-    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
-            int flags, PendingIntent operation, final OnAlarmListener listener, String listenerTag,
-            Handler targetHandler, WorkSource workSource, AlarmClockInfo alarmClock) {
+    private void setImpl(@AlarmType int type, long triggerAtMillis, long windowMillis,
+            long intervalMillis, int flags, PendingIntent operation, final OnAlarmListener listener,
+            String listenerTag, Handler targetHandler, WorkSource workSource,
+            AlarmClockInfo alarmClock) {
         if (triggerAtMillis < 0) {
             /* NOTYET
             if (mAlwaysExact) {
@@ -728,8 +739,7 @@
      * assured that it will get similar behavior on both current and older versions
      * of Android.
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should first
      * go off, using the appropriate clock (depending on the alarm type).  This
      * is inexact: the alarm will not fire before this time, but there may be a
@@ -763,7 +773,7 @@
      * @see #INTERVAL_HALF_DAY
      * @see #INTERVAL_DAY
      */
-    public void setInexactRepeating(int type, long triggerAtMillis,
+    public void setInexactRepeating(@AlarmType int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, 0, operation, null,
                 null, null, null, null);
@@ -795,8 +805,7 @@
      * <p>Regardless of the app's target SDK version, this call always allows batching of the
      * alarm.</p>
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should go
      * off, using the appropriate clock (depending on the alarm type).
      * @param operation Action to perform when the alarm goes off;
@@ -814,7 +823,8 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
+    public void setAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
+            PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, 0, FLAG_ALLOW_WHILE_IDLE,
                 operation, null, null, null, null, null);
     }
@@ -848,8 +858,7 @@
      * device is idle it may take even more liberties with scheduling in order to optimize
      * for battery life.</p>
      *
-     * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
-     *        {@link #RTC}, or {@link #RTC_WAKEUP}.
+     * @param type type of alarm.
      * @param triggerAtMillis time in milliseconds that the alarm should go
      *        off, using the appropriate clock (depending on the alarm type).
      * @param operation Action to perform when the alarm goes off;
@@ -868,7 +877,8 @@
      * @see #RTC
      * @see #RTC_WAKEUP
      */
-    public void setExactAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
+    public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
+            PendingIntent operation) {
         setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, operation,
                 null, null, null, null, null);
     }
diff --git a/core/java/android/net/RecommendationResult.aidl b/core/java/android/app/CompatibilityDisplayProperties.aidl
similarity index 73%
rename from core/java/android/net/RecommendationResult.aidl
rename to core/java/android/app/CompatibilityDisplayProperties.aidl
index f36995b..626a63e 100644
--- a/core/java/android/net/RecommendationResult.aidl
+++ b/core/java/android/app/CompatibilityDisplayProperties.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2016, The Android Open Source Project
+/*
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      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,
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net;
+package android.app;
 
-parcelable RecommendationResult;
+/** @hide */
+parcelable CompatibilityDisplayProperties;
diff --git a/core/java/android/app/CompatibilityDisplayProperties.java b/core/java/android/app/CompatibilityDisplayProperties.java
new file mode 100644
index 0000000..9a9bc2c
--- /dev/null
+++ b/core/java/android/app/CompatibilityDisplayProperties.java
@@ -0,0 +1,123 @@
+/*
+ * 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.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.PrintWriter;
+
+/**
+ * Display properties to be used by VR mode when creating a virtual display.
+ *
+ * @hide
+ */
+public class CompatibilityDisplayProperties implements Parcelable {
+
+   /**
+    * The actual width, height and dpi.
+    */
+    private final int mWidth;
+    private final int mHeight;
+    private final int mDpi;
+
+    public CompatibilityDisplayProperties(int width, int height, int dpi) {
+        mWidth = width;
+        mHeight = height;
+        mDpi = dpi;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getWidth();
+        result = 31 * result + getHeight();
+        result = 31 * result + getDpi();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "CompatibilityDisplayProperties{" +
+                "mWidth=" + mWidth +
+                ", mHeight=" + mHeight +
+                ", mDpi=" + mDpi +
+                "}";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CompatibilityDisplayProperties that = (CompatibilityDisplayProperties) o;
+
+        if (getWidth() != that.getWidth()) return false;
+        if (getHeight() != that.getHeight()) return false;
+        return getDpi() == that.getDpi();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mWidth);
+        dest.writeInt(mHeight);
+        dest.writeInt(mDpi);
+    }
+
+    public static final Parcelable.Creator<CompatibilityDisplayProperties> CREATOR
+            = new Parcelable.Creator<CompatibilityDisplayProperties>() {
+        @Override
+        public CompatibilityDisplayProperties createFromParcel(Parcel source) {
+            return new CompatibilityDisplayProperties(source);
+        }
+
+        @Override
+        public CompatibilityDisplayProperties[] newArray(int size) {
+            return new CompatibilityDisplayProperties[size];
+        }
+    };
+
+    private CompatibilityDisplayProperties(Parcel source) {
+        mWidth = source.readInt();
+        mHeight = source.readInt();
+        mDpi = source.readInt();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "CompatibilityDisplayProperties:");
+        pw.println(prefix + "  width=" + mWidth);
+        pw.println(prefix + "  height=" + mHeight);
+        pw.println(prefix + "  dpi=" + mDpi);
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    public int getDpi() {
+        return mDpi;
+    }
+}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 602cccb..e53e3da 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -676,7 +676,16 @@
      * Finally, a notification can be made {@link #VISIBILITY_SECRET}, which will suppress its icon
      * and ticker until the user has bypassed the lockscreen.
      */
-    public int visibility;
+    public @Visibility int visibility;
+
+    /** @hide */
+    @IntDef(prefix = { "VISIBILITY_" }, value = {
+            VISIBILITY_PUBLIC,
+            VISIBILITY_PRIVATE,
+            VISIBILITY_SECRET,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Visibility {}
 
     /**
      * Notification visibility: Show this notification in its entirety on all lockscreens.
@@ -1097,6 +1106,45 @@
     private String mShortcutId;
     private CharSequence mSettingsText;
 
+    /** @hide */
+    @IntDef(prefix = { "GROUP_ALERT_" }, value = {
+            GROUP_ALERT_ALL, GROUP_ALERT_CHILDREN, GROUP_ALERT_SUMMARY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GroupAlertBehavior {}
+
+    /**
+     * Constant for {@link Builder#setGroupAlertBehavior(int)}, meaning that all notifications in a
+     * group with sound or vibration ought to make sound or vibrate (respectively), so this
+     * notification will not be muted when it is in a group.
+     */
+    public static final int GROUP_ALERT_ALL = 0;
+
+    /**
+     * Constant for {@link Builder#setGroupAlertBehavior(int)}, meaning that all children
+     * notification in a group should be silenced (no sound or vibration) even if they are posted
+     * to a {@link NotificationChannel} that has sound and/or vibration. Use this constant to
+     * mute this notification if this notification is a group child.
+     *
+     * <p> For example, you might want to use this constant if you post a number of children
+     * notifications at once (say, after a periodic sync), and only need to notify the user
+     * audibly once.
+     */
+    public static final int GROUP_ALERT_SUMMARY = 1;
+
+    /**
+     * Constant for {@link Builder#setGroupAlertBehavior(int)}, meaning that the summary
+     * notification in a group should be silenced (no sound or vibration) even if they are
+     * posted to a {@link NotificationChannel} that has sound and/or vibration. Use this constant
+     * to mute this notification if this notification is a group summary.
+     *
+     * <p>For example, you might want to use this constant if only the children notifications
+     * in your group have content and the summary is only used to visually group notifications.
+     */
+    public static final int GROUP_ALERT_CHILDREN = 2;
+
+    private int mGroupAlertBehavior = GROUP_ALERT_ALL;
+
     /**
      * If this notification is being shown as a badge, always show as a number.
      */
@@ -1869,6 +1917,8 @@
         if (parcel.readInt() != 0) {
             mSettingsText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
         }
+
+        mGroupAlertBehavior = parcel.readInt();
     }
 
     @Override
@@ -1981,6 +2031,7 @@
         that.mShortcutId = this.mShortcutId;
         that.mBadgeIcon = this.mBadgeIcon;
         that.mSettingsText = this.mSettingsText;
+        that.mGroupAlertBehavior = this.mGroupAlertBehavior;
 
         if (!heavy) {
             that.lightenPayload(); // will clean out extras
@@ -2257,6 +2308,8 @@
         } else {
             parcel.writeInt(0);
         }
+
+        parcel.writeInt(mGroupAlertBehavior);
     }
 
     /**
@@ -2462,17 +2515,6 @@
     }
 
     /**
-     * @removed
-     * Returns what icon should be shown for this notification if it is being displayed in a
-     * Launcher that supports badging. Will be one of {@link #BADGE_ICON_NONE},
-     * {@link #BADGE_ICON_SMALL}, or {@link #BADGE_ICON_LARGE}.
-     */
-    @Deprecated
-    public int getBadgeIcon() {
-        return mBadgeIcon;
-    }
-
-    /**
      * Returns what icon should be shown for this notification if it is being displayed in a
      * Launcher that supports badging. Will be one of {@link #BADGE_ICON_NONE},
      * {@link #BADGE_ICON_SMALL}, or {@link #BADGE_ICON_LARGE}.
@@ -2497,6 +2539,15 @@
     }
 
     /**
+     * Returns which type of notifications in a group are responsible for audibly alerting the
+     * user. See {@link #GROUP_ALERT_ALL}, {@link #GROUP_ALERT_CHILDREN},
+     * {@link #GROUP_ALERT_SUMMARY}.
+     */
+    public @GroupAlertBehavior int getGroupAlertBehavior() {
+        return mGroupAlertBehavior;
+    }
+
+    /**
      * The small icon representing this notification in the status bar and content view.
      *
      * @return the small icon representing this notification.
@@ -2744,6 +2795,19 @@
         }
 
         /**
+         * Sets the group alert behavior for this notification. Use this method to mute this
+         * notification if alerts for this notification's group should be handled by a different
+         * notification. This is only applicable for notifications that belong to a
+         * {@link #setGroup(String) group}.
+         *
+         * <p> The default value is {@link #GROUP_ALERT_ALL}.</p>
+         */
+        public Builder setGroupAlertBehavior(@GroupAlertBehavior int groupAlertBehavior) {
+            mN.mGroupAlertBehavior = groupAlertBehavior;
+            return this;
+        }
+
+        /**
          * Specifies the channel the notification should be delivered on.
          */
         public Builder setChannel(String channelId) {
@@ -3545,12 +3609,9 @@
         /**
          * Specify the value of {@link #visibility}.
          *
-         * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default),
-         * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}.
-         *
          * @return The same Builder.
          */
-        public Builder setVisibility(int visibility) {
+        public Builder setVisibility(@Visibility int visibility) {
             mN.visibility = visibility;
             return this;
         }
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 9059daa..2dd3301 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -162,10 +162,9 @@
      *             broadcast. The recommended maximum length is 40 characters; the value may be
      *             truncated if it is too long.
      * @param importance The importance of the channel. This controls how interruptive notifications
-     *                   posted to this channel are. See e.g.
-     *                   {@link NotificationManager#IMPORTANCE_DEFAULT}.
+     *                   posted to this channel are.
      */
-    public NotificationChannel(String id, CharSequence name, int importance) {
+    public NotificationChannel(String id, CharSequence name, @Importance int importance) {
         this.mId = getTrimmedString(id);
         this.mName = name != null ? getTrimmedString(name.toString()) : null;
         this.mImportance = importance;
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 4dd578e..878c8c3 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -45,6 +45,26 @@
     }
 
     /**
+     * Sets the resolution and DPI of the compatibility virtual display used to display 2D
+     * applications in VR mode.
+     *
+     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+     *
+     * @param {@link android.app.CompatibilityDisplayProperties} properties to be set to the
+     * virtual display for 2D applications in VR mode.
+     *
+     * {@hide}
+     */
+    public void setCompatibilityDisplayProperties(
+            CompatibilityDisplayProperties compatDisplayProp) {
+        try {
+            mService.setCompatibilityDisplayProperties(compatDisplayProp);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Initiate connection for system controller data.
      *
      * @param fd Controller data file descriptor.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 0676bca..6d87de8 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -20,7 +20,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RawRes;
+import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -103,6 +105,7 @@
      * <p>Output: RESULT_OK if user decided to crop/set the wallpaper, RESULT_CANCEL otherwise
      * Activities that support this intent should specify a MIME filter of "image/*"
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_CROP_AND_SET_WALLPAPER =
             "android.service.wallpaper.CROP_AND_SET_WALLPAPER";
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 82ad825..a939eb0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2972,9 +2972,9 @@
      * profile.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param timeoutMs The new timeout, after which the user will have to unlock with strong
-     *         authentication method. A value of 0 means the admin is not participating in
-     *         controlling the timeout.
+     * @param timeoutMs The new timeout in milliseconds, after which the user will have to unlock
+     *         with strong authentication method. A value of 0 means the admin is not participating
+     *         in controlling the timeout.
      *         The minimum and maximum timeouts are platform-defined and are typically 1 hour and
      *         72 hours, respectively. Though discouraged, the admin may choose to require strong
      *         auth at all times using {@link #KEYGUARD_DISABLE_FINGERPRINT} and/or
@@ -3004,7 +3004,7 @@
      *
      * @param admin The name of the admin component to check, or {@code null} to aggregate
      *         accross all participating admins.
-     * @return The timeout or 0 if not configured for the provided admin.
+     * @return The timeout in milliseconds or 0 if not configured for the provided admin.
      */
     public long getRequiredStrongAuthTimeout(@Nullable ComponentName admin) {
         return getRequiredStrongAuthTimeout(admin, myUserId());
@@ -7681,6 +7681,8 @@
      *
      * <p> Backup service is off by default when device owner is present.
      *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param enabled {@code true} to enable the backup service, {@code false} to disable it.
      * @throws SecurityException if {@code admin} is not a device owner.
      */
     public void setBackupServiceEnabled(@NonNull ComponentName admin, boolean enabled) {
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
index 6bb9f2d..fa31273 100644
--- a/core/java/android/app/admin/SystemUpdateInfo.java
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -89,8 +89,9 @@
     }
 
     /**
-     * Gets time when the update was first available.
-     * @return Time as given by {@link System#currentTimeMillis()}
+     * Gets time when the update was first available in milliseconds since midnight, January 1,
+     * 1970 UTC.
+     * @return Time in milliseconds as given by {@link System#currentTimeMillis()}
      */
     public long getReceivedTime() {
         return mReceivedTime;
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index ca74d54..d757f3e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -6,6 +6,7 @@
 import android.content.ComponentName;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.BadParcelableException;
 import android.os.Binder;
 import android.os.Bundle;
@@ -599,7 +600,7 @@
         String mIdType;
         String mIdEntry;
 
-        // TODO(b/33197203): once we have more flags, it might be better to store the individual
+        // TODO: once we have more flags, it might be better to store the individual
         // fields (viewId and childId) of the field.
         AutofillId mAutofillId;
         @View.AutofillType int mAutofillType = View.AUTOFILL_TYPE_NONE;
@@ -638,7 +639,7 @@
         static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
         static final int FLAGS_OPAQUE = 0x00008000;
 
-        // TODO(b/33197203): autofill data is made of many fields and ideally we should verify
+        // TODO: autofill data is made of many fields and ideally we should verify
         // one-by-one to optimize what's sent over, but there isn't enough flag bits for that, we'd
         // need to create a 'flags2' or 'autoFillFlags' field and add these flags there.
         // So, to keep thinkg simpler for now, let's just use on flag for all of them...
@@ -666,7 +667,7 @@
 
         ViewNodeText mText;
         int mInputType;
-        String mUrl;
+        String mWebDomain;
         Bundle mExtras;
         LocaleList mLocaleList;
 
@@ -743,7 +744,7 @@
                 mInputType = in.readInt();
             }
             if ((flags&FLAGS_HAS_URL) != 0) {
-                mUrl = in.readString();
+                mWebDomain = in.readString();
             }
             if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) {
                 mLocaleList = in.readParcelable(null);
@@ -805,7 +806,7 @@
             if (mInputType != 0) {
                 flags |= FLAGS_HAS_INPUT_TYPE;
             }
-            if (mUrl != null) {
+            if (mWebDomain != null) {
                 flags |= FLAGS_HAS_URL;
             }
             if (mLocaleList != null) {
@@ -900,7 +901,7 @@
                 out.writeInt(mInputType);
             }
             if ((flags&FLAGS_HAS_URL) != 0) {
-                out.writeString(mUrl);
+                out.writeString(mWebDomain);
             }
             if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) {
                 out.writeParcelable(mLocaleList, 0);
@@ -1042,8 +1043,6 @@
          */
         public void updateAutofillValue(AutofillValue value) {
             mAutofillValue = value;
-            // TODO(b/33197203, b/33802548): decide whether to set text as well (so it would work
-            // with "legacy" views) or just the autofill value
             if (value.isText()) {
                 mText.mText = value.getTextValue();
             }
@@ -1237,17 +1236,20 @@
         }
 
         /**
-         * Returns the URL represented by this view.
+         * Returns the domain of the HTML document represented by this view.
          *
          * <p>Typically used when the view associated with the view is a container for an HTML
          * document.
          *
          * <strong>WARNING:</strong> a {@link android.service.autofill.AutofillService} should only
-         * use this URL for Autofill purposes when it trusts the app generating it (i.e., the app
+         * use this domain for Autofill purposes when it trusts the app generating it (i.e., the app
          * defined by {@link AssistStructure#getActivityComponent()}).
+         *
+         * @return domain-only part of the document. For example, if the full URL is
+         * {@code http://my.site/login?user=my_user}, it returns {@code my.site}.
          */
-        @Nullable public String getUrl() {
-            return mUrl;
+        @Nullable public String getWebDomain() {
+            return mWebDomain;
         }
 
         /**
@@ -1724,7 +1726,18 @@
 
         @Override
         public void setUrl(String url) {
-            mNode.mUrl = url;
+            if (url == null) return;
+
+            setWebDomain(url);
+        }
+
+        @Override
+        public void setWebDomain(@Nullable String domain) {
+            if (domain == null) {
+                mNode.mWebDomain = null;
+                return;
+            }
+            mNode.mWebDomain = Uri.parse(domain).getHost();
         }
 
         @Override
@@ -1946,9 +1959,9 @@
             Log.i(TAG, prefix + "  Text color fg: #" + Integer.toHexString(node.getTextColor())
                     + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor()));
         }
-        CharSequence url = node.getUrl();
-        if (url != null) {
-            Log.i(TAG, prefix + "  URL: " + url);
+        String webDomain = node.getWebDomain();
+        if (webDomain != null) {
+            Log.i(TAG, prefix + "  Web domain: " + webDomain);
         }
         HtmlInfo htmlInfo = node.getHtmlInfo();
         if (htmlInfo != null) {
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 3538256..007ea88 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -18,8 +18,10 @@
 
 import static android.util.TimeUtils.formatDuration;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.content.ClipData;
 import android.content.ComponentName;
 import android.net.Uri;
@@ -30,6 +32,8 @@
 import android.os.PersistableBundle;
 import android.util.Log;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Objects;
 
@@ -43,6 +47,18 @@
  */
 public class JobInfo implements Parcelable {
     private static String TAG = "JobInfo";
+
+    /** @hide */
+    @IntDef(prefix = { "NETWORK_TYPE_" }, value = {
+            NETWORK_TYPE_NONE,
+            NETWORK_TYPE_ANY,
+            NETWORK_TYPE_UNMETERED,
+            NETWORK_TYPE_NOT_ROAMING,
+            NETWORK_TYPE_METERED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NetworkType {}
+
     /** Default. */
     public static final int NETWORK_TYPE_NONE = 0;
     /** This job requires network connectivity. */
@@ -64,6 +80,14 @@
      */
     public static final long MAX_BACKOFF_DELAY_MILLIS = 5 * 60 * 60 * 1000;  // 5 hours.
 
+    /** @hide */
+    @IntDef(prefix = { "BACKOFF_POLICY_" }, value = {
+            BACKOFF_POLICY_LINEAR,
+            BACKOFF_POLICY_EXPONENTIAL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BackoffPolicy {}
+
     /**
      * Linearly back-off a failed job. See
      * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
@@ -349,14 +373,8 @@
 
     /**
      * The kind of connectivity requirements that the job has.
-     *
-     * @return One of {@link android.app.job.JobInfo#NETWORK_TYPE_ANY},
-     * {@link android.app.job.JobInfo#NETWORK_TYPE_NONE},
-     * {@link android.app.job.JobInfo#NETWORK_TYPE_UNMETERED},
-     * {@link android.app.job.JobInfo#NETWORK_TYPE_METERED}, or
-     * {@link android.app.job.JobInfo#NETWORK_TYPE_NOT_ROAMING},
      */
-    public int getNetworkType() {
+    public @NetworkType int getNetworkType() {
         return networkType;
     }
 
@@ -421,11 +439,9 @@
     }
 
     /**
-     * One of either {@link android.app.job.JobInfo#BACKOFF_POLICY_EXPONENTIAL}, or
-     * {@link android.app.job.JobInfo#BACKOFF_POLICY_LINEAR}, depending on which criteria you set
-     * when creating this job.
+     * Return the backoff policy of this job.
      */
-    public int getBackoffPolicy() {
+    public @BackoffPolicy int getBackoffPolicy() {
         return backoffPolicy;
     }
 
@@ -692,6 +708,13 @@
         private final Uri mUri;
         private final int mFlags;
 
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+                FLAG_NOTIFY_FOR_DESCENDANTS,
+        })
+        public @interface Flags { }
+
         /**
          * Flag for trigger: also trigger if any descendants of the given URI change.
          * Corresponds to the <var>notifyForDescendants</var> of
@@ -702,10 +725,9 @@
         /**
          * Create a new trigger description.
          * @param uri The URI to observe.  Must be non-null.
-         * @param flags Optional flags for the observer, either 0 or
-         * {@link #FLAG_NOTIFY_FOR_DESCENDANTS}.
+         * @param flags Flags for the observer.
          */
-        public TriggerContentUri(@NonNull Uri uri, int flags) {
+        public TriggerContentUri(@NonNull Uri uri, @Flags int flags) {
             mUri = uri;
             mFlags = flags;
         }
@@ -720,7 +742,7 @@
         /**
          * Return the flags supplied for the trigger.
          */
-        public int getFlags() {
+        public @Flags int getFlags() {
             return mFlags;
         }
 
@@ -886,7 +908,7 @@
          * job. If the network requested is not available your job will never run. See
          * {@link #setOverrideDeadline(long)} to change this behaviour.
          */
-        public Builder setRequiredNetworkType(int networkType) {
+        public Builder setRequiredNetworkType(@NetworkType int networkType) {
             mNetworkType = networkType;
             return this;
         }
@@ -1067,10 +1089,9 @@
          * mode.
          * @param initialBackoffMillis Millisecond time interval to wait initially when job has
          *                             failed.
-         * @param backoffPolicy is one of {@link #BACKOFF_POLICY_LINEAR} or
-         * {@link #BACKOFF_POLICY_EXPONENTIAL}
          */
-        public Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy) {
+        public Builder setBackoffCriteria(long initialBackoffMillis,
+                @BackoffPolicy int backoffPolicy) {
             mBackoffPolicySet = true;
             mInitialBackoffMillis = initialBackoffMillis;
             mBackoffPolicy = backoffPolicy;
@@ -1078,13 +1099,12 @@
         }
 
         /**
-         * Set whether or not to persist this job across device reboots. This will only have an
-         * effect if your application holds the permission
-         * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED}. Otherwise an exception will
-         * be thrown.
-         * @param isPersisted True to indicate that the job will be written to disk and loaded at
-         *                    boot.
+         * Set whether or not to persist this job across device reboots.
+         *
+         * @param isPersisted True to indicate that the job will be written to
+         *            disk and loaded at boot.
          */
+        @RequiresPermission(android.Manifest.permission.RECEIVE_BOOT_COMPLETED)
         public Builder setPersisted(boolean isPersisted) {
             mIsPersisted = isPersisted;
             return this;
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index 23f9eea..1768828 100644
--- a/core/java/android/app/job/JobScheduler.java
+++ b/core/java/android/app/job/JobScheduler.java
@@ -16,6 +16,7 @@
 
 package android.app.job;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -24,6 +25,8 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -51,6 +54,14 @@
  * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
  */
 public abstract class JobScheduler {
+    /** @hide */
+    @IntDef(prefix = { "RESULT_" }, value = {
+            RESULT_FAILURE,
+            RESULT_SUCCESS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Result {}
+
     /**
      * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
      * if the run-time for your job is too short, or perhaps the system can't resolve the
@@ -70,9 +81,9 @@
      * @param job The job you wish scheduled. See
      * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
      * you can schedule.
-     * @return An int representing ({@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}).
+     * @return the result of the schedule request.
      */
-    public abstract int schedule(@NonNull JobInfo job);
+    public abstract @Result int schedule(@NonNull JobInfo job);
 
     /**
      * Similar to {@link #schedule}, but allows you to enqueue work for a new <em>or existing</em>
@@ -107,9 +118,9 @@
      * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
      * you can schedule.
      * @param work New work to enqueue.  This will be available later when the job starts running.
-     * @return An int representing ({@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}).
+     * @return the result of the enqueue request.
      */
-    public abstract int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work);
+    public abstract @Result int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work);
 
     /**
      *
@@ -118,11 +129,10 @@
      *                    used to track battery usage and appIdleState.
      * @param userId    User on behalf of whom this job is to be scheduled.
      * @param tag Debugging tag for dumps associated with this job (instead of the service class)
-     * @return {@link #RESULT_SUCCESS} or {@link #RESULT_FAILURE}
      * @hide
      */
     @SystemApi
-    public abstract int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName,
+    public abstract @Result int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName,
             int userId, String tag);
 
     /**
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 9f35e85..6327f34 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -712,12 +712,13 @@
      *
      * @param profile The profile for which to get providers. Passing null is equivalent
      *        to querying for only the calling user.
-     * @return The installed providers.
+     * @return The installed providers, or an empty list if none are found for the given user.
      *
      * @see android.os.Process#myUserHandle()
      * @see android.os.UserManager#getUserProfiles()
      */
-    public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(@Nullable UserHandle profile) {
+    public @NonNull List<AppWidgetProviderInfo> getInstalledProvidersForProfile(
+            @Nullable UserHandle profile) {
         if (mService == null) {
             return Collections.emptyList();
         }
@@ -735,13 +736,20 @@
      *        equivalent to {@link #getInstalledProvidersForProfile(UserHandle)}.
      * @param profile The profile for which to get providers. Passing null is equivalent
      *        to querying for only the calling user.
-     * @return The installed providers.
+     * @return The installed providers, or an empty list if none are found for the given
+     *         package and user.
+     * @throws NullPointerException if the provided package name is null
      *
      * @see android.os.Process#myUserHandle()
      * @see android.os.UserManager#getUserProfiles()
      */
-    public List<AppWidgetProviderInfo> getInstalledProvidersForPackage(@Nullable String packageName,
-            @Nullable UserHandle profile) {
+    public @NonNull List<AppWidgetProviderInfo> getInstalledProvidersForPackage(
+            @NonNull String packageName, @Nullable UserHandle profile) {
+        if (packageName == null) {
+            throw new NullPointerException("A non-null package must be passed to this method. " +
+                    "If you want all widgets regardless of package, see " +
+                    "getInstalledProvidersForProfile(UserHandle)");
+        }
         if (mService == null) {
             return Collections.emptyList();
         }
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 8d2c3ec..5246513 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -73,7 +73,7 @@
 
     /**
      * Optional extra indicating the callback type, which will be one of
-     * ScanSettings.CALLBACK_TYPE_*.
+     * CALLBACK_TYPE_* constants in {@link ScanSettings}.
      * @see ScanCallback#onScanResult(int, ScanResult)
      */
     public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index e50b2a9..fac9e13 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -118,6 +118,9 @@
      * association is no longer relevant to avoid unnecessary battery and/or data drain resulting
      * from special privileges that the association provides</p>
      *
+     * <p>Calling this API requires a uses-feature
+     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
+     *
      * @param request specific details about this request
      * @param callback will be called once there's at least one device found for user to choose from
      * @param handler A handler to control which thread the callback will be delivered on, or null,
@@ -160,6 +163,9 @@
     }
 
     /**
+     * <p>Calling this API requires a uses-feature
+     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
+     *
      * @return a list of MAC addresses of devices that have been previously associated with the
      * current app. You can use these with {@link #disassociate}
      */
@@ -184,6 +190,9 @@
      * association is no longer relevant to avoid unnecessary battery and/or data drain resulting
      * from special privileges that the association provides</p>
      *
+     * <p>Calling this API requires a uses-feature
+     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
+     *
      * @param deviceMacAddress the MAC address of device to disassociate from this app
      */
     public void disassociate(@NonNull String deviceMacAddress) {
@@ -206,6 +215,9 @@
      * are allowed.
      *
      * Your app must have an association with a device before calling this API
+     *
+     * <p>Calling this API requires a uses-feature
+     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
      */
     public void requestNotificationAccess(ComponentName component) {
         if (!checkFeaturePresent()) {
@@ -226,6 +238,9 @@
      *
      * Your app must have an association with a device before calling this API
      *
+     * <p>Calling this API requires a uses-feature
+     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
+     *
      * @param component the name of the component
      * @return whether the given component has the notification listener permission
      */
diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java
index 8aeb22d..ea6b769 100644
--- a/core/java/android/content/ComponentName.java
+++ b/core/java/android/content/ComponentName.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -52,7 +54,7 @@
      *            the component
      * @return the new ComponentName
      */
-    public static ComponentName createRelative(String pkg, String cls) {
+    public static @NonNull ComponentName createRelative(@NonNull String pkg, @NonNull String cls) {
         if (TextUtils.isEmpty(cls)) {
             throw new IllegalArgumentException("class name cannot be empty");
         }
@@ -83,7 +85,7 @@
      *            the component
      * @return the new ComponentName
      */
-    public static ComponentName createRelative(Context pkg, String cls) {
+    public static @NonNull ComponentName createRelative(@NonNull Context pkg, @NonNull String cls) {
         return createRelative(pkg.getPackageName(), cls);
     }
 
@@ -95,7 +97,7 @@
      * @param cls The name of the class inside of <var>pkg</var> that
      * implements the component.  Can not be null.
      */
-    public ComponentName(String pkg, String cls) {
+    public ComponentName(@NonNull String pkg, @NonNull String cls) {
         if (pkg == null) throw new NullPointerException("package name is null");
         if (cls == null) throw new NullPointerException("class name is null");
         mPackage = pkg;
@@ -110,7 +112,7 @@
      * @param cls The name of the class inside of <var>pkg</var> that
      * implements the component.
      */
-    public ComponentName(Context pkg, String cls) {
+    public ComponentName(@NonNull Context pkg, @NonNull String cls) {
         if (cls == null) throw new NullPointerException("class name is null");
         mPackage = pkg.getPackageName();
         mClass = cls;
@@ -124,7 +126,7 @@
      * @param cls The Class object of the desired component, from which the
      * actual class name will be retrieved.
      */
-    public ComponentName(Context pkg, Class<?> cls) {
+    public ComponentName(@NonNull Context pkg, @NonNull Class<?> cls) {
         mPackage = pkg.getPackageName();
         mClass = cls.getName();
     }
@@ -136,14 +138,14 @@
     /**
      * Return the package name of this component.
      */
-    public String getPackageName() {
+    public @NonNull String getPackageName() {
         return mPackage;
     }
     
     /**
      * Return the class name of this component.
      */
-    public String getClassName() {
+    public @NonNull String getClassName() {
         return mClass;
     }
     
@@ -200,7 +202,7 @@
      * 
      * @see #unflattenFromString(String)
      */
-    public String flattenToString() {
+    public @NonNull String flattenToString() {
         return mPackage + "/" + mClass;
     }
     
@@ -215,7 +217,7 @@
      * 
      * @see #unflattenFromString(String)
      */
-    public String flattenToShortString() {
+    public @NonNull String flattenToShortString() {
         StringBuilder sb = new StringBuilder(mPackage.length() + mClass.length());
         appendShortString(sb, mPackage, mClass);
         return sb.toString();
@@ -255,7 +257,7 @@
      * 
      * @see #flattenToString()
      */
-    public static ComponentName unflattenFromString(String str) {
+    public static @Nullable ComponentName unflattenFromString(@NonNull String str) {
         int sep = str.indexOf('/');
         if (sep < 0 || (sep+1) >= str.length()) {
             return null;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 1585d21..d0ce3cf 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -85,6 +85,37 @@
  * broadcasting and receiving intents, etc.
  */
 public abstract class Context {
+    /** @hide */
+    @IntDef(flag = true, prefix = { "MODE_" }, value = {
+            MODE_PRIVATE,
+            MODE_WORLD_READABLE,
+            MODE_WORLD_WRITEABLE,
+            MODE_APPEND,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FileMode {}
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "MODE_" }, value = {
+            MODE_PRIVATE,
+            MODE_WORLD_READABLE,
+            MODE_WORLD_WRITEABLE,
+            MODE_MULTI_PROCESS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PreferencesMode {}
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "MODE_" }, value = {
+            MODE_PRIVATE,
+            MODE_WORLD_READABLE,
+            MODE_WORLD_WRITEABLE,
+            MODE_ENABLE_WRITE_AHEAD_LOGGING,
+            MODE_NO_LOCALIZED_COLLATORS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DatabaseMode {}
+
     /**
      * File creation mode: the default mode, where the created file can only
      * be accessed by the calling application (or all applications sharing the
@@ -720,15 +751,14 @@
      * @param name Desired preferences file. If a preferences file by this name
      * does not exist, it will be created when you retrieve an
      * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
-     * @param mode Operating mode.  Use 0 or {@link #MODE_PRIVATE} for the
-     * default operation.
+     * @param mode Operating mode.
      *
      * @return The single {@link SharedPreferences} instance that can be used
      *         to retrieve and modify the preference values.
      *
      * @see #MODE_PRIVATE
      */
-    public abstract SharedPreferences getSharedPreferences(String name, int mode);
+    public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);
 
     /**
      * Retrieve and hold the contents of the preferences file, returning
@@ -740,8 +770,7 @@
      * @param file Desired preferences file. If a preferences file by this name
      * does not exist, it will be created when you retrieve an
      * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
-     * @param mode Operating mode.  Use 0 or {@link #MODE_PRIVATE} for the
-     * default operation.
+     * @param mode Operating mode.
      *
      * @return The single {@link SharedPreferences} instance that can be used
      *         to retrieve and modify the preference values.
@@ -750,7 +779,7 @@
      * @see #MODE_PRIVATE
      * @removed
      */
-    public abstract SharedPreferences getSharedPreferences(File file, int mode);
+    public abstract SharedPreferences getSharedPreferences(File file, @PreferencesMode int mode);
 
     /**
      * Move an existing shared preferences file from the given source storage
@@ -805,9 +834,7 @@
      *
      * @param name The name of the file to open; can not contain path
      *            separators.
-     * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
-     *            default operation. Use {@link #MODE_APPEND} to append to an
-     *            existing file.
+     * @param mode Operating mode.
      * @return The resulting {@link FileOutputStream}.
      * @see #MODE_APPEND
      * @see #MODE_PRIVATE
@@ -816,7 +843,7 @@
      * @see #deleteFile
      * @see java.io.FileOutputStream#FileOutputStream(String)
      */
-    public abstract FileOutputStream openFileOutput(String name, int mode)
+    public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
         throws FileNotFoundException;
 
     /**
@@ -1413,26 +1440,21 @@
      *
      * @param name Name of the directory to retrieve.  This is a directory
      * that is created as part of your application data.
-     * @param mode Operating mode.  Use 0 or {@link #MODE_PRIVATE} for the
-     * default operation.
+     * @param mode Operating mode.
      *
      * @return A {@link File} object for the requested directory.  The directory
      * will have been created if it does not already exist.
      *
      * @see #openFileOutput(String, int)
      */
-    public abstract File getDir(String name, int mode);
+    public abstract File getDir(String name, @FileMode int mode);
 
     /**
      * Open a new private SQLiteDatabase associated with this Context's
      * application package. Create the database file if it doesn't exist.
      *
      * @param name The name (unique in the application package) of the database.
-     * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
-     *            default operation. Use
-     *            {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead
-     *            logging by default. Use {@link #MODE_NO_LOCALIZED_COLLATORS}
-     *            to disable localized collators.
+     * @param mode Operating mode.
      * @param factory An optional factory class that is called to instantiate a
      *            cursor when query is called.
      * @return The contents of a newly created database with the given name.
@@ -1444,7 +1466,7 @@
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
-            int mode, CursorFactory factory);
+            @DatabaseMode int mode, CursorFactory factory);
 
     /**
      * Open a new private SQLiteDatabase associated with this Context's
@@ -1455,11 +1477,7 @@
      * </p>
      *
      * @param name The name (unique in the application package) of the database.
-     * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
-     *            default operation. Use
-     *            {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead
-     *            logging by default. Use {@link #MODE_NO_LOCALIZED_COLLATORS}
-     *            to disable localized collators.
+     * @param mode Operating mode.
      * @param factory An optional factory class that is called to instantiate a
      *            cursor when query is called.
      * @param errorHandler the {@link DatabaseErrorHandler} to be used when
@@ -1475,7 +1493,7 @@
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
-            int mode, CursorFactory factory,
+            @DatabaseMode int mode, CursorFactory factory,
             @Nullable DatabaseErrorHandler errorHandler);
 
     /**
@@ -1777,9 +1795,9 @@
      * @see #startActivity(Intent)
      * @see #startIntentSender(IntentSender, Intent, int, int, int, Bundle)
      */
-    public abstract void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException;
+    public abstract void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent,
+            @Intent.MutableFlags int flagsMask, @Intent.MutableFlags int flagsValues,
+            int extraFlags) throws IntentSender.SendIntentException;
 
     /**
      * Like {@link #startActivity(Intent, Bundle)}, but taking a IntentSender
@@ -1806,9 +1824,9 @@
      * @see #startActivity(Intent, Bundle)
      * @see #startIntentSender(IntentSender, Intent, int, int, int)
      */
-    public abstract void startIntentSender(IntentSender intent,
-            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
-            Bundle options) throws IntentSender.SendIntentException;
+    public abstract void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent,
+            @Intent.MutableFlags int flagsMask, @Intent.MutableFlags int flagsValues,
+            int extraFlags, @Nullable Bundle options) throws IntentSender.SendIntentException;
 
     /**
      * Broadcast the given intent to all interested BroadcastReceivers.  This
@@ -2192,10 +2210,6 @@
      * all other ways, this behaves the same as
      * {@link #sendBroadcast(Intent)}.
      *
-     * <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY}
-     * permission in order to use this API.  If you do not hold that
-     * permission, {@link SecurityException} will be thrown.
-     *
      * @deprecated Sticky broadcasts should not be used.  They provide no security (anyone
      * can access them), no protection (anyone can modify them), and many other problems.
      * The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
@@ -2210,6 +2224,7 @@
      * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
     public abstract void sendStickyBroadcast(@RequiresPermission Intent intent);
 
     /**
@@ -2259,6 +2274,7 @@
      * @see android.app.Activity#RESULT_OK
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
     public abstract void sendStickyOrderedBroadcast(@RequiresPermission Intent intent,
             BroadcastReceiver resultReceiver,
             @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
@@ -2268,10 +2284,6 @@
      * <p>Remove the data previously sent with {@link #sendStickyBroadcast},
      * so that it is as if the sticky broadcast had never happened.
      *
-     * <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY}
-     * permission in order to use this API.  If you do not hold that
-     * permission, {@link SecurityException} will be thrown.
-     *
      * @deprecated Sticky broadcasts should not be used.  They provide no security (anyone
      * can access them), no protection (anyone can modify them), and many other problems.
      * The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
@@ -2283,6 +2295,7 @@
      * @see #sendStickyBroadcast
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
     public abstract void removeStickyBroadcast(@RequiresPermission Intent intent);
 
     /**
@@ -3048,7 +3061,7 @@
      * @see android.os.HardwarePropertiesManager
      * @see #HARDWARE_PROPERTIES_SERVICE
      */
-    public abstract Object getSystemService(@ServiceName @NonNull String name);
+    public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
 
     /**
      * Return the handle to a system-level service by class.
@@ -3078,7 +3091,7 @@
      * @return The service or null if the class is not a supported system service.
      */
     @SuppressWarnings("unchecked")
-    public final <T> T getSystemService(Class<T> serviceClass) {
+    public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) {
         // Because subclasses may override getSystemService(String) we cannot
         // perform a lookup by class alone.  We must first map the class to its
         // service name then invoke the string-based method.
@@ -3092,7 +3105,7 @@
      * @param serviceClass The class of the desired service.
      * @return The service name or null if the class is not a supported system service.
      */
-    public abstract String getSystemServiceName(Class<?> serviceClass);
+    public abstract @Nullable String getSystemServiceName(@NonNull Class<?> serviceClass);
 
     /**
      * Use with {@link #getSystemService} to retrieve a
@@ -3756,7 +3769,7 @@
      * @see #getSystemService
      * @see android.companion.CompanionDeviceManager
      */
-    public static final String COMPANION_DEVICE_SERVICE = "companion_device";
+    public static final String COMPANION_DEVICE_SERVICE = "companiondevice";
 
     /**
      * Use with {@link #getSystemService} to retrieve a
@@ -4181,10 +4194,12 @@
      * @see #checkCallingUriPermission
      */
     @CheckResult(suggest="#enforceUriPermission(Uri,int,int,String)")
+    @PackageManager.PermissionResult
     public abstract int checkUriPermission(Uri uri, int pid, int uid,
             @Intent.AccessUriMode int modeFlags);
 
     /** @hide */
+    @PackageManager.PermissionResult
     public abstract int checkUriPermission(Uri uri, int pid, int uid,
             @Intent.AccessUriMode int modeFlags, IBinder callerToken);
 
@@ -4208,6 +4223,7 @@
      * @see #checkUriPermission(Uri, int, int, int)
      */
     @CheckResult(suggest="#enforceCallingUriPermission(Uri,int,String)")
+    @PackageManager.PermissionResult
     public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);
 
     /**
@@ -4226,6 +4242,7 @@
      * @see #checkCallingUriPermission
      */
     @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)")
+    @PackageManager.PermissionResult
     public abstract int checkCallingOrSelfUriPermission(Uri uri,
             @Intent.AccessUriMode int modeFlags);
 
@@ -4250,6 +4267,7 @@
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      */
     @CheckResult(suggest="#enforceUriPermission(Uri,String,String,int,int,int,String)")
+    @PackageManager.PermissionResult
     public abstract int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
             @Nullable String writePermission, int pid, int uid,
             @Intent.AccessUriMode int modeFlags);
@@ -4336,8 +4354,14 @@
             @Nullable String message);
 
     /** @hide */
-    @IntDef(flag = true,
-            value = {CONTEXT_INCLUDE_CODE, CONTEXT_IGNORE_SECURITY, CONTEXT_RESTRICTED})
+    @IntDef(flag = true, prefix = { "CONTEXT_" }, value = {
+            CONTEXT_INCLUDE_CODE,
+            CONTEXT_IGNORE_SECURITY,
+            CONTEXT_RESTRICTED,
+            CONTEXT_DEVICE_PROTECTED_STORAGE,
+            CONTEXT_CREDENTIAL_PROTECTED_STORAGE,
+            CONTEXT_REGISTER_PACKAGE,
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CreatePackageOptions {}
 
@@ -4409,8 +4433,7 @@
      * {@link #CONTEXT_INCLUDE_CODE} for more information}.
      *
      * @param packageName Name of the application's package.
-     * @param flags Option flags, one of {@link #CONTEXT_INCLUDE_CODE}
-     *              or {@link #CONTEXT_IGNORE_SECURITY}.
+     * @param flags Option flags.
      *
      * @return A {@link Context} for the application.
      *
@@ -4429,7 +4452,7 @@
      * @hide
      */
     public abstract Context createPackageContextAsUser(
-            String packageName, int flags, UserHandle user)
+            String packageName, @CreatePackageOptions int flags, UserHandle user)
             throws PackageManager.NameNotFoundException;
 
     /**
@@ -4438,7 +4461,7 @@
      * @hide
      */
     public abstract Context createApplicationContext(ApplicationInfo application,
-            int flags) throws PackageManager.NameNotFoundException;
+            @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
 
     /**
      * Return a new Context object for the given split name. The new Context has a ClassLoader and
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b6f9ac9..da43fec 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -19,6 +19,8 @@
 import android.annotation.AnyRes;
 import android.annotation.BroadcastBehavior;
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -1397,6 +1399,7 @@
      *  <p>Input: nothing
      *  <p>Output: nothing
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST";
 
     /**
@@ -2059,6 +2062,7 @@
      * temporary system dialog to dismiss.  Some examples of temporary system
      * dialogs are the notification window-shade and the recent tasks dialog.
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";
     /**
      * Broadcast Action: Trigger the download and eventual installation
@@ -2588,6 +2592,7 @@
      * @deprecated replaced by android.os.storage.StorageEventListener
      */
     @Deprecated
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
 
     /**
@@ -2598,6 +2603,7 @@
      * @deprecated replaced by android.os.storage.StorageEventListener
      */
     @Deprecated
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
 
     /**
@@ -4903,6 +4909,96 @@
                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) != 0;
     }
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+            FLAG_GRANT_READ_URI_PERMISSION,
+            FLAG_GRANT_WRITE_URI_PERMISSION,
+            FLAG_FROM_BACKGROUND,
+            FLAG_DEBUG_LOG_RESOLUTION,
+            FLAG_EXCLUDE_STOPPED_PACKAGES,
+            FLAG_INCLUDE_STOPPED_PACKAGES,
+            FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
+            FLAG_GRANT_PREFIX_URI_PERMISSION,
+            FLAG_DEBUG_TRIAGED_MISSING,
+            FLAG_IGNORE_EPHEMERAL,
+            FLAG_ACTIVITY_NO_HISTORY,
+            FLAG_ACTIVITY_SINGLE_TOP,
+            FLAG_ACTIVITY_NEW_TASK,
+            FLAG_ACTIVITY_MULTIPLE_TASK,
+            FLAG_ACTIVITY_CLEAR_TOP,
+            FLAG_ACTIVITY_FORWARD_RESULT,
+            FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+            FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+            FLAG_ACTIVITY_BROUGHT_TO_FRONT,
+            FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+            FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+            FLAG_ACTIVITY_NEW_DOCUMENT,
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+            FLAG_ACTIVITY_NO_USER_ACTION,
+            FLAG_ACTIVITY_REORDER_TO_FRONT,
+            FLAG_ACTIVITY_NO_ANIMATION,
+            FLAG_ACTIVITY_CLEAR_TASK,
+            FLAG_ACTIVITY_TASK_ON_HOME,
+            FLAG_ACTIVITY_RETAIN_IN_RECENTS,
+            FLAG_ACTIVITY_LAUNCH_ADJACENT,
+            FLAG_RECEIVER_REGISTERED_ONLY,
+            FLAG_RECEIVER_REPLACE_PENDING,
+            FLAG_RECEIVER_FOREGROUND,
+            FLAG_RECEIVER_NO_ABORT,
+            FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT,
+            FLAG_RECEIVER_BOOT_UPGRADE,
+            FLAG_RECEIVER_INCLUDE_BACKGROUND,
+            FLAG_RECEIVER_EXCLUDE_BACKGROUND,
+            FLAG_RECEIVER_FROM_SHELL,
+            FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+            FLAG_FROM_BACKGROUND,
+            FLAG_DEBUG_LOG_RESOLUTION,
+            FLAG_EXCLUDE_STOPPED_PACKAGES,
+            FLAG_INCLUDE_STOPPED_PACKAGES,
+            FLAG_DEBUG_TRIAGED_MISSING,
+            FLAG_IGNORE_EPHEMERAL,
+            FLAG_ACTIVITY_NO_HISTORY,
+            FLAG_ACTIVITY_SINGLE_TOP,
+            FLAG_ACTIVITY_NEW_TASK,
+            FLAG_ACTIVITY_MULTIPLE_TASK,
+            FLAG_ACTIVITY_CLEAR_TOP,
+            FLAG_ACTIVITY_FORWARD_RESULT,
+            FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+            FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
+            FLAG_ACTIVITY_BROUGHT_TO_FRONT,
+            FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+            FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+            FLAG_ACTIVITY_NEW_DOCUMENT,
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
+            FLAG_ACTIVITY_NO_USER_ACTION,
+            FLAG_ACTIVITY_REORDER_TO_FRONT,
+            FLAG_ACTIVITY_NO_ANIMATION,
+            FLAG_ACTIVITY_CLEAR_TASK,
+            FLAG_ACTIVITY_TASK_ON_HOME,
+            FLAG_ACTIVITY_RETAIN_IN_RECENTS,
+            FLAG_ACTIVITY_LAUNCH_ADJACENT,
+            FLAG_RECEIVER_REGISTERED_ONLY,
+            FLAG_RECEIVER_REPLACE_PENDING,
+            FLAG_RECEIVER_FOREGROUND,
+            FLAG_RECEIVER_NO_ABORT,
+            FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT,
+            FLAG_RECEIVER_BOOT_UPGRADE,
+            FLAG_RECEIVER_INCLUDE_BACKGROUND,
+            FLAG_RECEIVER_EXCLUDE_BACKGROUND,
+            FLAG_RECEIVER_FROM_SHELL,
+            FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MutableFlags {}
+
     /**
      * If set, the recipient of this Intent will be granted permission to
      * perform read operations on the URI in the Intent's data and any URIs
@@ -5369,6 +5465,15 @@
     // ---------------------------------------------------------------------
     // toUri() and parseUri() options.
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "URI_" }, value = {
+            URI_ALLOW_UNSAFE,
+            URI_ANDROID_APP_SCHEME,
+            URI_INTENT_SCHEME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UriFlags {}
+
     /**
      * Flag for use with {@link #toUri} and {@link #parseUri}: the URI string
      * always has the "intent:" scheme.  This syntax can be used when you want
@@ -5538,7 +5643,7 @@
      * Make a clone of only the parts of the Intent that are relevant for
      * filter matching: the action, data, type, component, and categories.
      */
-    public Intent cloneFilter() {
+    public @NonNull Intent cloneFilter() {
         return new Intent(this, false);
     }
 
@@ -5727,8 +5832,7 @@
      * the scheme and full path.
      *
      * @param uri The URI to turn into an Intent.
-     * @param flags Additional processing flags.  Either 0,
-     * {@link #URI_INTENT_SCHEME}, or {@link #URI_ANDROID_APP_SCHEME}.
+     * @param flags Additional processing flags.
      *
      * @return Intent The newly created Intent object.
      *
@@ -5738,7 +5842,7 @@
      *
      * @see #toUri
      */
-    public static Intent parseUri(String uri, int flags) throws URISyntaxException {
+    public static Intent parseUri(String uri, @UriFlags int flags) throws URISyntaxException {
         int i = 0;
         try {
             final boolean androidApp = uri.startsWith("android-app:");
@@ -6568,7 +6672,7 @@
      *
      * @see #setAction
      */
-    public String getAction() {
+    public @Nullable String getAction() {
         return mAction;
     }
 
@@ -6583,7 +6687,7 @@
      * @see #getScheme
      * @see #setData
      */
-    public Uri getData() {
+    public @Nullable Uri getData() {
         return mData;
     }
 
@@ -6591,7 +6695,7 @@
      * The same as {@link #getData()}, but returns the URI as an encoded
      * String.
      */
-    public String getDataString() {
+    public @Nullable String getDataString() {
         return mData != null ? mData.toString() : null;
     }
 
@@ -6607,7 +6711,7 @@
      *
      * @see #getData
      */
-    public String getScheme() {
+    public @Nullable String getScheme() {
         return mData != null ? mData.getScheme() : null;
     }
 
@@ -6621,7 +6725,7 @@
      * @see #resolveType(ContentResolver)
      * @see #setType
      */
-    public String getType() {
+    public @Nullable String getType() {
         return mType;
     }
 
@@ -6636,7 +6740,7 @@
      * @see #getType
      * @see #resolveType(ContentResolver)
      */
-    public String resolveType(Context context) {
+    public @Nullable String resolveType(@NonNull Context context) {
         return resolveType(context.getContentResolver());
     }
 
@@ -6654,7 +6758,7 @@
      * @see #getType
      * @see #resolveType(Context)
      */
-    public String resolveType(ContentResolver resolver) {
+    public @Nullable String resolveType(@NonNull ContentResolver resolver) {
         if (mType != null) {
             return mType;
         }
@@ -6678,7 +6782,7 @@
      * @return The MIME type of this intent, or null if it is unknown or not
      *         needed.
      */
-    public String resolveTypeIfNeeded(ContentResolver resolver) {
+    public @Nullable String resolveTypeIfNeeded(@NonNull ContentResolver resolver) {
         if (mComponent != null) {
             return mType;
         }
@@ -6718,7 +6822,7 @@
      *
      * @see #setSelector
      */
-    public Intent getSelector() {
+    public @Nullable Intent getSelector() {
         return mSelector;
     }
 
@@ -6728,7 +6832,7 @@
      *
      * @see #setClipData
      */
-    public ClipData getClipData() {
+    public @Nullable ClipData getClipData() {
         return mClipData;
     }
 
@@ -6754,7 +6858,7 @@
      * @param loader a ClassLoader, or null to use the default loader
      * at the time of unmarshalling.
      */
-    public void setExtrasClassLoader(ClassLoader loader) {
+    public void setExtrasClassLoader(@Nullable ClassLoader loader) {
         if (mExtras != null) {
             mExtras.setClassLoader(loader);
         }
@@ -7275,7 +7379,7 @@
      * @return the map of all extras previously added with putExtra(),
      * or null if none have been added.
      */
-    public Bundle getExtras() {
+    public @Nullable Bundle getExtras() {
         return (mExtras != null)
                 ? new Bundle(mExtras)
                 : null;
@@ -7296,11 +7400,12 @@
      * normally just set them with {@link #setFlags} and let the system
      * take the appropriate action with them.
      *
-     * @return int The currently set flags.
-     *
+     * @return The currently set flags.
      * @see #setFlags
+     * @see #addFlags
+     * @see #removeFlags
      */
-    public int getFlags() {
+    public @Flags int getFlags() {
         return mFlags;
     }
 
@@ -7320,7 +7425,7 @@
      * @see #resolveActivity
      * @see #setPackage
      */
-    public String getPackage() {
+    public @Nullable String getPackage() {
         return mPackage;
     }
 
@@ -7335,7 +7440,7 @@
      * @see #resolveActivity
      * @see #setComponent
      */
-    public ComponentName getComponent() {
+    public @Nullable ComponentName getComponent() {
         return mComponent;
     }
 
@@ -7344,7 +7449,7 @@
      * used as a hint to the receiver for animations and the like.  Null means that there
      * is no source bounds.
      */
-    public Rect getSourceBounds() {
+    public @Nullable Rect getSourceBounds() {
         return mSourceBounds;
     }
 
@@ -7395,7 +7500,7 @@
      * @see #getComponent
      * @see #resolveActivityInfo
      */
-    public ComponentName resolveActivity(PackageManager pm) {
+    public ComponentName resolveActivity(@NonNull PackageManager pm) {
         if (mComponent != null) {
             return mComponent;
         }
@@ -7427,7 +7532,8 @@
      *
      * @see #resolveActivity
      */
-    public ActivityInfo resolveActivityInfo(PackageManager pm, int flags) {
+    public ActivityInfo resolveActivityInfo(@NonNull PackageManager pm,
+            @PackageManager.ComponentInfoFlags int flags) {
         ActivityInfo ai = null;
         if (mComponent != null) {
             try {
@@ -7453,7 +7559,8 @@
      * there are no matches.
      * @hide
      */
-    public ComponentName resolveSystemService(PackageManager pm, int flags) {
+    public @Nullable ComponentName resolveSystemService(@NonNull PackageManager pm,
+            @PackageManager.ComponentInfoFlags int flags) {
         if (mComponent != null) {
             return mComponent;
         }
@@ -7490,7 +7597,7 @@
      *
      * @see #getAction
      */
-    public Intent setAction(String action) {
+    public @NonNull Intent setAction(@Nullable String action) {
         mAction = action != null ? action.intern() : null;
         return this;
     }
@@ -7516,7 +7623,7 @@
      * @see #setDataAndNormalize
      * @see android.net.Uri#normalizeScheme()
      */
-    public Intent setData(Uri data) {
+    public @NonNull Intent setData(@Nullable Uri data) {
         mData = data;
         mType = null;
         return this;
@@ -7544,7 +7651,7 @@
      * @see #setType
      * @see android.net.Uri#normalizeScheme
      */
-    public Intent setDataAndNormalize(Uri data) {
+    public @NonNull Intent setDataAndNormalize(@NonNull Uri data) {
         return setData(data.normalizeScheme());
     }
 
@@ -7573,7 +7680,7 @@
      * @see #setDataAndType
      * @see #normalizeMimeType
      */
-    public Intent setType(String type) {
+    public @NonNull Intent setType(@Nullable String type) {
         mData = null;
         mType = type;
         return this;
@@ -7604,7 +7711,7 @@
      * @see #setData
      * @see #normalizeMimeType
      */
-    public Intent setTypeAndNormalize(String type) {
+    public @NonNull Intent setTypeAndNormalize(@Nullable String type) {
         return setType(normalizeMimeType(type));
     }
 
@@ -7633,7 +7740,7 @@
      * @see android.net.Uri#normalizeScheme
      * @see #setDataAndTypeAndNormalize
      */
-    public Intent setDataAndType(Uri data, String type) {
+    public @NonNull Intent setDataAndType(@Nullable Uri data, @Nullable String type) {
         mData = data;
         mType = type;
         return this;
@@ -7664,7 +7771,7 @@
      * @see #normalizeMimeType
      * @see android.net.Uri#normalizeScheme
      */
-    public Intent setDataAndTypeAndNormalize(Uri data, String type) {
+    public @NonNull Intent setDataAndTypeAndNormalize(@NonNull Uri data, @Nullable String type) {
         return setDataAndType(data.normalizeScheme(), normalizeMimeType(type));
     }
 
@@ -7684,7 +7791,7 @@
      * @see #hasCategory
      * @see #removeCategory
      */
-    public Intent addCategory(String category) {
+    public @NonNull Intent addCategory(String category) {
         if (mCategories == null) {
             mCategories = new ArraySet<String>();
         }
@@ -7739,7 +7846,7 @@
      * @param selector The desired selector Intent; set to null to not use
      * a special selector.
      */
-    public void setSelector(Intent selector) {
+    public void setSelector(@Nullable Intent selector) {
         if (selector == this) {
             throw new IllegalArgumentException(
                     "Intent being set as a selector of itself");
@@ -7778,7 +7885,7 @@
      *
      * @param clip The new clip to set.  May be null to clear the current clip.
      */
-    public void setClipData(ClipData clip) {
+    public void setClipData(@Nullable ClipData clip) {
         mClipData = clip;
     }
 
@@ -7811,7 +7918,7 @@
      * @see #removeExtra
      * @see #getBooleanExtra(String, boolean)
      */
-    public Intent putExtra(String name, boolean value) {
+    public @NonNull Intent putExtra(String name, boolean value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7834,7 +7941,7 @@
      * @see #removeExtra
      * @see #getByteExtra(String, byte)
      */
-    public Intent putExtra(String name, byte value) {
+    public @NonNull Intent putExtra(String name, byte value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7857,7 +7964,7 @@
      * @see #removeExtra
      * @see #getCharExtra(String, char)
      */
-    public Intent putExtra(String name, char value) {
+    public @NonNull Intent putExtra(String name, char value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7880,7 +7987,7 @@
      * @see #removeExtra
      * @see #getShortExtra(String, short)
      */
-    public Intent putExtra(String name, short value) {
+    public @NonNull Intent putExtra(String name, short value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7903,7 +8010,7 @@
      * @see #removeExtra
      * @see #getIntExtra(String, int)
      */
-    public Intent putExtra(String name, int value) {
+    public @NonNull Intent putExtra(String name, int value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7926,7 +8033,7 @@
      * @see #removeExtra
      * @see #getLongExtra(String, long)
      */
-    public Intent putExtra(String name, long value) {
+    public @NonNull Intent putExtra(String name, long value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7949,7 +8056,7 @@
      * @see #removeExtra
      * @see #getFloatExtra(String, float)
      */
-    public Intent putExtra(String name, float value) {
+    public @NonNull Intent putExtra(String name, float value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7972,7 +8079,7 @@
      * @see #removeExtra
      * @see #getDoubleExtra(String, double)
      */
-    public Intent putExtra(String name, double value) {
+    public @NonNull Intent putExtra(String name, double value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -7995,7 +8102,7 @@
      * @see #removeExtra
      * @see #getStringExtra(String)
      */
-    public Intent putExtra(String name, String value) {
+    public @NonNull Intent putExtra(String name, String value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8018,7 +8125,7 @@
      * @see #removeExtra
      * @see #getCharSequenceExtra(String)
      */
-    public Intent putExtra(String name, CharSequence value) {
+    public @NonNull Intent putExtra(String name, CharSequence value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8041,7 +8148,7 @@
      * @see #removeExtra
      * @see #getParcelableExtra(String)
      */
-    public Intent putExtra(String name, Parcelable value) {
+    public @NonNull Intent putExtra(String name, Parcelable value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8064,7 +8171,7 @@
      * @see #removeExtra
      * @see #getParcelableArrayExtra(String)
      */
-    public Intent putExtra(String name, Parcelable[] value) {
+    public @NonNull Intent putExtra(String name, Parcelable[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8087,7 +8194,8 @@
      * @see #removeExtra
      * @see #getParcelableArrayListExtra(String)
      */
-    public Intent putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value) {
+    public @NonNull Intent putParcelableArrayListExtra(String name,
+            ArrayList<? extends Parcelable> value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8110,7 +8218,7 @@
      * @see #removeExtra
      * @see #getIntegerArrayListExtra(String)
      */
-    public Intent putIntegerArrayListExtra(String name, ArrayList<Integer> value) {
+    public @NonNull Intent putIntegerArrayListExtra(String name, ArrayList<Integer> value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8133,7 +8241,7 @@
      * @see #removeExtra
      * @see #getStringArrayListExtra(String)
      */
-    public Intent putStringArrayListExtra(String name, ArrayList<String> value) {
+    public @NonNull Intent putStringArrayListExtra(String name, ArrayList<String> value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8156,7 +8264,8 @@
      * @see #removeExtra
      * @see #getCharSequenceArrayListExtra(String)
      */
-    public Intent putCharSequenceArrayListExtra(String name, ArrayList<CharSequence> value) {
+    public @NonNull Intent putCharSequenceArrayListExtra(String name,
+            ArrayList<CharSequence> value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8179,7 +8288,7 @@
      * @see #removeExtra
      * @see #getSerializableExtra(String)
      */
-    public Intent putExtra(String name, Serializable value) {
+    public @NonNull Intent putExtra(String name, Serializable value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8202,7 +8311,7 @@
      * @see #removeExtra
      * @see #getBooleanArrayExtra(String)
      */
-    public Intent putExtra(String name, boolean[] value) {
+    public @NonNull Intent putExtra(String name, boolean[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8225,7 +8334,7 @@
      * @see #removeExtra
      * @see #getByteArrayExtra(String)
      */
-    public Intent putExtra(String name, byte[] value) {
+    public @NonNull Intent putExtra(String name, byte[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8248,7 +8357,7 @@
      * @see #removeExtra
      * @see #getShortArrayExtra(String)
      */
-    public Intent putExtra(String name, short[] value) {
+    public @NonNull Intent putExtra(String name, short[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8271,7 +8380,7 @@
      * @see #removeExtra
      * @see #getCharArrayExtra(String)
      */
-    public Intent putExtra(String name, char[] value) {
+    public @NonNull Intent putExtra(String name, char[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8294,7 +8403,7 @@
      * @see #removeExtra
      * @see #getIntArrayExtra(String)
      */
-    public Intent putExtra(String name, int[] value) {
+    public @NonNull Intent putExtra(String name, int[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8317,7 +8426,7 @@
      * @see #removeExtra
      * @see #getLongArrayExtra(String)
      */
-    public Intent putExtra(String name, long[] value) {
+    public @NonNull Intent putExtra(String name, long[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8340,7 +8449,7 @@
      * @see #removeExtra
      * @see #getFloatArrayExtra(String)
      */
-    public Intent putExtra(String name, float[] value) {
+    public @NonNull Intent putExtra(String name, float[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8363,7 +8472,7 @@
      * @see #removeExtra
      * @see #getDoubleArrayExtra(String)
      */
-    public Intent putExtra(String name, double[] value) {
+    public @NonNull Intent putExtra(String name, double[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8386,7 +8495,7 @@
      * @see #removeExtra
      * @see #getStringArrayExtra(String)
      */
-    public Intent putExtra(String name, String[] value) {
+    public @NonNull Intent putExtra(String name, String[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8409,7 +8518,7 @@
      * @see #removeExtra
      * @see #getCharSequenceArrayExtra(String)
      */
-    public Intent putExtra(String name, CharSequence[] value) {
+    public @NonNull Intent putExtra(String name, CharSequence[] value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8432,7 +8541,7 @@
      * @see #removeExtra
      * @see #getBundleExtra(String)
      */
-    public Intent putExtra(String name, Bundle value) {
+    public @NonNull Intent putExtra(String name, Bundle value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8459,7 +8568,7 @@
      * @hide
      */
     @Deprecated
-    public Intent putExtra(String name, IBinder value) {
+    public @NonNull Intent putExtra(String name, IBinder value) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8474,7 +8583,7 @@
      *
      * @see #putExtra
      */
-    public Intent putExtras(Intent src) {
+    public @NonNull Intent putExtras(@NonNull Intent src) {
         if (src.mExtras != null) {
             if (mExtras == null) {
                 mExtras = new Bundle(src.mExtras);
@@ -8495,7 +8604,7 @@
      * @see #putExtra
      * @see #removeExtra
      */
-    public Intent putExtras(Bundle extras) {
+    public @NonNull Intent putExtras(@NonNull Bundle extras) {
         if (mExtras == null) {
             mExtras = new Bundle();
         }
@@ -8510,7 +8619,7 @@
      * @param src The exact extras contained in this Intent are copied
      * into the target intent, replacing any that were previously there.
      */
-    public Intent replaceExtras(Intent src) {
+    public @NonNull Intent replaceExtras(@NonNull Intent src) {
         mExtras = src.mExtras != null ? new Bundle(src.mExtras) : null;
         return this;
     }
@@ -8522,7 +8631,7 @@
      * @param extras The new set of extras in the Intent, or null to erase
      * all extras.
      */
-    public Intent replaceExtras(Bundle extras) {
+    public @NonNull Intent replaceExtras(@NonNull Bundle extras) {
         mExtras = extras != null ? new Bundle(extras) : null;
         return this;
     }
@@ -8555,41 +8664,13 @@
      * the behavior of your application.
      *
      * @param flags The desired flags.
-     *
      * @return Returns the same Intent object, for chaining multiple calls
      * into a single statement.
-     *
      * @see #getFlags
      * @see #addFlags
      * @see #removeFlags
-     *
-     * @see #FLAG_GRANT_READ_URI_PERMISSION
-     * @see #FLAG_GRANT_WRITE_URI_PERMISSION
-     * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-     * @see #FLAG_GRANT_PREFIX_URI_PERMISSION
-     * @see #FLAG_DEBUG_LOG_RESOLUTION
-     * @see #FLAG_FROM_BACKGROUND
-     * @see #FLAG_ACTIVITY_BROUGHT_TO_FRONT
-     * @see #FLAG_ACTIVITY_CLEAR_TASK
-     * @see #FLAG_ACTIVITY_CLEAR_TOP
-     * @see #FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
-     * @see #FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-     * @see #FLAG_ACTIVITY_FORWARD_RESULT
-     * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-     * @see #FLAG_ACTIVITY_MULTIPLE_TASK
-     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
-     * @see #FLAG_ACTIVITY_NEW_TASK
-     * @see #FLAG_ACTIVITY_NO_ANIMATION
-     * @see #FLAG_ACTIVITY_NO_HISTORY
-     * @see #FLAG_ACTIVITY_NO_USER_ACTION
-     * @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
-     * @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-     * @see #FLAG_ACTIVITY_REORDER_TO_FRONT
-     * @see #FLAG_ACTIVITY_SINGLE_TOP
-     * @see #FLAG_ACTIVITY_TASK_ON_HOME
-     * @see #FLAG_RECEIVER_REGISTERED_ONLY
      */
-    public Intent setFlags(int flags) {
+    public @NonNull Intent setFlags(@Flags int flags) {
         mFlags = flags;
         return this;
     }
@@ -8600,36 +8681,11 @@
      * @param flags The new flags to set.
      * @return Returns the same Intent object, for chaining multiple calls into
      *         a single statement.
-     * @see #setFlags(int)
-     * @see #removeFlags(int)
-     *
-     * @see #FLAG_GRANT_READ_URI_PERMISSION
-     * @see #FLAG_GRANT_WRITE_URI_PERMISSION
-     * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-     * @see #FLAG_GRANT_PREFIX_URI_PERMISSION
-     * @see #FLAG_DEBUG_LOG_RESOLUTION
-     * @see #FLAG_FROM_BACKGROUND
-     * @see #FLAG_ACTIVITY_BROUGHT_TO_FRONT
-     * @see #FLAG_ACTIVITY_CLEAR_TASK
-     * @see #FLAG_ACTIVITY_CLEAR_TOP
-     * @see #FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
-     * @see #FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-     * @see #FLAG_ACTIVITY_FORWARD_RESULT
-     * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-     * @see #FLAG_ACTIVITY_MULTIPLE_TASK
-     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
-     * @see #FLAG_ACTIVITY_NEW_TASK
-     * @see #FLAG_ACTIVITY_NO_ANIMATION
-     * @see #FLAG_ACTIVITY_NO_HISTORY
-     * @see #FLAG_ACTIVITY_NO_USER_ACTION
-     * @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
-     * @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-     * @see #FLAG_ACTIVITY_REORDER_TO_FRONT
-     * @see #FLAG_ACTIVITY_SINGLE_TOP
-     * @see #FLAG_ACTIVITY_TASK_ON_HOME
-     * @see #FLAG_RECEIVER_REGISTERED_ONLY
+     * @see #setFlags
+     * @see #getFlags
+     * @see #removeFlags
      */
-    public Intent addFlags(int flags) {
+    public @NonNull Intent addFlags(@Flags int flags) {
         mFlags |= flags;
         return this;
     }
@@ -8638,36 +8694,11 @@
      * Remove these flags from the intent.
      *
      * @param flags The flags to remove.
-     * @see #setFlags(int)
-     * @see #addFlags(int)
-     *
-     * @see #FLAG_GRANT_READ_URI_PERMISSION
-     * @see #FLAG_GRANT_WRITE_URI_PERMISSION
-     * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-     * @see #FLAG_GRANT_PREFIX_URI_PERMISSION
-     * @see #FLAG_DEBUG_LOG_RESOLUTION
-     * @see #FLAG_FROM_BACKGROUND
-     * @see #FLAG_ACTIVITY_BROUGHT_TO_FRONT
-     * @see #FLAG_ACTIVITY_CLEAR_TASK
-     * @see #FLAG_ACTIVITY_CLEAR_TOP
-     * @see #FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
-     * @see #FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-     * @see #FLAG_ACTIVITY_FORWARD_RESULT
-     * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
-     * @see #FLAG_ACTIVITY_MULTIPLE_TASK
-     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
-     * @see #FLAG_ACTIVITY_NEW_TASK
-     * @see #FLAG_ACTIVITY_NO_ANIMATION
-     * @see #FLAG_ACTIVITY_NO_HISTORY
-     * @see #FLAG_ACTIVITY_NO_USER_ACTION
-     * @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
-     * @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-     * @see #FLAG_ACTIVITY_REORDER_TO_FRONT
-     * @see #FLAG_ACTIVITY_SINGLE_TOP
-     * @see #FLAG_ACTIVITY_TASK_ON_HOME
-     * @see #FLAG_RECEIVER_REGISTERED_ONLY
+     * @see #setFlags
+     * @see #getFlags
+     * @see #addFlags
      */
-    public void removeFlags(int flags) {
+    public void removeFlags(@Flags int flags) {
         mFlags &= ~flags;
     }
 
@@ -8687,7 +8718,7 @@
      * @see #getPackage
      * @see #resolveActivity
      */
-    public Intent setPackage(String packageName) {
+    public @NonNull Intent setPackage(@Nullable String packageName) {
         if (packageName != null && mSelector != null) {
             throw new IllegalArgumentException(
                     "Can't set package name when selector is already set");
@@ -8719,7 +8750,7 @@
      * @see #getComponent
      * @see #resolveActivity
      */
-    public Intent setComponent(ComponentName component) {
+    public @NonNull Intent setComponent(@Nullable ComponentName component) {
         mComponent = component;
         return this;
     }
@@ -8739,7 +8770,8 @@
      * @see #setComponent
      * @see #setClass
      */
-    public Intent setClassName(Context packageContext, String className) {
+    public @NonNull Intent setClassName(@NonNull Context packageContext,
+            @NonNull String className) {
         mComponent = new ComponentName(packageContext, className);
         return this;
     }
@@ -8759,7 +8791,7 @@
      * @see #setComponent
      * @see #setClass
      */
-    public Intent setClassName(String packageName, String className) {
+    public @NonNull Intent setClassName(@NonNull String packageName, @NonNull String className) {
         mComponent = new ComponentName(packageName, className);
         return this;
     }
@@ -8778,7 +8810,7 @@
      *
      * @see #setComponent
      */
-    public Intent setClass(Context packageContext, Class<?> cls) {
+    public @NonNull Intent setClass(@NonNull Context packageContext, @NonNull Class<?> cls) {
         mComponent = new ComponentName(packageContext, cls);
         return this;
     }
@@ -8788,7 +8820,7 @@
      * used as a hint to the receiver for animations and the like.  Null means that there
      * is no source bounds.
      */
-    public void setSourceBounds(Rect r) {
+    public void setSourceBounds(@Nullable Rect r) {
         if (r != null) {
             mSourceBounds = new Rect(r);
         } else {
@@ -8909,7 +8941,7 @@
      * changed.
      */
     @FillInFlags
-    public int fillIn(Intent other, @FillInFlags int flags) {
+    public int fillIn(@NonNull Intent other, @FillInFlags int flags) {
         int changes = 0;
         boolean mayHaveCopiedUris = false;
         if (other.mAction != null
@@ -9257,13 +9289,12 @@
      * <p>You can convert the returned string back to an Intent with
      * {@link #getIntent}.
      *
-     * @param flags Additional operating flags.  Either 0,
-     * {@link #URI_INTENT_SCHEME}, or {@link #URI_ANDROID_APP_SCHEME}.
+     * @param flags Additional operating flags.
      *
      * @return Returns a URI encoding URI string describing the entire contents
      * of the Intent.
      */
-    public String toUri(int flags) {
+    public String toUri(@UriFlags int flags) {
         StringBuilder uri = new StringBuilder(128);
         if ((flags&URI_ANDROID_APP_SCHEME) != 0) {
             if (mPackage == null) {
@@ -9530,7 +9561,8 @@
      * @throws XmlPullParserException If there was an XML parsing error.
      * @throws IOException If there was an I/O error.
      */
-    public static Intent parseIntent(Resources resources, XmlPullParser parser, AttributeSet attrs)
+    public static @NonNull Intent parseIntent(@NonNull Resources resources,
+            @NonNull XmlPullParser parser, AttributeSet attrs)
             throws XmlPullParserException, IOException {
         Intent intent = new Intent();
 
@@ -9677,7 +9709,7 @@
      * @see #setType
      * @see #setTypeAndNormalize
      */
-    public static String normalizeMimeType(String type) {
+    public static @Nullable String normalizeMimeType(@Nullable String type) {
         if (type == null) {
             return null;
         }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 47d79cf..ecaf7eb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -522,6 +522,18 @@
      */
     public static final int PERMISSION_DENIED = -1;
 
+    /** @hide */
+    @IntDef(prefix = { "SIGNATURE_" }, value = {
+            SIGNATURE_MATCH,
+            SIGNATURE_NEITHER_SIGNED,
+            SIGNATURE_FIRST_NOT_SIGNED,
+            SIGNATURE_SECOND_NOT_SIGNED,
+            SIGNATURE_NO_MATCH,
+            SIGNATURE_UNKNOWN_PACKAGE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SignatureResult {}
+
     /**
      * Signature check result: this is returned by {@link #checkSignatures}
      * if all signatures on the two packages match.
@@ -558,11 +570,25 @@
      */
     public static final int SIGNATURE_UNKNOWN_PACKAGE = -4;
 
+    /** @hide */
+    @IntDef(prefix = { "COMPONENT_ENABLED_STATE_" }, value = {
+            COMPONENT_ENABLED_STATE_DEFAULT,
+            COMPONENT_ENABLED_STATE_ENABLED,
+            COMPONENT_ENABLED_STATE_DISABLED,
+            COMPONENT_ENABLED_STATE_DISABLED_USER,
+            COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EnabledState {}
+
     /**
-     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
-     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
-     * component or application is in its default enabled state (as specified
-     * in its manifest).
+     * Flag for {@link #setApplicationEnabledSetting(String, int, int)} and
+     * {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
+     * component or application is in its default enabled state (as specified in
+     * its manifest).
+     * <p>
+     * Explicitly setting the component state to this value restores it's
+     * enabled state to whatever is set in the manifest.
      */
     public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
 
@@ -764,6 +790,13 @@
      */
     public static final int INSTALL_ALLOCATE_AGGRESSIVE = 0x00008000;
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
+            DONT_KILL_APP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EnabledFlags {}
+
     /**
      * Flag parameter for
      * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
@@ -2871,7 +2904,7 @@
      * does not contain such an activity, or if <em>packageName</em> is not
      * recognized.
      */
-    public abstract Intent getLaunchIntentForPackage(String packageName);
+    public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName);
 
     /**
      * Return a "good" intent to launch a front-door Leanback activity in a
@@ -2885,7 +2918,7 @@
      *         the main Leanback activity in the package, or null if the package
      *         does not contain such an activity.
      */
-    public abstract Intent getLeanbackLaunchIntentForPackage(String packageName);
+    public abstract @Nullable Intent getLeanbackLaunchIntentForPackage(@NonNull String packageName);
 
     /**
      * Return an array of all of the POSIX secondary group IDs that have been
@@ -2901,7 +2934,7 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract int[] getPackageGids(String packageName)
+    public abstract int[] getPackageGids(@NonNull String packageName)
             throws NameNotFoundException;
 
     /**
@@ -3189,7 +3222,7 @@
      * @see #PERMISSION_DENIED
      */
     @CheckResult
-    public abstract int checkPermission(String permName, String pkgName);
+    public abstract @PermissionResult int checkPermission(String permName, String pkgName);
 
     /**
      * Checks whether a particular permissions has been revoked for a
@@ -3419,12 +3452,9 @@
      * #SIGNATURE_NO_MATCH} or {@link #SIGNATURE_UNKNOWN_PACKAGE}).
      *
      * @see #checkSignatures(int, int)
-     * @see #SIGNATURE_MATCH
-     * @see #SIGNATURE_NO_MATCH
-     * @see #SIGNATURE_UNKNOWN_PACKAGE
      */
     @CheckResult
-    public abstract int checkSignatures(String pkg1, String pkg2);
+    public abstract @SignatureResult int checkSignatures(String pkg1, String pkg2);
 
     /**
      * Like {@link #checkSignatures(String, String)}, but takes UIDs of
@@ -3442,12 +3472,9 @@
      * #SIGNATURE_NO_MATCH} or {@link #SIGNATURE_UNKNOWN_PACKAGE}).
      *
      * @see #checkSignatures(String, String)
-     * @see #SIGNATURE_MATCH
-     * @see #SIGNATURE_NO_MATCH
-     * @see #SIGNATURE_UNKNOWN_PACKAGE
      */
     @CheckResult
-    public abstract int checkSignatures(int uid1, int uid2);
+    public abstract @SignatureResult int checkSignatures(int uid1, int uid2);
 
     /**
      * Retrieve the names of all packages that are associated with a particular
@@ -3881,8 +3908,8 @@
      *         included by one of the <var>specifics</var> intents. If there are
      *         no matching activities, an empty list is returned.
      */
-    public abstract List<ResolveInfo> queryIntentActivityOptions(
-            ComponentName caller, Intent[] specifics, Intent intent, @ResolveInfoFlags int flags);
+    public abstract List<ResolveInfo> queryIntentActivityOptions(@Nullable ComponentName caller,
+            @Nullable Intent[] specifics, Intent intent, @ResolveInfoFlags int flags);
 
     /**
      * Retrieve all receivers that can handle a broadcast of the given intent.
@@ -5136,18 +5163,11 @@
      * manifest.
      *
      * @param componentName The component to enable
-     * @param newState The new enabled state for the component.  The legal values for this state
-     *                 are:
-     *                   {@link #COMPONENT_ENABLED_STATE_ENABLED},
-     *                   {@link #COMPONENT_ENABLED_STATE_DISABLED}
-     *                   and
-     *                   {@link #COMPONENT_ENABLED_STATE_DEFAULT}
-     *                 The last one removes the setting, thereby restoring the component's state to
-     *                 whatever was set in it's manifest (or enabled, by default).
-     * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
+     * @param newState The new enabled state for the component.
+     * @param flags Optional behavior flags.
      */
     public abstract void setComponentEnabledSetting(ComponentName componentName,
-            int newState, int flags);
+            @EnabledState int newState, @EnabledFlags int flags);
 
     /**
      * Return the enabled setting for a package component (activity,
@@ -5157,14 +5177,10 @@
      * the value originally specified in the manifest has not been modified.
      *
      * @param componentName The component to retrieve.
-     * @return Returns the current enabled state for the component.  May
-     * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
-     * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
-     * {@link #COMPONENT_ENABLED_STATE_DEFAULT}.  The last one means the
-     * component's enabled state is based on the original information in
-     * the manifest as found in {@link ComponentInfo}.
+     * @return Returns the current enabled state for the component.
      */
-    public abstract int getComponentEnabledSetting(ComponentName componentName);
+    public abstract @EnabledState int getComponentEnabledSetting(
+            ComponentName componentName);
 
     /**
      * Set the enabled setting for an application
@@ -5174,18 +5190,11 @@
      * {@link #setComponentEnabledSetting} for any of the application's components.
      *
      * @param packageName The package name of the application to enable
-     * @param newState The new enabled state for the component.  The legal values for this state
-     *                 are:
-     *                   {@link #COMPONENT_ENABLED_STATE_ENABLED},
-     *                   {@link #COMPONENT_ENABLED_STATE_DISABLED}
-     *                   and
-     *                   {@link #COMPONENT_ENABLED_STATE_DEFAULT}
-     *                 The last one removes the setting, thereby restoring the applications's state to
-     *                 whatever was set in its manifest (or enabled, by default).
-     * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
+     * @param newState The new enabled state for the application.
+     * @param flags Optional behavior flags.
      */
     public abstract void setApplicationEnabledSetting(String packageName,
-            int newState, int flags);
+            @EnabledState int newState, @EnabledFlags int flags);
 
     /**
      * Return the enabled setting for an application. This returns
@@ -5195,15 +5204,10 @@
      * the value originally specified in the manifest has not been modified.
      *
      * @param packageName The package name of the application to retrieve.
-     * @return Returns the current enabled state for the application.  May
-     * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
-     * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
-     * {@link #COMPONENT_ENABLED_STATE_DEFAULT}.  The last one means the
-     * application's enabled state is based on the original information in
-     * the manifest as found in {@link ApplicationInfo}.
+     * @return Returns the current enabled state for the application.
      * @throws IllegalArgumentException if the named package does not exist.
      */
-    public abstract int getApplicationEnabledSetting(String packageName);
+    public abstract @EnabledState int getApplicationEnabledSetting(String packageName);
 
     /**
      * Flush the package restrictions for a given user to disk. This forces the package restrictions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1f78bff..8609351 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -145,7 +145,12 @@
     private static final boolean DEBUG_PARSER = false;
     private static final boolean DEBUG_BACKUP = false;
 
-    private static final boolean MULTI_PACKAGE_APK_ENABLED = false;
+    private static final String PROPERTY_CHILD_PACKAGES_ENABLED =
+            "persist.sys.child_packages_enabled";
+
+    private static final boolean MULTI_PACKAGE_APK_ENABLED =
+            SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
+
     private static final int MAX_PACKAGES_PER_APK = 5;
 
     public static final int APK_SIGNING_UNKNOWN = 0;
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 10c4cb3..f5ad5cc 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -322,7 +322,10 @@
 
         if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
             synchronized(mTriggerListeners) {
-                for (TriggerEventListener l: mTriggerListeners.keySet()) {
+                HashMap<TriggerEventListener, TriggerEventQueue> triggerListeners =
+                    new HashMap<TriggerEventListener, TriggerEventQueue>(mTriggerListeners);
+
+                for (TriggerEventListener l: triggerListeners.keySet()) {
                     if (DEBUG_DYNAMIC_SENSOR){
                         Log.i(TAG, "removed trigger listener" + l.toString() +
                                    " due to sensor disconnection");
@@ -332,7 +335,10 @@
             }
         } else {
             synchronized(mSensorListeners) {
-                for (SensorEventListener l: mSensorListeners.keySet()) {
+                HashMap<SensorEventListener, SensorEventQueue> sensorListeners =
+                    new HashMap<SensorEventListener, SensorEventQueue>(mSensorListeners);
+
+                for (SensorEventListener l: sensorListeners.keySet()) {
                     if (DEBUG_DYNAMIC_SENSOR){
                         Log.i(TAG, "removed event listener" + l.toString() +
                                    " due to sensor disconnection");
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 7bfb5d0..211d54d 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -135,7 +135,7 @@
 
      /** @hide */
      @Retention(RetentionPolicy.SOURCE)
-     @IntDef(
+     @IntDef(prefix = {"TEMPLATE_"}, value =
          {TEMPLATE_PREVIEW,
           TEMPLATE_STILL_CAPTURE,
           TEMPLATE_RECORD,
@@ -757,7 +757,7 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
+    @IntDef(prefix = {"SESSION_OPERATION_MODE"}, value =
             {SESSION_OPERATION_MODE_NORMAL,
              SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED,
              SESSION_OPERATION_MODE_VENDOR_START})
@@ -808,10 +808,9 @@
      * create a builder specific for that device and template and override the
      * settings as desired, instead.</p>
      *
-     * @param templateType An enumeration selecting the use case for this
-     * request; one of the CameraDevice.TEMPLATE_ values. Not all template
-     * types are supported on every device. See the documentation for each
-     * template type for details.
+     * @param templateType An enumeration selecting the use case for this request. Not all template
+     * types are supported on every device. See the documentation for each template type for
+     * details.
      * @return a builder for a capture request, initialized with default
      * settings for that template, and no output streams
      *
@@ -969,7 +968,7 @@
 
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
-        @IntDef(
+        @IntDef(prefix = {"ERROR_"}, value =
             {ERROR_CAMERA_IN_USE,
              ERROR_MAX_CAMERAS_IN_USE,
              ERROR_CAMERA_DISABLED,
@@ -1052,8 +1051,7 @@
          * this happens. Further attempts at recovery are error-code specific.</p>
          *
          * @param camera The device reporting the error
-         * @param error The error code, one of the
-         *     {@code StateCallback.ERROR_*} values.
+         * @param error The error code.
          *
          * @see #ERROR_CAMERA_IN_USE
          * @see #ERROR_MAX_CAMERAS_IN_USE
diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java
index 8bb33f1..fbe0839 100644
--- a/core/java/android/hardware/camera2/CaptureFailure.java
+++ b/core/java/android/hardware/camera2/CaptureFailure.java
@@ -51,7 +51,7 @@
 
      /** @hide */
      @Retention(RetentionPolicy.SOURCE)
-     @IntDef(
+     @IntDef(prefix = {"REASON_"}, value =
          {REASON_ERROR,
           REASON_FLUSHED })
      public @interface FailureReason {};
@@ -119,7 +119,7 @@
      * Determine why the request was dropped, whether due to an error or to a user
      * action.
      *
-     * @return int One of {@code REASON_*} integer constants.
+     * @return int The reason code.
      *
      * @see #REASON_ERROR
      * @see #REASON_FLUSHED
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 1cf8f03..279d73d 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1662,9 +1662,13 @@
      * <p>The output images for request B may have contents captured before the output images for
      * request A, and the result metadata for request B may be older than the result metadata for
      * request A.</p>
-     * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in the
-     * past for requests with STILL_CAPTURE capture intent.</p>
-     * <p>The value of enableZsl in capture templates is always <code>false</code> if present.</p>
+     * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in
+     * the past for requests with STILL_CAPTURE capture intent.</p>
+     * <p>For applications targeting SDK versions O and newer, the value of enableZsl in
+     * TEMPLATE_STILL_CAPTURE template may be <code>true</code>. The value in other templates is always
+     * <code>false</code> if present.</p>
+     * <p>For applications targeting SDK versions older than O, the value of enableZsl in all
+     * capture templates is always <code>false</code> if present.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 419e3e2..aedfc4b 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2167,9 +2167,13 @@
      * <p>The output images for request B may have contents captured before the output images for
      * request A, and the result metadata for request B may be older than the result metadata for
      * request A.</p>
-     * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in the
-     * past for requests with STILL_CAPTURE capture intent.</p>
-     * <p>The value of enableZsl in capture templates is always <code>false</code> if present.</p>
+     * <p>Note that when enableZsl is <code>true</code>, it is not guaranteed to get output images captured in
+     * the past for requests with STILL_CAPTURE capture intent.</p>
+     * <p>For applications targeting SDK versions O and newer, the value of enableZsl in
+     * TEMPLATE_STILL_CAPTURE template may be <code>true</code>. The value in other templates is always
+     * <code>false</code> if present.</p>
+     * <p>For applications targeting SDK versions older than O, the value of enableZsl in all
+     * capture templates is always <code>false</code> if present.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index ae92457..b2a2aaf 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -17,9 +17,9 @@
 
 package android.hardware.usb;
 
-import com.android.internal.util.Preconditions;
-
 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;
@@ -30,6 +30,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.util.HashMap;
 
 /**
@@ -109,6 +111,7 @@
      * for the attached device
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_USB_DEVICE_ATTACHED =
             "android.hardware.usb.action.USB_DEVICE_ATTACHED";
 
@@ -121,6 +124,7 @@
      * for the detached device
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_USB_DEVICE_DETACHED =
             "android.hardware.usb.action.USB_DEVICE_DETACHED";
 
@@ -133,6 +137,7 @@
      * for the attached accessory
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_USB_ACCESSORY_ATTACHED =
             "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
 
@@ -145,6 +150,7 @@
      * for the attached accessory that was detached
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_USB_ACCESSORY_DETACHED =
             "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
 
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 768beea..b854cbf 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -19,6 +19,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -742,8 +743,6 @@
 
     /**
      * Retrieves the current preferred network type.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an integer representing the preferred network type
      *
@@ -753,6 +752,7 @@
      *             the networks to describe their precedence.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public int getNetworkPreference() {
         return TYPE_NONE;
     }
@@ -763,12 +763,11 @@
      * You should always check {@link NetworkInfo#isConnected()} before initiating
      * network traffic. This may return {@code null} when there is no default
      * network.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return a {@link NetworkInfo} object for the current default network
      *        or {@code null} if no default network is currently active
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo getActiveNetworkInfo() {
         try {
             return mService.getActiveNetworkInfo();
@@ -783,12 +782,11 @@
      * network disconnects, the returned {@code Network} object will no longer
      * be usable.  This will return {@code null} when there is no default
      * network.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return a {@link Network} object for the current default network or
      *        {@code null} if no default network is currently active
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public Network getActiveNetwork() {
         try {
             return mService.getActiveNetwork();
@@ -803,14 +801,13 @@
      * network disconnects, the returned {@code Network} object will no longer
      * be usable.  This will return {@code null} when there is no default
      * network for the UID.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
      *
      * @return a {@link Network} object for the current default network for the
      *         given UID or {@code null} if no default network is currently active
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public Network getActiveNetworkForUid(int uid) {
         return getActiveNetworkForUid(uid, false);
     }
@@ -871,8 +868,6 @@
      * Returns details about the currently active default data network
      * for a given uid.  This is for internal use only to avoid spying
      * other apps.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
      *
      * @return a {@link NetworkInfo} object for the current default network
      *        for the given uid or {@code null} if no default network is
@@ -880,6 +875,7 @@
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
         return getActiveNetworkInfoForUid(uid, false);
     }
@@ -896,8 +892,6 @@
     /**
      * Returns connection status information about a particular
      * network type.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param networkType integer specifying which networkType in
      *        which you're interested.
@@ -910,6 +904,7 @@
      *             {@link #getNetworkInfo(android.net.Network)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo getNetworkInfo(int networkType) {
         try {
             return mService.getNetworkInfo(networkType);
@@ -921,8 +916,6 @@
     /**
      * Returns connection status information about a particular
      * Network.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param network {@link Network} specifying which network
      *        in which you're interested.
@@ -930,6 +923,7 @@
      *        network or {@code null} if the {@code Network}
      *        is not valid.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo getNetworkInfo(Network network) {
         return getNetworkInfoForUid(network, Process.myUid(), false);
     }
@@ -946,8 +940,6 @@
     /**
      * Returns connection status information about all network
      * types supported by the device.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of {@link NetworkInfo} objects.  Check each
      * {@link NetworkInfo#getType} for which type each applies.
@@ -957,6 +949,7 @@
      *             {@link #getNetworkInfo(android.net.Network)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo[] getAllNetworkInfo() {
         try {
             return mService.getAllNetworkInfo();
@@ -969,15 +962,13 @@
      * Returns the {@link Network} object currently serving a given type, or
      * null if the given type is not connected.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
-     *
      * @hide
      * @deprecated This method does not support multiple connected networks
      *             of the same type. Use {@link #getAllNetworks} and
      *             {@link #getNetworkInfo(android.net.Network)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public Network getNetworkForType(int networkType) {
         try {
             return mService.getNetworkForType(networkType);
@@ -989,11 +980,10 @@
     /**
      * Returns an array of all {@link Network} currently tracked by the
      * framework.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of {@link Network} objects.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public Network[] getAllNetworks() {
         try {
             return mService.getAllNetworks();
@@ -1017,8 +1007,6 @@
 
     /**
      * Returns the IP information for the current default network.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return a {@link LinkProperties} object describing the IP info
      *        for the current default network, or {@code null} if there
@@ -1026,6 +1014,7 @@
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public LinkProperties getActiveLinkProperties() {
         try {
             return mService.getActiveLinkProperties();
@@ -1036,8 +1025,6 @@
 
     /**
      * Returns the IP information for a given network type.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param networkType the network type of interest.
      * @return a {@link LinkProperties} object describing the IP info
@@ -1051,6 +1038,7 @@
      *             {@link #getLinkProperties(android.net.Network)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public LinkProperties getLinkProperties(int networkType) {
         try {
             return mService.getLinkPropertiesForType(networkType);
@@ -1062,12 +1050,11 @@
     /**
      * Get the {@link LinkProperties} for the given {@link Network}.  This
      * will return {@code null} if the network is unknown.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param network The {@link Network} object identifying the network in question.
      * @return The {@link LinkProperties} for the network, or {@code null}.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public LinkProperties getLinkProperties(Network network) {
         try {
             return mService.getLinkProperties(network);
@@ -1079,12 +1066,11 @@
     /**
      * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}.  This
      * will return {@code null} if the network is unknown.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param network The {@link Network} object identifying the network in question.
      * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkCapabilities getNetworkCapabilities(Network network) {
         try {
             return mService.getNetworkCapabilities(network);
@@ -1727,11 +1713,9 @@
      * network is active. Quota status can change rapidly, so these values
      * shouldn't be cached.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
-     *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
         try {
             return mService.getActiveNetworkQuotaInfo();
@@ -1929,13 +1913,12 @@
     /**
      * Get the set of tetherable, available interfaces.  This list is limited by
      * device configuration and current interface existence.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more Strings of tetherable interface names.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetherableIfaces() {
         try {
             return mService.getTetherableIfaces();
@@ -1946,13 +1929,12 @@
 
     /**
      * Get the set of tethered interfaces.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more String of currently tethered interface names.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetheredIfaces() {
         try {
             return mService.getTetheredIfaces();
@@ -1968,14 +1950,13 @@
      * may cause them to reset to the available state.
      * {@link ConnectivityManager#getLastTetherError} can be used to get more
      * information on the cause of the errors.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more String indicating the interface names
      *        which failed to tether.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetheringErroredIfaces() {
         try {
             return mService.getTetheringErroredIfaces();
@@ -2060,14 +2041,13 @@
      * Check if the device allows for tethering.  It may be disabled via
      * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
      * due to device configuration.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return a boolean - {@code true} indicating Tethering is supported.
      *
      * {@hide}
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public boolean isTetheringSupported() {
         try {
             return mService.isTetheringSupported();
@@ -2171,14 +2151,13 @@
      * Get the list of regular expressions that define any tetherable
      * USB network interfaces.  If USB tethering is not supported by the
      * device, this list should be empty.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more regular expression Strings defining
      *        what interfaces are considered tetherable usb interfaces.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetherableUsbRegexs() {
         try {
             return mService.getTetherableUsbRegexs();
@@ -2191,14 +2170,13 @@
      * Get the list of regular expressions that define any tetherable
      * Wifi network interfaces.  If Wifi tethering is not supported by the
      * device, this list should be empty.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more regular expression Strings defining
      *        what interfaces are considered tetherable wifi interfaces.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetherableWifiRegexs() {
         try {
             return mService.getTetherableWifiRegexs();
@@ -2211,14 +2189,13 @@
      * Get the list of regular expressions that define any tetherable
      * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
      * device, this list should be empty.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return an array of 0 or more regular expression Strings defining
      *        what interfaces are considered tetherable bluetooth interfaces.
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public String[] getTetherableBluetoothRegexs() {
         try {
             return mService.getTetherableBluetoothRegexs();
@@ -2280,8 +2257,6 @@
     /**
      * Get a more detailed error code after a Tethering or Untethering
      * request asynchronously failed.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param iface The name of the interface of interest
      * @return error The error code of the last error tethering or untethering the named
@@ -2289,6 +2264,7 @@
      *
      * {@hide}
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public int getLastTetherError(String iface) {
         try {
             return mService.getLastTetherError(iface);
@@ -2362,13 +2338,12 @@
      * for typical HTTP proxies - they are general network dependent.  However if you're
      * doing something unusual like general internal filtering this may be useful.  On
      * a private network where the proxy is not accessible, you may break HTTP using this.
-     * <p>This method requires the caller to hold the permission
-     * android.Manifest.permission#CONNECTIVITY_INTERNAL.
      *
      * @param p A {@link ProxyInfo} object defining the new global
      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public void setGlobalProxy(ProxyInfo p) {
         try {
             mService.setGlobalProxy(p);
@@ -2434,14 +2409,13 @@
      * hardware supports it.  For example a GSM phone without a SIM
      * should still return {@code true} for mobile data, but a wifi only
      * tablet would return {@code false}.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param networkType The network type we'd like to check
      * @return {@code true} if supported, else {@code false}
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public boolean isNetworkSupported(int networkType) {
         try {
             return mService.isNetworkSupported(networkType);
@@ -2457,12 +2431,11 @@
      * battery/performance issues. You should check this before doing large
      * data transfers, and warn the user or delay the operation until another
      * network is available.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @return {@code true} if large transfers should be avoided, otherwise
      *        {@code false}.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public boolean isActiveNetworkMetered() {
         try {
             return mService.isActiveNetworkMetered();
@@ -2541,13 +2514,12 @@
 
     /**
      * Set the value for enabling/disabling airplane mode
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
      *
      * @param enable whether to enable airplane mode or not
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public void setAirplaneMode(boolean enable) {
         try {
             mService.setAirplaneMode(enable);
@@ -3225,14 +3197,13 @@
      * Registers to receive notifications about all networks which satisfy the given
      * {@link NetworkRequest}.  The callbacks will continue to be called until
      * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param request {@link NetworkRequest} describing this request.
      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
      *                        networks change state.
      *                        The callback is invoked on the default internal Handler.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
         registerNetworkCallback(request, networkCallback, getDefaultHandler());
     }
@@ -3241,14 +3212,13 @@
      * Registers to receive notifications about all networks which satisfy the given
      * {@link NetworkRequest}.  The callbacks will continue to be called until
      * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param request {@link NetworkRequest} describing this request.
      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
      *                        networks change state.
      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerNetworkCallback(
             NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
         CallbackHandler cbHandler = new CallbackHandler(handler);
@@ -3280,13 +3250,12 @@
      * <p>
      * The request may be released normally by calling
      * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      * @param request {@link NetworkRequest} describing this request.
      * @param operation Action to perform when the network is available (corresponds
      *                  to the {@link NetworkCallback#onAvailable} call.  Typically
      *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
         checkPendingIntent(operation);
         try {
@@ -3300,13 +3269,12 @@
      * Registers to receive notifications about changes in the system default network. The callbacks
      * will continue to be called until either the application exits or
      * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param networkCallback The {@link NetworkCallback} that the system will call as the
      *                        system default network changes.
      *                        The callback is invoked on the default internal Handler.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerDefaultNetworkCallback(NetworkCallback networkCallback) {
         registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
     }
@@ -3315,13 +3283,12 @@
      * Registers to receive notifications about changes in the system default network. The callbacks
      * will continue to be called until either the application exits or
      * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param networkCallback The {@link NetworkCallback} that the system will call as the
      *                        system default network changes.
      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) {
         // This works because if the NetworkCapabilities are null,
         // ConnectivityService takes them from the default request.
@@ -3398,15 +3365,13 @@
      * {@code always} is true, then the choice is remembered, so that the next time the user
      * connects to this network, the system will switch to it.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
-     *
      * @param network The network to accept.
      * @param accept Whether to accept the network even if unvalidated.
      * @param always Whether to remember this choice in the future.
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
         try {
             mService.setAcceptUnvalidated(network, accept, always);
@@ -3421,13 +3386,11 @@
      * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code
      * NETWORK_AVOID_BAD_WIFI setting is unset}.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
-     *
      * @param network The network to accept.
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
     public void setAvoidUnvalidated(Network network) {
         try {
             mService.setAvoidUnvalidated(network);
@@ -3488,15 +3451,13 @@
      * for multipath data transfer on this network when it is not the system default network.
      * Applications desiring to use multipath network protocols should call this method before
      * each such operation.
-     * <p>
-     * This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      *
      * @param network The network on which the application desires to use multipath data.
      *                If {@code null}, this method will return the a preference that will generally
      *                apply to metered networks.
      * @return a bitwise OR of zero or more of the  {@code MULTIPATH_PREFERENCE_*} constants.
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public @MultipathPreference int getMultipathPreference(Network network) {
         try {
             return mService.getMultipathPreference(network);
diff --git a/core/java/android/net/INetworkRecommendationProvider.aidl b/core/java/android/net/INetworkRecommendationProvider.aidl
index 052c92c..cde0185 100644
--- a/core/java/android/net/INetworkRecommendationProvider.aidl
+++ b/core/java/android/net/INetworkRecommendationProvider.aidl
@@ -17,8 +17,6 @@
 package android.net;
 
 import android.net.NetworkKey;
-import android.net.RecommendationRequest;
-import android.os.IRemoteCallback;
 
 /**
  * The service responsible for answering network recommendation requests.
@@ -27,20 +25,6 @@
 oneway interface INetworkRecommendationProvider {
 
     /**
-     * Request a recommendation for the best network to connect to
-     * taking into account the inputs from the {@link RecommendationRequest}.
-     *
-     * @param request a {@link RecommendationRequest} instance containing the details of the request
-     * @param callback a {@link IRemoteCallback} instance to invoke when the recommendation
-     *                 is available
-     * @param sequence an internal number used for tracking the request
-     * @hide
-     */
-    void requestRecommendation(in RecommendationRequest request,
-                               in IRemoteCallback callback,
-                               int sequence);
-
-    /**
      * Request scoring for networks.
      *
      * Implementations should use {@link NetworkScoreManager#updateScores(ScoredNetwork[])} to
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 362ea9d..73e52c8 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -19,10 +19,7 @@
 import android.net.INetworkScoreCache;
 import android.net.NetworkKey;
 import android.net.NetworkScorerAppData;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
 import android.net.ScoredNetwork;
-import android.os.RemoteCallback;
 
 /**
  * A service for updating network scores from a network scorer application.
@@ -81,16 +78,6 @@
     void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
 
     /**
-     * Request a recommendation for the best network to connect to
-     * taking into account the inputs from the {@link RecommendationRequest}.
-     *
-     * @param request a {@link RecommendationRequest} instance containing the details of the request
-     * @return a {@link RecommendationResult} containing the recommended network to connect to
-     * @throws SecurityException if the caller is not the system
-     */
-    RecommendationResult requestRecommendation(in RecommendationRequest request);
-
-    /**
      * Request scoring for networks.
      *
      * Implementations should delegate to the registered network recommendation provider or
@@ -119,18 +106,6 @@
      *         scorer.
      */
     String getActiveScorerPackage();
-    
-    /**
-     * Request a recommendation for the best network to connect to
-     * taking into account the inputs from the {@link RecommendationRequest}.
-     *
-     * @param request a {@link RecommendationRequest} instance containing the details of the request
-     * @param remoteCallback a {@link RemoteCallback} instance to invoke when the recommendation
-     *                       is available.
-     * @throws SecurityException if the caller is not the system
-     */
-    oneway void requestRecommendationAsync(in RecommendationRequest request,
-                                           in RemoteCallback remoteCallback);
 
     /**
      * Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
diff --git a/core/java/android/net/NetworkRecommendationProvider.java b/core/java/android/net/NetworkRecommendationProvider.java
index af0459d..1eaa1f9 100644
--- a/core/java/android/net/NetworkRecommendationProvider.java
+++ b/core/java/android/net/NetworkRecommendationProvider.java
@@ -39,10 +39,14 @@
 public abstract class NetworkRecommendationProvider {
     private static final String TAG = "NetworkRecProvider";
     private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
-    /** The key into the callback Bundle where the RecommendationResult will be found. */
+    /** The key into the callback Bundle where the RecommendationResult will be found.
+     * @deprecated to be removed.
+     */
     public static final String EXTRA_RECOMMENDATION_RESULT =
             "android.net.extra.RECOMMENDATION_RESULT";
-    /** The key into the callback Bundle where the sequence will be found. */
+    /** The key into the callback Bundle where the sequence will be found.
+     * @deprecated to be removed.
+     */
     public static final String EXTRA_SEQUENCE = "android.net.extra.SEQUENCE";
     private final IBinder mService;
 
@@ -77,9 +81,9 @@
      * @param callback a {@link ResultCallback} instance. When a {@link RecommendationResult} is
      *                 available it must be passed into
      *                 {@link ResultCallback#onResult(RecommendationResult)}.
+     * @deprecated to be removed.
      */
-    public abstract void onRequestRecommendation(RecommendationRequest request,
-            ResultCallback callback);
+    public void onRequestRecommendation(RecommendationRequest request, ResultCallback callback) {}
 
     /**
      * Invoked when network scores have been requested.
@@ -101,6 +105,8 @@
     /**
      * A callback implementing applications should invoke when a {@link RecommendationResult}
      * is available.
+     *
+     * @deprecated to be removed.
      */
     public static class ResultCallback {
         private final IRemoteCallback mCallback;
@@ -176,23 +182,6 @@
         }
 
         @Override
-        public void requestRecommendation(final RecommendationRequest request,
-                final IRemoteCallback callback, final int sequence) throws RemoteException {
-            enforceCallingPermission();
-            if (VERBOSE) Log.v(TAG, "requestRecommendation(seq=" + sequence + ")");
-            execute(new Runnable() {
-                @Override
-                public void run() {
-                    if (VERBOSE) {
-                        Log.v(TAG, "requestRecommendation(seq=" + sequence + ") running...");
-                    }
-                    ResultCallback resultCallback = new ResultCallback(callback, sequence);
-                    onRequestRecommendation(request, resultCallback);
-                }
-            });
-        }
-
-        @Override
         public void requestScores(final NetworkKey[] networks) throws RemoteException {
             enforceCallingPermission();
             if (networks != null && networks.length > 0) {
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 29483cd..eeb426a 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -428,14 +428,11 @@
      * @throws SecurityException if the caller does not hold the
      *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
      * @hide
+     * @deprecated to be removed.
      */
     public RecommendationResult requestRecommendation(RecommendationRequest request)
             throws SecurityException {
-        try {
-            return mService.requestRecommendation(request);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return null;
     }
 
     /**
@@ -452,43 +449,4 @@
             throw e.rethrowFromSystemServer();
         }
     }
-
-    /**
-     * Request a recommendation for which network to connect to.
-     *
-     * <p>The callback will be run on the thread associated with provided {@link Handler}.
-     *
-     * @param request a {@link RecommendationRequest} instance containing additional
-     *                request details
-     * @param handler a {@link Handler} instance representing the thread to complete the future on.
-     *                If null the responding binder thread will be used.
-     * @return a {@link CompletableFuture} instance that will eventually receive the
-     *         {@link RecommendationResult}.
-     * @throws SecurityException
-     * @hide
-     */
-    public CompletableFuture<RecommendationResult> requestRecommendation(
-            final @NonNull RecommendationRequest request,
-            final @Nullable Handler handler) {
-        Preconditions.checkNotNull(request, "RecommendationRequest cannot be null.");
-
-        final CompletableFuture<RecommendationResult> futureResult =
-                new CompletableFuture<>();
-
-        RemoteCallback remoteCallback = new RemoteCallback(new RemoteCallback.OnResultListener() {
-            @Override
-            public void onResult(Bundle data) {
-                RecommendationResult result = data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
-                futureResult.complete(result);
-            }
-        }, handler);
-
-        try {
-            mService.requestRecommendationAsync(request, remoteCallback);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        return futureResult;
-    }
 }
diff --git a/core/java/android/net/RecommendationRequest.aidl b/core/java/android/net/RecommendationRequest.aidl
deleted file mode 100644
index 76497b8..0000000
--- a/core/java/android/net/RecommendationRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2016, 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.net;
-
-parcelable RecommendationRequest;
diff --git a/core/java/android/net/RecommendationRequest.java b/core/java/android/net/RecommendationRequest.java
index 9f97c5a..45ee3a5 100644
--- a/core/java/android/net/RecommendationRequest.java
+++ b/core/java/android/net/RecommendationRequest.java
@@ -30,6 +30,7 @@
  *
  * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
  * @hide
+ * @deprecated to be removed.
  */
 @SystemApi
 public final class RecommendationRequest implements Parcelable {
@@ -43,6 +44,7 @@
     /**
      * Builder class for constructing {@link RecommendationRequest} instances.
      * @hide
+     * @deprecated to be removed.
      */
     @SystemApi
     public static final class Builder {
diff --git a/core/java/android/net/RecommendationResult.java b/core/java/android/net/RecommendationResult.java
index 70cf09c..ce4d83a 100644
--- a/core/java/android/net/RecommendationResult.java
+++ b/core/java/android/net/RecommendationResult.java
@@ -31,6 +31,7 @@
  *
  * @see {@link NetworkScoreManager#requestRecommendation(RecommendationRequest)}.
  * @hide
+ * @deprecated to be removed.
  */
 @SystemApi
 public final class RecommendationResult implements Parcelable {
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index cb85eef..db84b6f 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.util.Log;
 
@@ -67,6 +69,7 @@
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DROPBOX_ENTRY_ADDED =
         "android.intent.action.DROPBOX_ENTRY_ADDED";
 
diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java
index c10abec..6632ca5 100644
--- a/core/java/android/os/Parcelable.java
+++ b/core/java/android/os/Parcelable.java
@@ -16,6 +16,11 @@
 
 package android.os;
 
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Interface for classes whose instances can be written to
  * and restored from a {@link Parcel}.  Classes implementing the Parcelable
@@ -53,6 +58,14 @@
  * }</pre>
  */
 public interface Parcelable {
+    /** @hide */
+    @IntDef(flag = true, prefix = { "PARCELABLE_" }, value = {
+            PARCELABLE_WRITE_RETURN_VALUE,
+            PARCELABLE_ELIDE_DUPLICATES,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteFlags {}
+
     /**
      * Flag for use with {@link #writeToParcel}: the object being written
      * is a return value, that is the result of a function such as
@@ -79,6 +92,13 @@
      * marshalled.
      */
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "CONTENTS_" }, value = {
+            CONTENTS_FILE_DESCRIPTOR,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ContentsFlags {}
+
     /**
      * Descriptor bit used with {@link #describeContents()}: indicates that
      * the Parcelable object's flattened representation includes a file descriptor.
@@ -96,10 +116,8 @@
      *  
      * @return a bitmask indicating the set of special object types marshaled
      * by this Parcelable object instance.
-     *
-     * @see #CONTENTS_FILE_DESCRIPTOR
      */
-    public int describeContents();
+    public @ContentsFlags int describeContents();
     
     /**
      * Flatten this object in to a Parcel.
@@ -108,7 +126,7 @@
      * @param flags Additional flags about how the object should be written.
      * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
      */
-    public void writeToParcel(Parcel dest, int flags);
+    public void writeToParcel(Parcel dest, @WriteFlags int flags);
 
     /**
      * Interface that must be implemented and provided as a public CREATOR
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index c6bbf48..1e55c78 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.RequiresPermission;
 import android.app.ActivityThread;
 import android.content.Context;
 import android.media.AudioAttributes;
@@ -65,22 +66,19 @@
 
     /**
      * Vibrate constantly for the specified period of time.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#VIBRATE}.
      *
      * @param milliseconds The number of milliseconds to vibrate.
      *
      * @deprecated Use {@link #vibrate(VibrationEffect)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(long milliseconds) {
         vibrate(milliseconds, null);
     }
 
     /**
      * Vibrate constantly for the specified period of time.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#VIBRATE}.
      *
      * @param milliseconds The number of milliseconds to vibrate.
      * @param attributes {@link AudioAttributes} corresponding to the vibration. For example,
@@ -91,6 +89,7 @@
      * @deprecated Use {@link #vibrate(VibrationEffect, AudioAttributes)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(long milliseconds, AudioAttributes attributes) {
         try {
             // This ignores all exceptions to stay compatible with pre-O implementations.
@@ -115,8 +114,6 @@
      * To cause the pattern to repeat, pass the index into the pattern array at which
      * to start the repeat, or -1 to disable repeating.
      * </p>
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#VIBRATE}.
      *
      * @param pattern an array of longs of times for which to turn the vibrator on or off.
      * @param repeat the index into pattern at which to repeat, or -1 if
@@ -125,6 +122,7 @@
      * @deprecated Use {@link #vibrate(VibrationEffect)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(long[] pattern, int repeat) {
         vibrate(pattern, repeat, null);
     }
@@ -142,8 +140,6 @@
      * To cause the pattern to repeat, pass the index into the pattern array at which
      * to start the repeat, or -1 to disable repeating.
      * </p>
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#VIBRATE}.
      *
      * @param pattern an array of longs of times for which to turn the vibrator on or off.
      * @param repeat the index into pattern at which to repeat, or -1 if
@@ -156,6 +152,7 @@
      * @deprecated Use {@link #vibrate(VibrationEffect, AudioAttributes)} instead.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(long[] pattern, int repeat, AudioAttributes attributes) {
         // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other
         // exceptions for compatibility purposes
@@ -170,10 +167,12 @@
         }
     }
 
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(VibrationEffect vibe) {
         vibrate(vibe, null);
     }
 
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public void vibrate(VibrationEffect vibe, AudioAttributes attributes) {
         vibrate(Process.myUid(), mPackageName, vibe, attributes);
     }
@@ -183,13 +182,13 @@
      * that the vibration is owned by someone else.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public abstract void vibrate(int uid, String opPkg,
             VibrationEffect vibe, AudioAttributes attributes);
 
     /**
      * Turn the vibrator off.
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#VIBRATE}.
      */
+    @RequiresPermission(android.Manifest.permission.VIBRATE)
     public abstract void cancel();
 }
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 7496cb2..2179bd4 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -17,8 +17,6 @@
 package android.preference;
 
 import android.annotation.CallSuper;
-import com.android.internal.util.CharSequences;
-
 import android.annotation.DrawableRes;
 import android.annotation.LayoutRes;
 import android.annotation.Nullable;
@@ -42,6 +40,8 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
+import com.android.internal.util.CharSequences;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -650,7 +650,11 @@
 
         final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame);
         if (imageFrame != null) {
-            imageFrame.setVisibility(mIcon != null ? View.VISIBLE : View.GONE);
+            if (mIcon != null) {
+                imageFrame.setVisibility(View.VISIBLE);
+            } else {
+                imageFrame.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE);
+            }
         }
 
         if (mShouldDisableView) {
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index b31b295..42d5ce1 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -18,6 +18,8 @@
 
 import com.android.internal.R;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -2164,6 +2166,7 @@
              * @deprecated Do not use. This is not supported.
              */
             @Deprecated
+            @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
             public static final String FILTER_CONTACTS_ACTION =
                     "com.android.contacts.action.FILTER_CONTACTS";
 
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b4f19d8..5408e13 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -17,6 +17,8 @@
 package android.provider;
 
 import android.accounts.Account;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
@@ -8401,6 +8403,7 @@
          * Action used to launch the system contacts application and bring up a QuickContact dialog
          * for the provided {@link Contacts} entry.
          */
+        @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
         public static final String ACTION_QUICK_CONTACT =
                 "android.provider.action.QUICK_CONTACT";
 
@@ -8924,6 +8927,7 @@
          * @see #METADATA_ACCOUNT_TYPE
          * @see #METADATA_MIMETYPE
          */
+        @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
         public static final String ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS =
                 "android.provider.action.VOICE_SEND_MESSAGE_TO_CONTACTS";
 
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 068628a..bcd1b6b 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -33,7 +33,6 @@
 import android.database.Cursor;
 import android.graphics.Typeface;
 import android.graphics.fonts.FontRequest;
-import android.graphics.fonts.FontResult;
 import android.graphics.fonts.FontVariationAxis;
 import android.net.Uri;
 import android.os.Bundle;
@@ -43,6 +42,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.ResultReceiver;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.LruCache;
 
@@ -64,6 +64,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Utility class to deal with Font ContentProviders.
@@ -104,14 +105,6 @@
          */
         public static final String VARIATION_SETTINGS = "font_variation_settings";
         /**
-         * DO NOT USE THIS COLUMN.
-         * This column is kept for preventing demo apps.
-         * TODO: Remove once nobody uses this column.
-         * @hide
-         * @removed
-         */
-        public static final String STYLE = "font_style";
-        /**
          * Constant used to request data from a font provider. The cursor returned from the query
          * should have this column populated with the int weight for the resulting font. This value
          * should be between 100 and 900. The most common values are 400 for regular weight and 700
@@ -158,36 +151,24 @@
         public static final int RESULT_CODE_MALFORMED_QUERY = 3;
     }
 
-    /**
-     * Constant used to identify the List of {@link ParcelFileDescriptor} item in the Bundle
-     * returned to the ResultReceiver in getFont.
-     * @hide
-     */
-    public static final String PARCEL_FONT_RESULTS = "font_results";
-    // Error codes internal to the system, which can not come from a provider. To keep the number
-    // space open for new provider codes, these should all be negative numbers.
-    /** @hide */
-    public static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1;
-    /** @hide */
-    public static final int RESULT_CODE_WRONG_CERTIFICATES = -2;
-    // Note -3 is used by Typeface to indicate the font failed to load.
+    private static final Object sLock = new Object();
+    @GuardedBy("sLock")
+    private static Handler sHandler;
+    @GuardedBy("sLock")
+    private static HandlerThread sThread;
+    @GuardedBy("sLock")
+    private static Set<String> sInQueueSet;
 
-    private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000;
-
-    private final Context mContext;
-    private final PackageManager mPackageManager;
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private Handler mHandler;
-    @GuardedBy("mLock")
-    private HandlerThread mThread;
+    private volatile static Context sContext;  // set once in setApplicationContextForResources
 
     private static final LruCache<String, Typeface> sTypefaceCache = new LruCache<>(16);
 
+    private FontsContract() {
+    }
+
     /** @hide */
-    public FontsContract(Context context) {
-        mContext = context.getApplicationContext();
-        mPackageManager = mContext.getPackageManager();
+    public static void setApplicationContextForResources(Context context) {
+        sContext = context.getApplicationContext();
     }
 
     /**
@@ -320,91 +301,67 @@
         }
     }
 
+    private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000;
+
     // We use a background thread to post the content resolving work for all requests on. This
     // thread should be quit/stopped after all requests are done.
-    private final Runnable mReplaceDispatcherThreadRunnable = new Runnable() {
+    // TODO: Factor out to other class. Consider to switch MessageQueue.IdleHandler.
+    private static final Runnable sReplaceDispatcherThreadRunnable = new Runnable() {
         @Override
         public void run() {
-            synchronized (mLock) {
-                if (mThread != null) {
-                    mThread.quitSafely();
-                    mThread = null;
-                    mHandler = null;
+            synchronized (sLock) {
+                if (sThread != null) {
+                    sThread.quitSafely();
+                    sThread = null;
+                    sHandler = null;
+                    sInQueueSet = null;
                 }
             }
         }
     };
 
     /** @hide */
-    public void getFont(FontRequest request, ResultReceiver receiver) {
-        synchronized (mLock) {
-            if (mHandler == null) {
-                mThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND);
-                mThread.start();
-                mHandler = new Handler(mThread.getLooper());
-            }
-            mHandler.post(() -> {
-                ProviderInfo providerInfo;
-                try {
-                    providerInfo = getProvider(mPackageManager, request);
-                    if (providerInfo == null) {
-                        receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
-                        return;
-                    }
-                } catch (PackageManager.NameNotFoundException e) {
-                    receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
-                    return;
-                }
-                FontInfo[] fonts;
-                try {
-                    fonts = getFontFromProvider(mContext, request, providerInfo.authority,
-                            null /* cancellation signal */);
-                } catch (InvalidFormatException e) {
-                    receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
-                    return;
-                }
-
-                ArrayList<FontResult> result = new ArrayList<>();
-                int resultCode = -1;
-                for (FontInfo font : fonts) {
-                    try {
-                        resultCode = font.getResultCode();
-                        if (resultCode != Columns.RESULT_CODE_OK) {
-                            if (resultCode < 0) {
-                                // Negative values are reserved for the internal errors.
-                                resultCode = Columns.RESULT_CODE_FONT_NOT_FOUND;
-                            }
-                            for (int i = 0; i < result.size(); ++i) {
-                                try {
-                                    result.get(i).getFileDescriptor().close();
-                                } catch (IOException e) {
-                                    // Ignore, as we are closing fds for cleanup.
-                                }
-                            }
-                            receiver.send(resultCode, null);
-                            return;
-                        }
-                        ParcelFileDescriptor pfd = mContext.getContentResolver().openFileDescriptor(
-                                font.getUri(), "r");
-                        result.add(new FontResult(pfd, font.getTtcIndex(),
-                                FontVariationAxis.toFontVariationSettings(font.getAxes()),
-                                font.getWeight(), font.isItalic()));
-                    } catch (FileNotFoundException e) {
-                        Log.e(TAG, "FileNotFoundException raised when interacting with content "
-                                + "provider " + providerInfo.authority, e);
-                    }
-                }
-                if (!result.isEmpty()) {
-                    Bundle bundle = new Bundle();
-                    bundle.putParcelableArrayList(PARCEL_FONT_RESULTS, result);
-                    receiver.send(Columns.RESULT_CODE_OK, bundle);
-                    return;
-                }
-                receiver.send(Columns.RESULT_CODE_FONT_NOT_FOUND, null);
-            });
-            mHandler.removeCallbacks(mReplaceDispatcherThreadRunnable);
-            mHandler.postDelayed(mReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS);
+    public static Typeface getFontOrWarmUpCache(FontRequest request) {
+        final String id = request.getIdentifier();
+        Typeface cachedTypeface = sTypefaceCache.get(id);
+        if (cachedTypeface != null) {
+            return cachedTypeface;
         }
+
+        // Unfortunately the typeface is not available at this time, but requesting from the font
+        // provider takes too much time. For now, request the font data to ensure it is in the cache
+        // next time and return.
+        synchronized (sLock) {
+            if (sHandler == null) {
+                sThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND);
+                sThread.start();
+                sHandler = new Handler(sThread.getLooper());
+                sInQueueSet = new ArraySet<>();
+            }
+            if (sInQueueSet.contains(id)) {
+                return null;  // Already requested.
+            }
+            sInQueueSet.add(id);
+            sHandler.post(() -> {
+                synchronized (sLock) {
+                    sInQueueSet.remove(id);
+                }
+                try {
+                    FontFamilyResult result = fetchFonts(sContext, null, request);
+                    if (result.getStatusCode() == FontFamilyResult.STATUS_OK) {
+                        Typeface typeface = buildTypeface(sContext, null, result.getFonts());
+                        if (typeface != null) {
+                            sTypefaceCache.put(id, typeface);
+                        }
+                    }
+                } catch (NameNotFoundException e) {
+                    // Ignore.
+                }
+            });
+            sHandler.removeCallbacks(sReplaceDispatcherThreadRunnable);
+            sHandler.postDelayed(sReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS);
+        }
+        return null;
     }
 
     /**
@@ -415,12 +372,12 @@
          * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
          * provider was not found on the device.
          */
-        public static final int FAIL_REASON_PROVIDER_NOT_FOUND = RESULT_CODE_PROVIDER_NOT_FOUND;
+        public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1;
         /**
          * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
          * provider must be authenticated and the given certificates do not match its signature.
          */
-        public static final int FAIL_REASON_WRONG_CERTIFICATES = RESULT_CODE_WRONG_CERTIFICATES;
+        public static final int FAIL_REASON_WRONG_CERTIFICATES = -2;
         /**
          * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
          * returned by the provider was not loaded properly.
@@ -452,16 +409,14 @@
         public FontRequestCallback() {}
 
         /**
-         * Called then a Typeface request done via {@link Typeface#create(FontRequest,
-         * FontRequestCallback)} is complete. Note that this method will not be called if
-         * {@link #onTypefaceRequestFailed(int)} is called instead.
+         * Called then a Typeface request done via {@link #requestFont} is complete. Note that this
+         * method will not be called if {@link #onTypefaceRequestFailed(int)} is called instead.
          * @param typeface  The Typeface object retrieved.
          */
         public void onTypefaceRetrieved(Typeface typeface) {}
 
         /**
-         * Called when a Typeface request done via {@link Typeface#create(FontRequest,
-         * FontRequestCallback)} fails.
+         * Called when a Typeface request done via {@link #requestFont}} fails.
          * @param reason One of {@link #FAIL_REASON_PROVIDER_NOT_FOUND},
          *               {@link #FAIL_REASON_FONT_NOT_FOUND},
          *               {@link #FAIL_REASON_FONT_LOAD_ERROR},
@@ -793,7 +748,7 @@
                 .build();
         try (Cursor cursor = context.getContentResolver().query(uri, new String[] { Columns._ID,
                         Columns.FILE_ID, Columns.TTC_INDEX, Columns.VARIATION_SETTINGS,
-                        Columns.STYLE, Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
+                        Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
                 "query = ?", new String[] { request.getQuery() }, null, cancellationSignal);) {
             // TODO: Should we restrict the amount of fonts that can be returned?
             // TODO: Write documentation explaining that all results should be from the same family.
@@ -806,7 +761,6 @@
                 final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS);
                 final int weightColumnIndex = cursor.getColumnIndex(Columns.WEIGHT);
                 final int italicColumnIndex = cursor.getColumnIndex(Columns.ITALIC);
-                final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE);
                 while (cursor.moveToNext()) {
                     int resultCode = resultCodeColumnIndex != -1
                             ? cursor.getInt(resultCodeColumnIndex) : Columns.RESULT_CODE_OK;
@@ -823,17 +777,11 @@
                         long id = cursor.getLong(fileIdColumnIndex);
                         fileUri = ContentUris.withAppendedId(fileBaseUri, id);
                     }
-                    // TODO: Stop using STYLE column and enforce WEIGHT/ITALIC column.
                     int weight;
                     boolean italic;
                     if (weightColumnIndex != -1 && italicColumnIndex != -1) {
                         weight = cursor.getInt(weightColumnIndex);
                         italic = cursor.getInt(italicColumnIndex) == 1;
-                    } else if (styleColumnIndex != -1) {
-                        final int style = cursor.getInt(styleColumnIndex);
-                        weight = (style & Typeface.BOLD) != 0 ?
-                                Typeface.Builder.BOLD_WEIGHT : Typeface.Builder.NORMAL_WEIGHT;
-                        italic = (style & Typeface.ITALIC) != 0;
                     } else {
                         weight = Typeface.Builder.NORMAL_WEIGHT;
                         italic = false;
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 93adf83..13e1e26 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1498,6 +1498,7 @@
              * May also contain the extra EXTRA_MAX_BYTES.
              * @see #EXTRA_MAX_BYTES
              */
+            @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
             public static final String RECORD_SOUND_ACTION =
                     "android.provider.MediaStore.RECORD_SOUND";
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0884480..69371be 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1398,6 +1398,26 @@
     public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS
             = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
 
+    /**
+     * Activity Action: Show screen that let user select its Autofill Service.
+     * <p>
+     * Input: Intent's data URI set with an application name, using the
+     * "package" schema (like "package:com.my.app").
+     *
+     * <p>
+     * Output: {@link android.app.Activity#RESULT_OK} if user selected an Autofill Service belonging
+     * to the caller package.
+     *
+     * <p>
+     * <b>NOTE: </b> applications should call
+     * {@link android.view.autofill.AutofillManager#hasEnabledAutofillServices()} and
+     * {@link android.view.autofill.AutofillManager#isAutofillSupported()} first, and only
+     * broadcast this intent if they return {@code false} and {@code true} respectively.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE =
+            "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
+
     // End of Intent actions for Settings
 
     /**
@@ -5555,76 +5575,6 @@
                 "high_text_contrast_enabled";
 
         /**
-         * If injection of accessibility enhancing JavaScript screen-reader
-         * is enabled.
-         * <p>
-         *   Note: The JavaScript based screen-reader is served by the
-         *   Google infrastructure and enable users with disabilities to
-         *   efficiently navigate in and explore web content.
-         * </p>
-         * <p>
-         *   This property represents a boolean value.
-         * </p>
-         * @hide
-         */
-        public static final String ACCESSIBILITY_SCRIPT_INJECTION =
-            "accessibility_script_injection";
-
-        /**
-         * The URL for the injected JavaScript based screen-reader used
-         * for providing accessibility of content in WebView.
-         * <p>
-         *   Note: The JavaScript based screen-reader is served by the
-         *   Google infrastructure and enable users with disabilities to
-         *   efficiently navigate in and explore web content.
-         * </p>
-         * <p>
-         *   This property represents a string value.
-         * </p>
-         * @hide
-         */
-        public static final String ACCESSIBILITY_SCREEN_READER_URL =
-            "accessibility_script_injection_url";
-
-        /**
-         * Key bindings for navigation in built-in accessibility support for web content.
-         * <p>
-         *   Note: These key bindings are for the built-in accessibility navigation for
-         *   web content which is used as a fall back solution if JavaScript in a WebView
-         *   is not enabled or the user has not opted-in script injection from Google.
-         * </p>
-         * <p>
-         *   The bindings are separated by semi-colon. A binding is a mapping from
-         *   a key to a sequence of actions (for more details look at
-         *   android.webkit.AccessibilityInjector). A key is represented as the hexademical
-         *   string representation of an integer obtained from a meta state (optional) shifted
-         *   sixteen times left and bitwise ored with a key code. An action is represented
-         *   as a hexademical string representation of an integer where the first two digits
-         *   are navigation action index, the second, the third, and the fourth digit pairs
-         *   represent the action arguments. The separate actions in a binding are colon
-         *   separated. The key and the action sequence it maps to are separated by equals.
-         * </p>
-         * <p>
-         *   For example, the binding below maps the DPAD right button to traverse the
-         *   current navigation axis once without firing an accessibility event and to
-         *   perform the same traversal again but to fire an event:
-         *   <code>
-         *     0x16=0x01000100:0x01000101;
-         *   </code>
-         * </p>
-         * <p>
-         *   The goal of this binding is to enable dynamic rebinding of keys to
-         *   navigation actions for web content without requiring a framework change.
-         * </p>
-         * <p>
-         *   This property represents a string value.
-         * </p>
-         * @hide
-         */
-        public static final String ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS =
-            "accessibility_web_content_key_bindings";
-
-        /**
          * Setting that specifies whether the display magnification is enabled via a system-wide
          * triple tap gesture. Display magnifications allows the user to zoom in the display content
          * and is targeted to low vision users. The current magnification scale is controlled by
@@ -6994,8 +6944,6 @@
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-            ACCESSIBILITY_SCRIPT_INJECTION,
-            ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
             ENABLED_ACCESSIBILITY_SERVICES,
             ENABLED_NOTIFICATION_LISTENERS,
             ENABLED_VR_LISTENERS,
@@ -8352,16 +8300,6 @@
                 "network_recommendations_package";
 
         /**
-         * Value to specify if the Wi-Fi Framework should defer to
-         * {@link com.android.server.NetworkScoreService} for evaluating saved open networks.
-         *
-         * Type: int (0 for false, 1 for true)
-         * @hide
-         */
-        @SystemApi
-        public static final String CURATE_SAVED_OPEN_NETWORKS = "curate_saved_open_networks";
-
-        /**
          * The package name of the application that connect and secures high quality open wifi
          * networks automatically.
          *
@@ -8376,6 +8314,7 @@
          *
          * Type: long
          * @hide
+         * @deprecated to be removed
          */
         public static final String NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS =
                 "network_recommendation_request_timeout_ms";
@@ -9877,7 +9816,6 @@
             CHARGING_SOUNDS_ENABLED,
             USB_MASS_STORAGE_ENABLED,
             NETWORK_RECOMMENDATIONS_ENABLED,
-            CURATE_SAVED_OPEN_NETWORKS,
             WIFI_WAKEUP_ENABLED,
             WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
             USE_OPEN_WIFI_PACKAGE,
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 813c54f..cb47c10 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -36,9 +36,6 @@
 
 import java.util.List;
 
-//TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
-//life-cycle (and how state could be maintained on server-side) is well documented.
-
 /**
  * Top-level service of the current autofill service for a given user.
  *
@@ -50,19 +47,6 @@
     /**
      * The {@link Intent} that must be declared as handled by the service.
      * To be supported, the service must also require the
-     * {@link android.Manifest.permission#BIND_AUTO_FILL} permission so
-     * that other applications can not abuse it.
-     *
-     * @hide
-     * @deprecated TODO(b/35956626): remove once clients use AutofillService
-     */
-    @Deprecated
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String OLD_SERVICE_INTERFACE = "android.service.autofill.AutoFillService";
-
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     * To be supported, the service must also require the
      * {@link android.Manifest.permission#BIND_AUTOFILL} permission so
      * that other applications can not abuse it.
      */
@@ -82,18 +66,12 @@
      */
     public static final String SERVICE_META_DATA = "android.autofill";
 
-    // Internal extras
-    /** @hide */
-    public static final String EXTRA_SESSION_ID = "android.service.autofill.extra.SESSION_ID";
-
     // Handler messages.
     private static final int MSG_CONNECT = 1;
     private static final int MSG_DISCONNECT = 2;
     private static final int MSG_ON_FILL_REQUEST = 3;
     private static final int MSG_ON_SAVE_REQUEST = 4;
 
-    private static final int UNUSED_ARG = -1;
-
     private final IAutoFillService mInterface = new IAutoFillService.Stub() {
         @Override
         public void onConnectedStateChanged(boolean connected) {
@@ -136,7 +114,13 @@
                 final IFillCallback callback = (IFillCallback) args.arg3;
                 final FillCallback fillCallback = new FillCallback(callback, request.getId());
                 args.recycle();
-                onFillRequest(request, cancellation, fillCallback);
+                // TODO(b/37563972): temporary try-catch hack to support old method
+                try {
+                    onFillRequest(request, cancellation, fillCallback);
+                } catch (AbstractMethodError e) {
+                    onFillRequest(request.getStructure(), request.getClientState(),
+                            request.getFlags(), cancellation, fillCallback);
+                }
                 break;
             } case MSG_ON_SAVE_REQUEST: {
                 final SomeArgs args = (SomeArgs) msg.obj;
@@ -144,7 +128,14 @@
                 final ISaveCallback callback = (ISaveCallback) args.arg2;
                 final SaveCallback saveCallback = new SaveCallback(callback);
                 args.recycle();
-                onSaveRequest(request, saveCallback);
+                // TODO(b/37563972): temporary try-catch hack to support old method
+                try {
+                    onSaveRequest(request, saveCallback);
+                } catch (AbstractMethodError e) {
+                    final List<FillContext> contexts = request.getFillContexts();
+                    onSaveRequest(contexts.get(contexts.size() - 1).getStructure(),
+                            request.getClientState(), saveCallback);
+                }
                 break;
             } case MSG_DISCONNECT: {
                 onDisconnected();
@@ -170,8 +161,7 @@
 
     @Override
     public final IBinder onBind(Intent intent) {
-        if (SERVICE_INTERFACE.equals(intent.getAction())
-                || OLD_SERVICE_INTERFACE.equals(intent.getAction())) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
             return mInterface.asBinder();
         }
         Log.w(TAG, "Tried to bind to wrong intent: " + intent);
@@ -202,11 +192,8 @@
      *     handling this fill request in order to save resources.
      * @param callback object used to notify the result of the request.
      */
-    public void onFillRequest(@NonNull FillRequest request,
-            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback) {
-        onFillRequest(request.getStructure(), request.getClientState(), request.getFlags(),
-                cancellationSignal, callback);
-    }
+    public abstract void onFillRequest(@NonNull FillRequest request,
+            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
 
     /**
      * Called by the Android system do decide if an {@link Activity} can be autofilled by the
@@ -229,6 +216,8 @@
      *     this to notify you that the fill result is no longer needed and you should stop
      *     handling this fill request in order to save resources.
      * @param callback object used to notify the result of the request.
+     *
+     * @hide
      */
     @Deprecated
     public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
@@ -246,11 +235,8 @@
      *        See {@link FillResponse} for examples of multiple-sections requests.
      * @param callback object used to notify the result of the request.
      */
-    public void onSaveRequest(@NonNull SaveRequest request, @NonNull SaveCallback callback) {
-        final List<FillContext> contexts = request.getFillContexts();
-        onSaveRequest(contexts.get(contexts.size() - 1).getStructure(),
-                request.getClientState(), callback);
-    }
+    public abstract void onSaveRequest(@NonNull SaveRequest request,
+            @NonNull SaveCallback callback);
 
     /**
      * Called when user requests service to save the fields of an {@link Activity}.
@@ -267,6 +253,8 @@
      *        conserve resources.
      *        See {@link FillResponse} for examples of multiple-sections requests.
      * @param callback object used to notify the result of the request.
+     *
+     * @hide
      */
     @Deprecated
     public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
@@ -280,9 +268,9 @@
     public void onDisconnected() {
     }
 
+    /** @hide */
     @Deprecated
     public final void disableSelf() {
-        // TODO(b/33197203): Remove when GCore has migrated off this API
         getSystemService(AutofillManager.class).disableOwnedAutofillServices();
     }
 
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index aa6db4d..49f348c 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -39,8 +39,6 @@
  * @see AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)
  */
 public final class FillRequest implements Parcelable {
-    private static AtomicInteger sIdCounter = new AtomicInteger();
-
     /**
      * Indicates autofill was explicitly requested by the user.
      */
@@ -58,12 +56,6 @@
     private final @NonNull AssistStructure mStructure;
     private final @Nullable Bundle mClientState;
 
-    /** @hide */
-    public FillRequest(@NonNull AssistStructure structure,
-            @Nullable Bundle clientState, @RequestFlags int flags) {
-        this(sIdCounter.incrementAndGet(), structure, clientState, flags);
-    }
-
     private FillRequest(@NonNull Parcel parcel) {
         mId = parcel.readInt();
         mStructure = parcel.readParcelable(null);
@@ -71,7 +63,8 @@
         mFlags = parcel.readInt();
     }
 
-    private FillRequest(int id, @NonNull AssistStructure structure,
+    /** @hide */
+    public FillRequest(int id, @NonNull AssistStructure structure,
             @Nullable Bundle clientState, @RequestFlags int flags) {
         mId = id;
         mFlags = Preconditions.checkFlagsArgument(flags, FLAG_MANUAL_REQUEST);
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 68ce0b5..2afb1f4 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -242,7 +242,7 @@
         public @NonNull Builder setAuthentication(@NonNull AutofillId[] ids,
                 @Nullable IntentSender authentication, @Nullable RemoteViews presentation) {
             throwIfDestroyed();
-            // TODO(b/33197203): assert ids is not null nor empty once old version is removed
+            // TODO(b/37424539): assert ids is not null nor empty once old version is removed
             if (authentication == null ^ presentation == null) {
                 throw new IllegalArgumentException("authentication and presentation"
                         + " must be both non-null or null");
@@ -254,7 +254,7 @@
         }
 
         /**
-         * TODO(b/33197203): will be removed once clients use the version that takes ids
+         * TODO(b/37424539): will be removed once clients use the version that takes ids
          * @hide
          * @deprecated
          */
@@ -311,6 +311,7 @@
 
         /**
          * @deprecated Use {@link #setClientState(Bundle)} instead.
+         * @hide
          */
         @Deprecated
         public Builder setExtras(@Nullable Bundle extras) {
diff --git a/core/java/android/service/resolver/ResolverRankerService.java b/core/java/android/service/resolver/ResolverRankerService.java
index 0506747..7523347 100644
--- a/core/java/android/service/resolver/ResolverRankerService.java
+++ b/core/java/android/service/resolver/ResolverRankerService.java
@@ -65,6 +65,12 @@
     public static final String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
 
     /**
+     * The permission that a service must hold. If the service does not hold the permission, the
+     * system will skip that service.
+     */
+    public static final String HOLD_PERMISSION = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
+
+    /**
      * The permission that a service must require to ensure that only Android system can bind to it.
      * If this permission is not enforced in the AndroidManifest of the service, the system will
      * skip that service.
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 6eea07d..8b2d0c6 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -16,6 +16,7 @@
 
 package android.service.vr;
 
+import android.app.CompatibilityDisplayProperties;
 import android.service.vr.IVrStateCallbacks;
 import android.service.vr.IPersistentVrStateCallbacks;
 
@@ -67,6 +68,18 @@
     void setPersistentVrModeEnabled(in boolean enabled);
 
     /**
+     * Sets the resolution and DPI of the compatibility virtual display used to display
+     * 2D applications in VR mode.
+     *
+     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+     *
+     * @param compatDisplayProperties Compatibitlity display properties to be set for
+     * the VR virtual display
+     */
+    void setCompatibilityDisplayProperties(
+            in CompatibilityDisplayProperties compatDisplayProperties);
+
+    /**
      * Return current virtual display id.
      *
      * @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
index d94af8a..68d0309 100644
--- a/core/java/android/util/MergedConfiguration.java
+++ b/core/java/android/util/MergedConfiguration.java
@@ -21,6 +21,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.io.PrintWriter;
+
 /**
  * Container that holds global and override config and their merge product.
  * Merged configuration updates automatically whenever global or override configs are updated via
@@ -41,6 +43,10 @@
         setConfiguration(globalConfig, overrideConfig);
     }
 
+    public MergedConfiguration(Configuration globalConfig) {
+        setGlobalConfiguration(globalConfig);
+    }
+
     public MergedConfiguration(MergedConfiguration mergedConfiguration) {
         setConfiguration(mergedConfiguration.getGlobalConfiguration(),
                 mergedConfiguration.getOverrideConfiguration());
@@ -93,6 +99,36 @@
     }
 
     /**
+     * Update global configurations.
+     * Merged configuration will automatically be updated.
+     * @param globalConfig New global configuration.
+     */
+    public void setGlobalConfiguration(Configuration globalConfig) {
+        mGlobalConfig.setTo(globalConfig);
+        updateMergedConfig();
+    }
+
+    /**
+     * Update override configurations.
+     * Merged configuration will automatically be updated.
+     * @param overrideConfig New override configuration.
+     */
+    public void setOverrideConfiguration(Configuration overrideConfig) {
+        mOverrideConfig.setTo(overrideConfig);
+        updateMergedConfig();
+    }
+
+    public void setTo(MergedConfiguration config) {
+        setConfiguration(config.mGlobalConfig, config.mOverrideConfig);
+    }
+
+    public void unset() {
+        mGlobalConfig.unset();
+        mOverrideConfig.unset();
+        updateMergedConfig();
+    }
+
+    /**
      * @return Stored global configuration value.
      */
     @NonNull
@@ -119,4 +155,14 @@
         mMergedConfig.setTo(mGlobalConfig);
         mMergedConfig.updateFrom(mOverrideConfig);
     }
+
+    @Override
+    public String toString() {
+        return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}";
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "mGlobalConfig=" + mGlobalConfig);
+        pw.println(prefix + "mOverrideConfig=" + mOverrideConfig);
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bcf0b90..d42c6db 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7381,17 +7381,20 @@
      * optimal implementation providing this data.
      */
     public void onProvideVirtualStructure(ViewStructure structure) {
-        onProvideVirtualStructureForAssistOrAutofill(structure, false);
+        AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+        if (provider != null) {
+            AccessibilityNodeInfo info = createAccessibilityNodeInfo();
+            structure.setChildCount(1);
+            ViewStructure root = structure.newChild(0);
+            populateVirtualStructure(root, provider, info);
+            info.recycle();
+        }
     }
 
     /**
      * Called when assist structure is being retrieved from a view as part of an autofill request
      * to generate additional virtual structure under this view.
      *
-     * <p>The default implementation uses {@link #getAccessibilityNodeProvider()} to try to
-     * generate this from the view's virtual accessibility nodes, if any. You can override this
-     * for a more optimal implementation providing this data.
-     *
      * <p>When implementing this method, subclasses must follow the rules below:
      *
      * <ol>
@@ -7415,27 +7418,10 @@
      * @param flags optional flags (currently {@code 0}).
      */
     public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
-        onProvideVirtualStructureForAssistOrAutofill(structure, true);
-    }
-
-    private void onProvideVirtualStructureForAssistOrAutofill(ViewStructure structure,
-            boolean forAutofill) {
-        if (forAutofill) {
-            setAutofillId(structure);
-        }
-        // NOTE: currently flags are only used for AutoFill; if they're used for Assist as well,
-        // this method should take a boolean with the type of request.
-        AccessibilityNodeProvider provider = getAccessibilityNodeProvider();
-        if (provider != null) {
-            AccessibilityNodeInfo info = createAccessibilityNodeInfo();
-            structure.setChildCount(1);
-            ViewStructure root = structure.newChild(0);
-            if (forAutofill) {
-                setAutofillId(root);
-            }
-            populateVirtualStructure(root, provider, info, forAutofill);
-            info.recycle();
-        }
+        // TODO(b/36171235): need a way to let apps set the ViewStructure without forcing them
+        // to call super() (in case they override both this method and dispatchProvide....
+        // Perhaps the best solution would simply make setAutofillId(ViewStructure) public.
+        setAutofillId(structure);
     }
 
     /**
@@ -7652,7 +7638,7 @@
     }
 
     private void populateVirtualStructure(ViewStructure structure,
-            AccessibilityNodeProvider provider, AccessibilityNodeInfo info, boolean forAutofill) {
+            AccessibilityNodeProvider provider, AccessibilityNodeInfo info) {
         structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
                 null, null, null);
         Rect rect = structure.getTempRect();
@@ -7690,10 +7676,7 @@
         CharSequence cname = info.getClassName();
         structure.setClassName(cname != null ? cname.toString() : null);
         structure.setContentDescription(info.getContentDescription());
-        if (!forAutofill && (info.getText() != null || info.getError() != null)) {
-            // TODO(b/33197203) (b/33269702): when sanitized, try to use the Accessibility API to
-            // just set sanitized values (like text coming from resource files), rather than not
-            // setting it at all.
+        if ((info.getText() != null || info.getError() != null)) {
             structure.setText(info.getText(), info.getTextSelectionStart(),
                     info.getTextSelectionEnd());
         }
@@ -7704,12 +7687,7 @@
                 AccessibilityNodeInfo cinfo = provider.createAccessibilityNodeInfo(
                         AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
                 ViewStructure child = structure.newChild(i);
-                if (forAutofill) {
-                    // TODO(b/33197203): add CTS test to autofill virtual children based on
-                    // Accessibility API.
-                    child.setAutofillId(structure, i);
-                }
-                populateVirtualStructure(child, provider, cinfo, forAutofill);
+                populateVirtualStructure(child, provider, cinfo);
                 cinfo.recycle();
             }
         }
@@ -9598,13 +9576,10 @@
      *
      * @return Returns {@code false} if assist data collection for autofill is not blocked,
      * else {@code true}.
-     *
-     * TODO(b/33197203): update / remove javadoc tags below
-     * @see #setAssistBlocked(boolean)
-     * @attr ref android.R.styleable#View_assistBlocked
      */
     public boolean isAutofillBlocked() {
-        return false; // TODO(b/33197203): properly implement it
+        // TODO(b/36171235): properly implement it using isImportantForAutofill()
+        return false;
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9ecced6..1f13220 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -435,8 +435,9 @@
 
     AccessibilityInteractionController mAccessibilityInteractionController;
 
-    AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager;
-    HighContrastTextManager mHighContrastTextManager;
+    final AccessibilityInteractionConnectionManager mAccessibilityInteractionConnectionManager =
+            new AccessibilityInteractionConnectionManager();
+    final HighContrastTextManager mHighContrastTextManager;
 
     SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent;
 
@@ -496,13 +497,11 @@
         mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
                 context);
         mAccessibilityManager = AccessibilityManager.getInstance(context);
-        mAccessibilityInteractionConnectionManager =
-            new AccessibilityInteractionConnectionManager();
         mAccessibilityManager.addAccessibilityStateChangeListener(
-                mAccessibilityInteractionConnectionManager);
+                mAccessibilityInteractionConnectionManager, mHandler);
         mHighContrastTextManager = new HighContrastTextManager();
         mAccessibilityManager.addHighTextContrastStateChangeListener(
-                mHighContrastTextManager);
+                mHighContrastTextManager, mHandler);
         mViewConfiguration = ViewConfiguration.get(context);
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 435610e..387a9ce 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -362,11 +362,19 @@
     public abstract AutofillId getAutofillId();
 
     /**
-     * Sets the URL represented by this node.
+     * @deprecated - use {@link #setWebDomain(String)} instead.
+     */
+    @Deprecated
+    public abstract void setUrl(String url);
+
+    /**
+     * Sets the Web domain represented by this node.
      *
      * <p>Typically used when the view is a container for an HTML document.
+     *
+     * @param domain URL representing the domain; only the host part will be used.
      */
-    public abstract void setUrl(String url);
+    public abstract void setWebDomain(@Nullable String domain);
 
     /**
      * Sets the the list of locales associated with this node.
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 6c884c4..dfb0095 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -37,6 +37,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.IWindow;
 import android.view.View;
@@ -47,7 +48,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * System level service that serves as an event dispatch for {@link AccessibilityEvent}s,
@@ -137,17 +137,18 @@
 
     boolean mIsHighTextContrastEnabled;
 
-    private final CopyOnWriteArrayList<AccessibilityStateChangeListener>
-            mAccessibilityStateChangeListeners = new CopyOnWriteArrayList<>();
+    private final ArrayMap<AccessibilityStateChangeListener, Handler>
+            mAccessibilityStateChangeListeners = new ArrayMap<>();
 
-    private final CopyOnWriteArrayList<TouchExplorationStateChangeListener>
-            mTouchExplorationStateChangeListeners = new CopyOnWriteArrayList<>();
+    private final ArrayMap<TouchExplorationStateChangeListener, Handler>
+            mTouchExplorationStateChangeListeners = new ArrayMap<>();
 
-    private final CopyOnWriteArrayList<HighTextContrastChangeListener>
-            mHighTextContrastStateChangeListeners = new CopyOnWriteArrayList<>();
+    private final ArrayMap<HighTextContrastChangeListener, Handler>
+            mHighTextContrastStateChangeListeners = new ArrayMap<>();
 
-    private final CopyOnWriteArrayList<AccessibilityServicesStateChangeListener>
-            mServicesStateChangeListeners = new CopyOnWriteArrayList<>();
+    private final ArrayMap<AccessibilityServicesStateChangeListener, Handler>
+            mServicesStateChangeListeners = new ArrayMap<>();
+
     /**
      * Listener for the system accessibility state. To listen for changes to the
      * accessibility state on the device, implement this interface and register
@@ -229,7 +230,21 @@
 
         @Override
         public void notifyServicesStateChanged() {
-            mHandler.obtainMessage(MyCallback.MSG_NOTIFY_SERVICES_STATE_CHANGED).sendToTarget();
+            final ArrayMap<AccessibilityServicesStateChangeListener, Handler> listeners;
+            synchronized (mLock) {
+                if (mServicesStateChangeListeners.isEmpty()) {
+                    return;
+                }
+                listeners = new ArrayMap<>(mServicesStateChangeListeners);
+            }
+
+            int numListeners = listeners.size();
+            for (int i = 0; i < numListeners; i++) {
+                final AccessibilityServicesStateChangeListener listener =
+                        mServicesStateChangeListeners.keyAt(i);
+                mServicesStateChangeListeners.valueAt(i).post(() -> listener
+                        .onAccessibilityServicesStateChanged(AccessibilityManager.this));
+            }
         }
 
         @Override
@@ -565,73 +580,118 @@
 
     /**
      * Registers an {@link AccessibilityStateChangeListener} for changes in
-     * the global accessibility state of the system.
+     * the global accessibility state of the system. Equivalent to calling
+     * {@link #addAccessibilityStateChangeListener(AccessibilityStateChangeListener, Handler)}
+     * with a null handler.
      *
      * @param listener The listener.
-     * @return True if successfully registered.
+     * @return Always returns {@code true}.
      */
     public boolean addAccessibilityStateChangeListener(
             @NonNull AccessibilityStateChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mAccessibilityStateChangeListeners.add(listener);
+        addAccessibilityStateChangeListener(listener, null);
+        return true;
+    }
+
+    /**
+     * Registers an {@link AccessibilityStateChangeListener} for changes in
+     * the global accessibility state of the system. If the listener has already been registered,
+     * the handler used to call it back is updated.
+     *
+     * @param listener The listener.
+     * @param handler The handler on which the listener should be called back, or {@code null}
+     *                for a callback on the process's main handler.
+     */
+    public void addAccessibilityStateChangeListener(
+            @NonNull AccessibilityStateChangeListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            mAccessibilityStateChangeListeners
+                    .put(listener, (handler == null) ? mHandler : handler);
+        }
     }
 
     /**
      * Unregisters an {@link AccessibilityStateChangeListener}.
      *
      * @param listener The listener.
-     * @return True if successfully unregistered.
+     * @return True if the listener was previously registered.
      */
     public boolean removeAccessibilityStateChangeListener(
             @NonNull AccessibilityStateChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mAccessibilityStateChangeListeners.remove(listener);
+        synchronized (mLock) {
+            int index = mAccessibilityStateChangeListeners.indexOfKey(listener);
+            mAccessibilityStateChangeListeners.remove(listener);
+            return (index >= 0);
+        }
     }
 
     /**
      * Registers a {@link TouchExplorationStateChangeListener} for changes in
-     * the global touch exploration state of the system.
+     * the global touch exploration state of the system. Equivalent to calling
+     * {@link #addTouchExplorationStateChangeListener(TouchExplorationStateChangeListener, Handler)}
+     * with a null handler.
      *
      * @param listener The listener.
-     * @return True if successfully registered.
+     * @return Always returns {@code true}.
      */
     public boolean addTouchExplorationStateChangeListener(
             @NonNull TouchExplorationStateChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mTouchExplorationStateChangeListeners.add(listener);
+        addTouchExplorationStateChangeListener(listener, null);
+        return true;
+    }
+
+    /**
+     * Registers an {@link TouchExplorationStateChangeListener} for changes in
+     * the global touch exploration state of the system. If the listener has already been
+     * registered, the handler used to call it back is updated.
+     *
+     * @param listener The listener.
+     * @param handler The handler on which the listener should be called back, or {@code null}
+     *                for a callback on the process's main handler.
+     */
+    public void addTouchExplorationStateChangeListener(
+            @NonNull TouchExplorationStateChangeListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            mTouchExplorationStateChangeListeners
+                    .put(listener, (handler == null) ? mHandler : handler);
+        }
     }
 
     /**
      * Unregisters a {@link TouchExplorationStateChangeListener}.
      *
      * @param listener The listener.
-     * @return True if successfully unregistered.
+     * @return True if listener was previously registered.
      */
     public boolean removeTouchExplorationStateChangeListener(
             @NonNull TouchExplorationStateChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mTouchExplorationStateChangeListeners.remove(listener);
+        synchronized (mLock) {
+            int index = mTouchExplorationStateChangeListeners.indexOfKey(listener);
+            mTouchExplorationStateChangeListeners.remove(listener);
+            return (index >= 0);
+        }
     }
 
     /**
      * Registers a {@link AccessibilityServicesStateChangeListener}.
      *
      * @param listener The listener.
-     * @return True if successfully registered.
-     *
+     * @param handler The handler on which the listener should be called back, or {@code null}
+     *                for a callback on the process's main handler.
      * @hide
      */
     public void addAccessibilityServicesStateChangeListener(
-            @NonNull AccessibilityServicesStateChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        mServicesStateChangeListeners.add(listener);
+            @NonNull AccessibilityServicesStateChangeListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            mServicesStateChangeListeners
+                    .put(listener, (handler == null) ? mHandler : handler);
+        }
     }
 
     /**
      * Unregisters a {@link AccessibilityServicesStateChangeListener}.
      *
      * @param listener The listener.
-     * @return True if successfully unregistered.
      *
      * @hide
      */
@@ -646,28 +706,29 @@
      * the global high text contrast state of the system.
      *
      * @param listener The listener.
-     * @return True if successfully registered.
      *
      * @hide
      */
-    public boolean addHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mHighTextContrastStateChangeListeners.add(listener);
+    public void addHighTextContrastStateChangeListener(
+            @NonNull HighTextContrastChangeListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            mHighTextContrastStateChangeListeners
+                    .put(listener, (handler == null) ? mHandler : handler);
+        }
     }
 
     /**
      * Unregisters a {@link HighTextContrastChangeListener}.
      *
      * @param listener The listener.
-     * @return True if successfully unregistered.
      *
      * @hide
      */
-    public boolean removeHighTextContrastStateChangeListener(
+    public void removeHighTextContrastStateChangeListener(
             @NonNull HighTextContrastChangeListener listener) {
-        // Final CopyOnWriteArrayList - no lock needed.
-        return mHighTextContrastStateChangeListeners.remove(listener);
+        synchronized (mLock) {
+            mHighTextContrastStateChangeListeners.remove(listener);
+        }
     }
 
     /**
@@ -732,15 +793,15 @@
         mIsHighTextContrastEnabled = highTextContrastEnabled;
 
         if (wasEnabled != enabled) {
-            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED);
+            notifyAccessibilityStateChanged();
         }
 
         if (wasTouchExplorationEnabled != touchExplorationEnabled) {
-            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_EXPLORATION_STATE_CHANGED);
+            notifyTouchExplorationStateChanged();
         }
 
         if (wasHighTextContrastEnabled != highTextContrastEnabled) {
-            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED);
+            notifyHighTextContrastStateChanged();
         }
     }
 
@@ -932,81 +993,78 @@
     /**
      * Notifies the registered {@link AccessibilityStateChangeListener}s.
      */
-    private void handleNotifyAccessibilityStateChanged() {
+    private void notifyAccessibilityStateChanged() {
         final boolean isEnabled;
+        final ArrayMap<AccessibilityStateChangeListener, Handler> listeners;
         synchronized (mLock) {
+            if (mAccessibilityStateChangeListeners.isEmpty()) {
+                return;
+            }
             isEnabled = mIsEnabled;
+            listeners = new ArrayMap<>(mAccessibilityStateChangeListeners);
         }
-        // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
-        for (AccessibilityStateChangeListener listener : mAccessibilityStateChangeListeners) {
-            listener.onAccessibilityStateChanged(isEnabled);
+
+        int numListeners = listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            final AccessibilityStateChangeListener listener =
+                    mAccessibilityStateChangeListeners.keyAt(i);
+            mAccessibilityStateChangeListeners.valueAt(i)
+                    .post(() -> listener.onAccessibilityStateChanged(isEnabled));
         }
     }
 
     /**
      * Notifies the registered {@link TouchExplorationStateChangeListener}s.
      */
-    private void handleNotifyTouchExplorationStateChanged() {
+    private void notifyTouchExplorationStateChanged() {
         final boolean isTouchExplorationEnabled;
+        final ArrayMap<TouchExplorationStateChangeListener, Handler> listeners;
         synchronized (mLock) {
+            if (mTouchExplorationStateChangeListeners.isEmpty()) {
+                return;
+            }
             isTouchExplorationEnabled = mIsTouchExplorationEnabled;
+            listeners = new ArrayMap<>(mTouchExplorationStateChangeListeners);
         }
-        // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
-        for (TouchExplorationStateChangeListener listener :mTouchExplorationStateChangeListeners) {
-            listener.onTouchExplorationStateChanged(isTouchExplorationEnabled);
+
+        int numListeners = listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            final TouchExplorationStateChangeListener listener =
+                    mTouchExplorationStateChangeListeners.keyAt(i);
+            mTouchExplorationStateChangeListeners.valueAt(i)
+                    .post(() -> listener.onTouchExplorationStateChanged(isTouchExplorationEnabled));
         }
     }
 
     /**
      * Notifies the registered {@link HighTextContrastChangeListener}s.
      */
-    private void handleNotifyHighTextContrastStateChanged() {
+    private void notifyHighTextContrastStateChanged() {
         final boolean isHighTextContrastEnabled;
+        final ArrayMap<HighTextContrastChangeListener, Handler> listeners;
         synchronized (mLock) {
+            if (mHighTextContrastStateChangeListeners.isEmpty()) {
+                return;
+            }
             isHighTextContrastEnabled = mIsHighTextContrastEnabled;
+            listeners = new ArrayMap<>(mHighTextContrastStateChangeListeners);
         }
-        // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
-        for (HighTextContrastChangeListener listener : mHighTextContrastStateChangeListeners) {
-            listener.onHighTextContrastStateChanged(isHighTextContrastEnabled);
-        }
-    }
 
-    /**
-     * Notifies the registered {@link AccessibilityServicesStateChangeListener}s.
-     */
-    private void handleNotifyServicesStateChanged() {
-        // Listeners are a final CopyOnWriteArrayList, hence no lock needed.
-        for (AccessibilityServicesStateChangeListener listener : mServicesStateChangeListeners) {
-            listener.onAccessibilityServicesStateChanged(this);
+        int numListeners = listeners.size();
+        for (int i = 0; i < numListeners; i++) {
+            final HighTextContrastChangeListener listener =
+                    mHighTextContrastStateChangeListeners.keyAt(i);
+            mHighTextContrastStateChangeListeners.valueAt(i)
+                    .post(() -> listener.onHighTextContrastStateChanged(isHighTextContrastEnabled));
         }
     }
 
     private final class MyCallback implements Handler.Callback {
-        public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1;
-        public static final int MSG_NOTIFY_EXPLORATION_STATE_CHANGED = 2;
-        public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3;
-        public static final int MSG_SET_STATE = 4;
-        public static final int MSG_NOTIFY_SERVICES_STATE_CHANGED = 5;
+        public static final int MSG_SET_STATE = 1;
 
         @Override
         public boolean handleMessage(Message message) {
             switch (message.what) {
-                case MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED: {
-                    handleNotifyAccessibilityStateChanged();
-                } break;
-
-                case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: {
-                    handleNotifyTouchExplorationStateChanged();
-                } break;
-
-                case MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED: {
-                    handleNotifyHighTextContrastStateChanged();
-                } break;
-
-                case MSG_NOTIFY_SERVICES_STATE_CHANGED: {
-                    handleNotifyServicesStateChanged();
-                } break;
-
                 case MSG_SET_STATE: {
                     // See comment at mClient
                     final int state = message.arg1;
diff --git a/core/java/android/view/autofill/AutofillId.java b/core/java/android/view/autofill/AutofillId.java
index d678015..268f7f3 100644
--- a/core/java/android/view/autofill/AutofillId.java
+++ b/core/java/android/view/autofill/AutofillId.java
@@ -30,7 +30,6 @@
     private final boolean mVirtual;
     private final int mVirtualId;
 
-    // TODO(b/33197203): use factory and cache values, since they're immutable
     /** @hide */
     public AutofillId(int id) {
         mVirtual = false;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 981be21..caf188d 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -51,12 +51,10 @@
 import java.util.Objects;
 
 /**
- * App entry point to the AutoFill Framework.
+ * App entry point to the Autofill Framework.
  *
  * <p>It is safe to call into this from any thread.
  */
-// TODO(b/33197203): improve this javadoc
-//TODO(b/33197203): restrict manager calls to activity
 public final class AutofillManager {
 
     private static final String TAG = "AutofillManager";
@@ -101,17 +99,15 @@
     static final String SESSION_ID_TAG = "android:sessionId";
     static final String LAST_AUTOFILLED_DATA_TAG = "android:lastAutoFilledData";
 
-    // Public flags start from the lowest bit
     /**
-     * Indicates autofill was explicitly requested by the user.
-     *
      * @deprecated Use {@link android.service.autofill.FillRequest#FLAG_MANUAL_REQUEST}
+     * @hide
      */
-    // TODO(b/33197203): remove (and change value of private flags)
+    // TODO(b/37563972): remove (and change value of private flags)
     @Deprecated
     public static final int FLAG_MANUAL_REQUEST = 0x1;
 
-    // Private flags start from the highest bit
+    // TODO(b/37563972): start from 0x1 once FLAG_MANUAL_REQUEST is gone
     /** @hide */ public static final int FLAG_START_SESSION = 0x80000000;
     /** @hide */ public static final int FLAG_VIEW_ENTERED =  0x40000000;
     /** @hide */ public static final int FLAG_VIEW_EXITED =   0x20000000;
@@ -663,6 +659,39 @@
         }
     }
 
+    /**
+     * Returns {@code true} if the calling application provides a {@link AutofillService} that is
+     * enabled for the current user, or {@code false} otherwise.
+     */
+    public boolean hasEnabledAutofillServices() {
+        if (mService == null) return false;
+
+        try {
+            return mService.isServiceEnabled(mContext.getUserId(), mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns {@code true} if Autofill is supported for this user.
+     *
+     * <p>Autofill is typically supported, but it could be unsupported in cases like:
+     * <ol>
+     *     <li>Low-end devices.
+     *     <li>Device policy rules that forbid its usage.
+     * </ol>
+     */
+    public boolean isAutofillSupported() {
+        if (mService == null) return false;
+
+        try {
+            return mService.isServiceSupported(mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private AutofillClient getClientLocked() {
         if (mContext instanceof AutofillClient) {
             return (AutofillClient) mContext;
@@ -675,7 +704,7 @@
         if (!hasAutofillFeature()) {
             return;
         }
-        // TODO(b/33197203): the result code is being ignored, so this method is not reliably
+        // TODO: the result code is being ignored, so this method is not reliably
         // handling the cases where it's not RESULT_OK: it works fine if the service does not
         // set the EXTRA_AUTHENTICATION_RESULT extra, but it could cause weird results if the
         // service set the extra and returned RESULT_CANCELED...
@@ -1323,8 +1352,6 @@
         @Override
         public void autofill(int sessionId, IBinder windowToken, List<AutofillId> ids,
                 List<AutofillValue> values) {
-            // TODO(b/33197203): must keep the dataset so subsequent calls pass the same
-            // dataset.extras to service
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
                 afm.mContext.getMainThreadHandler().post(
diff --git a/core/java/android/view/autofill/AutofillValue.java b/core/java/android/view/autofill/AutofillValue.java
index e2dd7fe..b1a9d90 100644
--- a/core/java/android/view/autofill/AutofillValue.java
+++ b/core/java/android/view/autofill/AutofillValue.java
@@ -252,7 +252,6 @@
      *
      * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
      */
-    // TODO(b/33197203): use cache
     public static AutofillValue forText(@Nullable CharSequence value) {
         return value == null ? null : new AutofillValue(AUTOFILL_TYPE_TEXT, value);
     }
diff --git a/core/java/android/view/autofill/Helper.java b/core/java/android/view/autofill/Helper.java
index aa94de0..2b25ae7 100644
--- a/core/java/android/view/autofill/Helper.java
+++ b/core/java/android/view/autofill/Helper.java
@@ -25,7 +25,8 @@
 /** @hide */
 public final class Helper {
 
-    public static final boolean DEBUG = true; // TODO(b/33197203): set to false when stable
+    // TODO(b/36141126): set to false and remove guard from places that should always be on
+    public static final boolean DEBUG = true;
     public static final boolean VERBOSE = false;
     public static final String REDACTED = "[REDACTED]";
 
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index df777c4..9417bd0 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -44,4 +44,6 @@
     void setAuthenticationResult(in Bundle data, int sessionId, int userId);
     void setHasCallback(int sessionId, int userId, boolean hasIt);
     void disableOwnedAutofillServices(int userId);
+    boolean isServiceSupported(int userId);
+    boolean isServiceEnabled(int userId, String packageName);
 }
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 2123deb..b519ec9 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -40,6 +40,7 @@
 
     private static final String WEBVIEW_ZYGOTE_SERVICE_32 = "webview_zygote32";
     private static final String WEBVIEW_ZYGOTE_SERVICE_64 = "webview_zygote64";
+    private static final String WEBVIEW_ZYGOTE_SOCKET = "webview_zygote";
 
     /**
      * Lock object that protects all other static members.
@@ -202,7 +203,7 @@
         }
 
         try {
-            sZygote = new ZygoteProcess("webview_zygote", null);
+            sZygote = new ZygoteProcess(WEBVIEW_ZYGOTE_SOCKET, null);
 
             // All the work below is usually done by LoadedApk, but the zygote can't talk to
             // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so
@@ -217,6 +218,8 @@
             final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
                     TextUtils.join(File.pathSeparator, zipPaths);
 
+            waitForZygote();
+
             Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
             sZygote.preloadPackageForAbi(zip, librarySearchPath, sPackageCacheKey,
                                          Build.SUPPORTED_ABIS[0]);
@@ -225,4 +228,25 @@
             sZygote = null;
         }
     }
+
+    /**
+     * Wait until a connection to the Zygote can be established.
+     */
+    private static void waitForZygote() {
+        while (true) {
+            try {
+                final ZygoteProcess.ZygoteState zs =
+                        ZygoteProcess.ZygoteState.connect(WEBVIEW_ZYGOTE_SOCKET);
+                zs.close();
+                break;
+            } catch (IOException ioe) {
+                Log.w(LOGTAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
+            }
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ie) {
+            }
+        }
+    }
 }
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index f80c9e6..816c949 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -491,8 +491,6 @@
         return AbsSpinner.class.getName();
     }
 
-    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
-
     @Override
     public void autofill(AutofillValue value) {
         if (!isEnabled()) return;
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index c7ba7b5..0762b15 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -574,8 +574,6 @@
         stream.addProperty("checked", isChecked());
     }
 
-    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
-
     @Override
     public void onProvideAutofillStructure(ViewStructure structure, int flags) {
         super.onProvideAutofillStructure(structure, flags);
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 463ff58..0dce079 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -764,8 +764,6 @@
         void onValidationChanged(boolean valid);
     }
 
-    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
-
     @Override
     public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
         // This view is self-sufficient for autofill, so it needs to call
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index 08e6575..5c4d4d2 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -417,8 +417,6 @@
         }
     }
 
-    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
-
     @Override
     public void onProvideAutofillStructure(ViewStructure structure, int flags) {
         super.onProvideAutofillStructure(structure, flags);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 036b391..e534233 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -413,6 +413,30 @@
         recalculateMemoryUsage();
     }
 
+    private static class RemoteViewsContextWrapper extends ContextWrapper {
+        private final Context mContextForResources;
+
+        RemoteViewsContextWrapper(Context context, Context contextForResources) {
+            super(context);
+            mContextForResources = contextForResources;
+        }
+
+        @Override
+        public Resources getResources() {
+            return mContextForResources.getResources();
+        }
+
+        @Override
+        public Resources.Theme getTheme() {
+            return mContextForResources.getTheme();
+        }
+
+        @Override
+        public String getPackageName() {
+            return mContextForResources.getPackageName();
+        }
+    }
+
     private class SetEmptyView extends Action {
         int viewId;
         int emptyViewId;
@@ -3240,20 +3264,7 @@
         // still returns the current users userId so settings like data / time formats
         // are loaded without requiring cross user persmissions.
         final Context contextForResources = getContextForResources(context);
-        Context inflationContext = new ContextWrapper(context) {
-            @Override
-            public Resources getResources() {
-                return contextForResources.getResources();
-            }
-            @Override
-            public Resources.Theme getTheme() {
-                return contextForResources.getTheme();
-            }
-            @Override
-            public String getPackageName() {
-                return contextForResources.getPackageName();
-            }
-        };
+        Context inflationContext = new RemoteViewsContextWrapper(context, contextForResources);
 
         LayoutInflater inflater = (LayoutInflater)
                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java
index 57e2ece..9190117 100644
--- a/core/java/android/widget/SimpleAdapter.java
+++ b/core/java/android/widget/SimpleAdapter.java
@@ -320,9 +320,6 @@
         return mFilter;
     }
 
-    // TODO(b/33197203): implement getAutofillOptions
-
-
     /**
      * This class can be used by external clients of SimpleAdapter to bind
      * values to views.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f42d6c8..399cfac 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10170,8 +10170,6 @@
         structure.setInputType(getInputType());
     }
 
-    // TODO(b/33197203): add unit/CTS tests for autofill methods
-
     boolean canRequestAutofill() {
         final AutofillManager afm = mContext.getSystemService(AutofillManager.class);
         if (afm != null) {
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index fb00c4392..df99fb4 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -519,8 +519,6 @@
         }
     }
 
-    // TODO(b/33197203): add unit/CTS tests for autofill methods (and make sure they handle enable)
-
     @Override
     public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
         // This view is self-sufficient for autofill, so it needs to call
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index 73b62a5..54b9cd8 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -438,6 +438,14 @@
                             + " in the manifest.");
                     continue;
                 }
+                if (PackageManager.PERMISSION_GRANTED != mPm.checkPermission(
+                        ResolverRankerService.HOLD_PERMISSION,
+                        resolveInfo.serviceInfo.packageName)) {
+                    Log.w(TAG, "ResolverRankerService " + componentName + " does not hold"
+                            + " permission " + ResolverRankerService.HOLD_PERMISSION
+                            + " - this service will not be queried for ResolverComparator.");
+                    continue;
+                }
             } catch (NameNotFoundException e) {
                 Log.e(TAG, "Could not look up service " + componentName
                         + "; component name not found");
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 2c8e4e0..73886a7 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -169,6 +169,13 @@
     }
 
     /**
+     * Length of the given array or 0 if it's null.
+     */
+    public static int size(@Nullable Object[] array) {
+        return array == null ? 0 : array.length;
+    }
+
+    /**
      * Checks that value is present as at least one of the elements of the array.
      * @param array the array to check in
      * @param value the value to check for
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 96285cd..ceb3cc8 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -234,6 +234,7 @@
     libseccomp_policy \
     libselinux \
     libcrypto \
+    libgrallocusage \
 
 LOCAL_SHARED_LIBRARIES := \
     libmemtrack \
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index ed0ab60..4b31c91 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -34,6 +34,7 @@
 #include <private/gui/ComposerService.h>
 
 #include <hardware/gralloc1.h>
+#include <grallocusage/GrallocUsageConversion.h>
 
 #include "core_jni_helpers.h"
 
@@ -85,7 +86,7 @@
             &producerUsage, &consumerUsage, usage, 0);
 
     sp<GraphicBuffer> buffer = new GraphicBuffer(width, height, pixelFormat, layers,
-            producerUsage, consumerUsage,
+            android_convertGralloc1To0Usage(producerUsage, consumerUsage),
             std::string("HardwareBuffer pid [") + std::to_string(getpid()) +"]");
     status_t error = buffer->initCheck();
     if (error < 0) {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index b95258b..6000fb5 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -685,11 +685,14 @@
 
     // Grant CAP_WAKE_ALARM to the Bluetooth process.
     // Additionally, allow bluetooth to open packet sockets so it can start the DHCP client.
+    // Grant CAP_SYS_NICE to allow Bluetooth to set RT priority for
+    // audio-related threads.
     // TODO: consider making such functionality an RPC to netd.
     if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
       capabilities |= (1LL << CAP_WAKE_ALARM);
       capabilities |= (1LL << CAP_NET_RAW);
       capabilities |= (1LL << CAP_NET_BIND_SERVICE);
+      capabilities |= (1LL << CAP_SYS_NICE);
     }
 
     // Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1777f24..3131302 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3161,6 +3161,14 @@
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Must be held by services that extend
+         {@link android.service.resolver.ResolverRankerService}.
+         <p>Protection level: signature|privileged
+         @hide
+    -->
+    <permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE"
+                android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Must be required by services that extend
          {@link android.service.resolver.ResolverRankerService}, to ensure that only the system can
          bind to them.
@@ -3702,14 +3710,6 @@
         <service android:name="com.android.server.PreloadsFileCacheExpirationJobService"
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
-
-        <service android:name="com.android.internal.app.LRResolverRankerService"
-            android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
-            android:priority="-1" >
-            <intent-filter>
-                <action android:name="android.service.resolver.ResolverRankerService" />
-            </intent-filter>
-        </service>
     </application>
 
 </manifest>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6e790a7..3e11368 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3426,7 +3426,9 @@
             <flag name="flagIncludeNotImportantViews" value="0x00000002" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE}. -->
             <flag name="flagRequestTouchExplorationMode" value="0x00000004" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY}. -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY}.
+                 Not used by the framework.
+            -->
             <flag name="flagRequestEnhancedWebAccessibility" value="0x00000008" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}. -->
             <flag name="flagReportViewIds" value="0x00000010" />
@@ -3457,12 +3459,8 @@
          -->
         <attr name="canRequestTouchExplorationMode" format="boolean" />
         <!-- Attribute whether the accessibility service wants to be able to request enhanced
-             web accessibility enhancements. For example, installing scripts to make app
-             content more accessible.
-             <p>
-             Required to allow setting the {@link android.accessibilityservice
-             #AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} flag.
-             </p>
+             web accessibility enhancements.
+             {@deprecated Not used by the framework}
          -->
         <attr name="canRequestEnhancedWebAccessibility" format="boolean" />
         <!-- Attribute whether the accessibility service wants to be able to request to
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a5181fe..35b12ff 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -713,13 +713,6 @@
     <string name="capability_desc_canRequestTouchExploration">Tapped items will be spoken aloud
         and the screen can be explored using gestures.</string>
 
-    <!-- Title for the capability of an accessibility service to request enhanced web accessibility. -->
-    <string name="capability_title_canRequestEnhancedWebAccessibility">Turn on enhanced web
-        accessibility</string>
-    <!-- Description for the capability of an accessibility service to request enhanced web accessibility. -->
-    <string name="capability_desc_canRequestEnhancedWebAccessibility">Scripts may be installed to
-        make app content more accessible.</string>
-
     <!-- Title for the capability of an accessibility service to request to filter key events. -->
     <string name="capability_title_canRequestFilterKeyEvents">Observe text you type</string>
     <!-- Description for the capability of an accessibility service to request to filter key events. -->
diff --git a/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java b/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
index 497bc5c..ff9816a 100644
--- a/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
+++ b/core/tests/coretests/src/android/net/NetworkRecommendationProviderTest.java
@@ -1,26 +1,19 @@
 package android.net;
 
-import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
-import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
-
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertSame;
 import static junit.framework.Assert.fail;
-import static junit.framework.TestCase.assertEquals;
 
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 
 import android.Manifest.permission;
 import android.content.Context;
-import android.os.Bundle;
-import android.os.IRemoteCallback;
 import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -35,11 +28,9 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class NetworkRecommendationProviderTest {
-    @Mock private IRemoteCallback mMockRemoteCallback;
     @Mock private Context mContext;
     private NetworkRecProvider mRecProvider;
     private INetworkRecommendationProvider mStub;
-    private CountDownLatch mRecRequestLatch;
     private CountDownLatch mScoreRequestLatch;
     private NetworkKey[] mTestNetworkKeys;
 
@@ -48,10 +39,8 @@
         MockitoAnnotations.initMocks(this);
 
         Executor executor = Executors.newSingleThreadExecutor();
-        mRecRequestLatch = new CountDownLatch(1);
         mScoreRequestLatch = new CountDownLatch(1);
-        mRecProvider = new NetworkRecProvider(mContext, executor, mRecRequestLatch,
-                mScoreRequestLatch);
+        mRecProvider = new NetworkRecProvider(mContext, executor, mScoreRequestLatch);
         mStub = INetworkRecommendationProvider.Stub.asInterface(mRecProvider.getBinder());
         mTestNetworkKeys = new NetworkKey[2];
         mTestNetworkKeys[0] = new NetworkKey(new WifiKey("\"ssid_01\"", "00:00:00:00:00:11"));
@@ -59,69 +48,6 @@
     }
 
     @Test
-    public void testRecommendationRequestReceived() throws Exception {
-        final RecommendationRequest request = new RecommendationRequest.Builder().build();
-        final int sequence = 100;
-        mStub.requestRecommendation(request, mMockRemoteCallback, sequence);
-
-        // wait for onRequestRecommendation() to be called in our impl below.
-        mRecRequestLatch.await(200, TimeUnit.MILLISECONDS);
-        NetworkRecommendationProvider.ResultCallback expectedResultCallback =
-                new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
-        assertEquals(request, mRecProvider.mCapturedRequest);
-        assertEquals(expectedResultCallback, mRecProvider.mCapturedCallback);
-    }
-
-    @Test
-    public void testRecommendationRequest_permissionsEnforced() throws Exception {
-        final RecommendationRequest request = new RecommendationRequest.Builder().build();
-        final int sequence = 100;
-        Mockito.doThrow(new SecurityException())
-                .when(mContext)
-                .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES), anyString());
-
-        try {
-            mStub.requestRecommendation(request, mMockRemoteCallback, sequence);
-            fail("SecurityException expected.");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testResultCallbackOnResult() throws Exception {
-        final int sequence = 100;
-        final NetworkRecommendationProvider.ResultCallback callback =
-                new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
-
-        final RecommendationResult result = RecommendationResult.createDoNotConnectRecommendation();
-        callback.onResult(result);
-
-        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        Mockito.verify(mMockRemoteCallback).sendResult(bundleCaptor.capture());
-        Bundle capturedBundle = bundleCaptor.getValue();
-        assertEquals(sequence, capturedBundle.getInt(EXTRA_SEQUENCE));
-        assertSame(result, capturedBundle.getParcelable(EXTRA_RECOMMENDATION_RESULT));
-    }
-
-    @Test
-    public void testResultCallbackOnResult_runTwice_throwsException() throws Exception {
-        final int sequence = 100;
-        final NetworkRecommendationProvider.ResultCallback callback =
-                new NetworkRecommendationProvider.ResultCallback(mMockRemoteCallback, sequence);
-
-        final RecommendationResult result = RecommendationResult.createDoNotConnectRecommendation();
-        callback.onResult(result);
-
-        try {
-            callback.onResult(result);
-            fail("Callback ran more than once.");
-        } catch (IllegalStateException e) {
-            // expected
-        }
-    }
-
-    @Test
     public void testScoreRequestReceived() throws Exception {
         mStub.requestScores(mTestNetworkKeys);
 
@@ -162,28 +88,15 @@
     }
 
     private static class NetworkRecProvider extends NetworkRecommendationProvider {
-        private final CountDownLatch mRecRequestLatch;
         private final CountDownLatch mScoreRequestLatch;
-        RecommendationRequest mCapturedRequest;
-        ResultCallback mCapturedCallback;
         NetworkKey[] mCapturedNetworks;
 
-        NetworkRecProvider(Context context, Executor executor, CountDownLatch recRequestLatch,
-            CountDownLatch networkRequestLatch) {
+        NetworkRecProvider(Context context, Executor executor, CountDownLatch networkRequestLatch) {
             super(context, executor);
-            mRecRequestLatch = recRequestLatch;
             mScoreRequestLatch = networkRequestLatch;
         }
 
         @Override
-        public void onRequestRecommendation(RecommendationRequest request,
-                ResultCallback callback) {
-            mCapturedRequest = request;
-            mCapturedCallback = callback;
-            mRecRequestLatch.countDown();
-        }
-
-        @Override
         public void onRequestScores(NetworkKey[] networks) {
             mCapturedNetworks = networks;
             mScoreRequestLatch.countDown();
diff --git a/core/tests/coretests/src/android/net/RecommendationRequestTest.java b/core/tests/coretests/src/android/net/RecommendationRequestTest.java
deleted file mode 100644
index e2e6883..0000000
--- a/core/tests/coretests/src/android/net/RecommendationRequestTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package android.net;
-
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiConfiguration;
-import android.os.Parcel;
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-
-public class RecommendationRequestTest extends AndroidTestCase {
-    private ScanResult[] mScanResults;
-    private WifiConfiguration mDefaultConfig;
-    private WifiConfiguration mConnectedConfig;
-    private WifiConfiguration[] mConnectableConfigs;
-    private int mLastSelectedNetworkId;
-    private long mLastSelectedNetworkTimestamp;
-
-    @Override
-    public void setUp() throws Exception {
-        mScanResults = new ScanResult[2];
-        mScanResults[0] = new ScanResult();
-        mScanResults[1] = new ScanResult(
-                "ssid",
-                "bssid",
-                0L /*hessid*/,
-                1 /*anqpDominId*/,
-                "caps",
-                2 /*level*/,
-                3 /*frequency*/,
-                4L /*tsf*/,
-                5 /*distCm*/,
-                6 /*distSdCm*/,
-                7 /*channelWidth*/,
-                8 /*centerFreq0*/,
-                9 /*centerFreq1*/,
-                false /*is80211McRTTResponder*/);
-        mDefaultConfig = new WifiConfiguration();
-        mDefaultConfig.SSID = "default_config";
-        mConnectedConfig = new WifiConfiguration();
-        mConnectedConfig.SSID = "connected_config";
-        mConnectableConfigs = new WifiConfiguration[] {mDefaultConfig, mConnectedConfig};
-        mLastSelectedNetworkId = 5;
-        mLastSelectedNetworkTimestamp = SystemClock.elapsedRealtime();
-    }
-
-    public void testParceling() throws Exception {
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setDefaultWifiConfig(mDefaultConfig)
-                .setScanResults(mScanResults)
-                .setConnectedWifiConfig(mConnectedConfig)
-                .setConnectableConfigs(mConnectableConfigs)
-                .setLastSelectedNetwork(mLastSelectedNetworkId, mLastSelectedNetworkTimestamp)
-                .build();
-
-        RecommendationRequest parceled = passThroughParcel(request);
-        assertEquals(request.getDefaultWifiConfig().SSID,
-                parceled.getDefaultWifiConfig().SSID);
-        assertEquals(request.getConnectedConfig().SSID,
-                parceled.getConnectedConfig().SSID);
-        ScanResult[] parceledScanResults = parceled.getScanResults();
-        assertNotNull(parceledScanResults);
-        assertEquals(mScanResults.length, parceledScanResults.length);
-        for (int i = 0; i < mScanResults.length; i++) {
-            assertEquals(mScanResults[i].SSID, parceledScanResults[i].SSID);
-        }
-        WifiConfiguration[] parceledConfigs = parceled.getConnectableConfigs();
-        for (int i = 0; i < parceledConfigs.length; i++) {
-            assertEquals(mConnectableConfigs[i].SSID, parceledConfigs[i].SSID);
-        }
-        assertEquals(mLastSelectedNetworkId, parceled.getLastSelectedNetworkId());
-        assertEquals(mLastSelectedNetworkTimestamp, parceled.getLastSelectedNetworkTimestamp());
-    }
-
-    public void testParceling_nullScanResults() throws Exception {
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setDefaultWifiConfig(mDefaultConfig)
-                .build();
-
-        RecommendationRequest parceled = passThroughParcel(request);
-        ScanResult[] parceledScanResults = parceled.getScanResults();
-        assertNull(parceledScanResults);
-    }
-
-    public void testParceling_nullWifiConfigArray() throws Exception {
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .setDefaultWifiConfig(mDefaultConfig)
-                .build();
-
-        RecommendationRequest parceled = passThroughParcel(request);
-        WifiConfiguration[] parceledConfigs = parceled.getConnectableConfigs();
-        assertNull(parceledConfigs);
-    }
-
-    public void testParceling_unsetLastSelectedNetwork() throws Exception {
-        RecommendationRequest request = new RecommendationRequest.Builder()
-                .build();
-
-        RecommendationRequest parceled = passThroughParcel(request);
-
-        assertEquals(-1, parceled.getLastSelectedNetworkId());
-        assertEquals(0, parceled.getLastSelectedNetworkTimestamp());
-    }
-
-    private RecommendationRequest passThroughParcel(RecommendationRequest request) {
-        Parcel p = Parcel.obtain();
-        RecommendationRequest output = null;
-        try {
-            request.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            output = RecommendationRequest.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(output);
-        return output;
-    }
-}
diff --git a/core/tests/coretests/src/android/preference/PreferenceIconSpaceTest.java b/core/tests/coretests/src/android/preference/PreferenceIconSpaceTest.java
new file mode 100644
index 0000000..654474c
--- /dev/null
+++ b/core/tests/coretests/src/android/preference/PreferenceIconSpaceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.preference;
+
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PreferenceIconSpaceTest {
+
+    private TestPreference mPreference;
+
+    @Mock
+    private ViewGroup mViewGroup;
+    @Mock
+    private ImageView mIconView;
+    @Mock
+    private View mImageFrame;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mViewGroup.findViewById(com.android.internal.R.id.icon_frame))
+                .thenReturn(mImageFrame);
+        when(mViewGroup.findViewById(com.android.internal.R.id.icon))
+                .thenReturn(mIconView);
+
+        mPreference = new TestPreference(InstrumentationRegistry.getTargetContext());
+    }
+
+    @Test
+    public void bindView_iconSpaceReserved_shouldReserveIconSpace() {
+        mPreference.setIconSpaceReserved(true);
+        mPreference.bindView(mViewGroup);
+
+        verify(mIconView).setVisibility(View.INVISIBLE);
+        verify(mImageFrame).setVisibility(View.INVISIBLE);
+    }
+
+    @Test
+    public void bindView_iconSpaceNotReserved_shouldNotReserveIconSpace() {
+        mPreference.setIconSpaceReserved(false);
+        mPreference.bindView(mViewGroup);
+
+        verify(mIconView).setVisibility(View.GONE);
+        verify(mImageFrame).setVisibility(View.GONE);
+    }
+
+    @Test
+    public void bindView_hasIcon_shouldDisplayIcon() {
+        mPreference.setIcon(new ColorDrawable(Color.BLACK));
+        mPreference.bindView(mViewGroup);
+
+        verify(mIconView).setVisibility(View.VISIBLE);
+        verify(mImageFrame).setVisibility(View.VISIBLE);
+    }
+
+    private static class TestPreference extends Preference {
+
+        public TestPreference(Context context) {
+            super(context);
+        }
+
+        public void bindView(View view) {
+            onBindView(view);
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d7887d3..38ab865 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -376,7 +376,6 @@
 
     private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS =
              newHashSet(
-                 Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
                  Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
                  Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS,
                  Settings.Secure.ALWAYS_ON_VPN_APP,
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 86ab3dc..344f3c8 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -181,9 +181,6 @@
     <allow-in-power-save package="com.android.cellbroadcastreceiver" />
     <allow-in-power-save package="com.android.shell" />
 
-    <!-- STOPSHIP(b/36856786): Revert this once it is fixed properly -->
-    <allow-in-power-save package="com.google.android.apps.enterprise.dmagent" />
-
     <!-- These are the packages that are white-listed to be able to run as system user -->
     <system-user-whitelisted-app package="com.android.settings" />
 
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 7f07f03..efed165 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -356,4 +356,8 @@
         <permission name="android.permission.CONTROL_VPN"/>
     </privapp-permissions>
 
+    <privapp-permissions package="com.google.android.ext.services">
+        <permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
+    </privapp-permissions>
+
 </permissions>
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 115c77f..aedf6a7 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -27,11 +27,9 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.content.Context;
 import android.content.res.AssetManager;
 import android.graphics.FontListParser;
 import android.graphics.fonts.FontRequest;
-import android.graphics.fonts.FontResult;
 import android.graphics.fonts.FontVariationAxis;
 import android.graphics.fonts.FontVariationAxis.InvalidFormatException;
 import android.net.Uri;
@@ -100,10 +98,6 @@
     static Typeface[] sDefaults;
     private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache =
             new LongSparseArray<>(3);
-    @GuardedBy("sLock")
-    private static FontsContract sFontsContract;
-    @GuardedBy("sLock")
-    private static Handler sHandler;
 
     /**
      * Cache for Typeface objects dynamically loaded from assets. Currently max size is 16.
@@ -205,16 +199,9 @@
     public static Typeface createFromResources(
             FamilyResourceEntry entry, AssetManager mgr, String path) {
         if (sFallbackFonts != null) {
-            Typeface typeface = findFromCache(mgr, path);
-            if (typeface != null) return typeface;
-
             if (entry instanceof ProviderResourceEntry) {
                 final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
                 // Downloadable font
-                typeface = findFromCache(providerEntry.getAuthority(), providerEntry.getQuery());
-                if (typeface != null) {
-                    return typeface;
-                }
                 List<List<String>> givenCerts = providerEntry.getCerts();
                 List<List<byte[]>> certs = new ArrayList<>();
                 if (givenCerts != null) {
@@ -229,11 +216,15 @@
                 }
                 // Downloaded font and it wasn't cached, request it again and return a
                 // default font instead (nothing we can do now).
-                create(new FontRequest(providerEntry.getAuthority(), providerEntry.getPackage(),
-                        providerEntry.getQuery(), certs), NO_OP_REQUEST_CALLBACK);
-                return DEFAULT;
+                FontRequest request = new FontRequest(providerEntry.getAuthority(),
+                        providerEntry.getPackage(), providerEntry.getQuery(), certs);
+                Typeface typeface = FontsContract.getFontOrWarmUpCache(request);
+                return typeface == null ? DEFAULT : typeface;
             }
 
+            Typeface typeface = findFromCache(mgr, path);
+            if (typeface != null) return typeface;
+
             // family is FontFamilyFilesResourceEntry
             final FontFamilyFilesResourceEntry filesEntry =
                     (FontFamilyFilesResourceEntry) entry;
@@ -283,223 +274,6 @@
     }
 
     /**
-     * Set the application context so we can generate font requests from the provider. This should
-     * be called from ActivityThread when the application binds, as we preload fonts.
-     * @hide
-     */
-    public static void setApplicationContext(Context context) {
-        synchronized (sLock) {
-            if (sFontsContract == null) {
-                sFontsContract = new FontsContract(context);
-                sHandler = new Handler();
-            }
-        }
-    }
-
-    /**
-     * Create a typeface object given a font request. The font will be asynchronously fetched,
-     * therefore the result is delivered to the given callback. See {@link FontRequest}.
-     * Only one of the methods in callback will be invoked, depending on whether the request
-     * succeeds or fails. These calls will happen on the main thread.
-     * @param request A {@link FontRequest} object that identifies the provider and query for the
-     *                request. May not be null.
-     * @param callback A callback that will be triggered when results are obtained. May not be null.
-     */
-    @Deprecated
-    public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) {
-        // Check the cache first
-        // TODO: would the developer want to avoid a cache hit and always ask for the freshest
-        // result?
-        Typeface cachedTypeface = findFromCache(
-                request.getProviderAuthority(), request.getQuery());
-        if (cachedTypeface != null) {
-            sHandler.post(() -> callback.onTypefaceRetrieved(cachedTypeface));
-            return;
-        }
-        synchronized (sLock) {
-            if (sFontsContract == null) {
-                throw new RuntimeException("Context not initialized, can't query provider");
-            }
-            final ResultReceiver receiver = new ResultReceiver(null) {
-                @Override
-                public void onReceiveResult(int resultCode, Bundle resultData) {
-                    sHandler.post(() -> receiveResult(request, callback, resultCode, resultData));
-                }
-            };
-            sFontsContract.getFont(request, receiver);
-        }
-    }
-
-    private static Typeface findFromCache(String providerAuthority, String query) {
-        synchronized (sDynamicTypefaceCache) {
-            final String key = createProviderUid(providerAuthority, query);
-            Typeface typeface = sDynamicTypefaceCache.get(key);
-            if (typeface != null) {
-                return typeface;
-            }
-        }
-        return null;
-    }
-
-    private static void receiveResult(FontRequest request, FontRequestCallback callback,
-            int resultCode, Bundle resultData) {
-        Typeface cachedTypeface = findFromCache(
-                request.getProviderAuthority(), request.getQuery());
-        if (cachedTypeface != null) {
-            // We already know the result.
-            // Probably the requester requests the same font again in a short interval.
-            callback.onTypefaceRetrieved(cachedTypeface);
-            return;
-        }
-        if (resultCode != FontsContract.Columns.RESULT_CODE_OK) {
-            callback.onTypefaceRequestFailed(resultCode);
-            return;
-        }
-        if (resultData == null) {
-            callback.onTypefaceRequestFailed(
-                    FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
-            return;
-        }
-        List<FontResult> resultList =
-                resultData.getParcelableArrayList(FontsContract.PARCEL_FONT_RESULTS);
-        if (resultList == null || resultList.isEmpty()) {
-            callback.onTypefaceRequestFailed(
-                    FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
-            return;
-        }
-        FontFamily fontFamily = new FontFamily();
-        for (int i = 0; i < resultList.size(); ++i) {
-            FontResult result = resultList.get(i);
-            ParcelFileDescriptor fd = result.getFileDescriptor();
-            if (fd == null) {
-                callback.onTypefaceRequestFailed(
-                        FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
-                return;
-            }
-            try (FileInputStream is = new FileInputStream(fd.getFileDescriptor())) {
-                FileChannel fileChannel = is.getChannel();
-                long fontSize = fileChannel.size();
-                ByteBuffer fontBuffer = fileChannel.map(
-                        FileChannel.MapMode.READ_ONLY, 0, fontSize);
-                int weight = result.getWeight();
-                int italic = result.getItalic() ? STYLE_ITALIC : STYLE_NORMAL;
-                FontVariationAxis[] axes = null;
-                try {
-                    axes = FontVariationAxis.fromFontVariationSettings(
-                            result.getFontVariationSettings());
-                } catch (FontVariationAxis.InvalidFormatException e) {
-                    // TODO: Nice to pass FontVariationAxis[] directly instead of string.
-                }
-                if (!fontFamily.addFontFromBuffer(fontBuffer, result.getTtcIndex(),
-                        axes, weight, italic)) {
-                    Log.e(TAG, "Error creating font " + request.getQuery());
-                    callback.onTypefaceRequestFailed(
-                            FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
-                    return;
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "Error reading font " + request.getQuery(), e);
-                callback.onTypefaceRequestFailed(
-                        FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
-                return;
-            } finally {
-                IoUtils.closeQuietly(fd);
-            }
-        }
-        if (!fontFamily.freeze()) {
-            callback.onTypefaceRequestFailed(
-                    FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
-            return;
-        }
-        Typeface typeface = Typeface.createFromFamiliesWithDefault(
-                new FontFamily[] { fontFamily },
-                RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
-        synchronized (sDynamicTypefaceCache) {
-            String key = createProviderUid(request.getProviderAuthority(), request.getQuery());
-            sDynamicTypefaceCache.put(key, typeface);
-        }
-        callback.onTypefaceRetrieved(typeface);
-    }
-
-    /**
-     * Interface used to receive asynchronously fetched typefaces.
-     */
-    @Deprecated
-    public interface FontRequestCallback {
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
-         * provider was not found on the device.
-         */
-        int FAIL_REASON_PROVIDER_NOT_FOUND = FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND;
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
-         * provider must be authenticated and the given certificates do not match its signature.
-         */
-        int FAIL_REASON_WRONG_CERTIFICATES = FontsContract.RESULT_CODE_WRONG_CERTIFICATES;
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
-         * returned by the provider was not loaded properly.
-         */
-        int FAIL_REASON_FONT_LOAD_ERROR = -3;
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
-         * provider did not return any results for the given query.
-         */
-        int FAIL_REASON_FONT_NOT_FOUND = FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND;
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
-         * provider found the queried font, but it is currently unavailable.
-         */
-        int FAIL_REASON_FONT_UNAVAILABLE = FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE;
-        /**
-         * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
-         * query was not supported by the provider.
-         */
-        int FAIL_REASON_MALFORMED_QUERY = FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY;
-
-        /** @hide */
-        @IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR,
-                FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE,
-                FAIL_REASON_MALFORMED_QUERY })
-        @Retention(RetentionPolicy.SOURCE)
-        @interface FontRequestFailReason {}
-
-        /**
-         * Called then a Typeface request done via {@link Typeface#create(FontRequest,
-         * FontRequestCallback)} is complete. Note that this method will not be called if
-         * {@link #onTypefaceRequestFailed(int)} is called instead.
-         * @param typeface  The Typeface object retrieved.
-         */
-        void onTypefaceRetrieved(Typeface typeface);
-
-        /**
-         * Called when a Typeface request done via {@link Typeface#create(FontRequest,
-         * FontRequestCallback)} fails.
-         * @param reason May be one of {@link #FAIL_REASON_PROVIDER_NOT_FOUND},
-         *               {@link #FAIL_REASON_FONT_NOT_FOUND},
-         *               {@link #FAIL_REASON_FONT_LOAD_ERROR},
-         *               {@link #FAIL_REASON_FONT_UNAVAILABLE} or
-         *               {@link #FAIL_REASON_MALFORMED_QUERY} if returned by the system. May also be
-         *               a positive value greater than 0 defined by the font provider as an
-         *               additional error code. Refer to the provider's documentation for more
-         *               information on possible returned error codes.
-         */
-        void onTypefaceRequestFailed(@FontRequestFailReason int reason);
-    }
-
-    private static final FontRequestCallback NO_OP_REQUEST_CALLBACK = new FontRequestCallback() {
-        @Override
-        public void onTypefaceRetrieved(Typeface typeface) {
-            // Do nothing.
-        }
-
-        @Override
-        public void onTypefaceRequestFailed(@FontRequestFailReason int reason) {
-            // Do nothing.
-        }
-    };
-
-    /**
      * A builder class for creating new Typeface instance.
      *
      * <p>
diff --git a/graphics/java/android/graphics/fonts/FontResult.java b/graphics/java/android/graphics/fonts/FontResult.java
deleted file mode 100644
index 20e736e..0000000
--- a/graphics/java/android/graphics/fonts/FontResult.java
+++ /dev/null
@@ -1,115 +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.fonts;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.Paint;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * Results returned from a Font Provider to the system.
- * @hide
- */
-public final class FontResult implements Parcelable {
-    private final ParcelFileDescriptor mFileDescriptor;
-    private final int mTtcIndex;
-    private final String mFontVariationSettings;
-    private final int mWeight;
-    private final boolean mItalic;
-
-    /**
-     * Creates a FontResult with all the information needed about a provided font.
-     * @param fileDescriptor A ParcelFileDescriptor pointing to the font file. This shoult point to
-     *                       a real file or shared memory, as the client will mmap the given file
-     *                       descriptor. Pipes, sockets and other non-mmap-able file descriptors
-     *                       will fail to load in the client application.
-     * @param ttcIndex If providing a TTC_INDEX file, the index to point to. Otherwise, 0.
-     * @param fontVariationSettings If providing a variation font, the settings for it. May be null.
-     * @param weight An integer that indicates the font weight.
-     * @param italic A boolean that indicates the font is italic style or not.
-     */
-    public FontResult(@NonNull ParcelFileDescriptor fileDescriptor, int ttcIndex,
-            @Nullable String fontVariationSettings, int weight, boolean italic) {
-        mFileDescriptor = Preconditions.checkNotNull(fileDescriptor);
-        mTtcIndex = ttcIndex;
-        mFontVariationSettings = fontVariationSettings;
-        mWeight = weight;
-        mItalic = italic;
-    }
-
-    public ParcelFileDescriptor getFileDescriptor() {
-        return mFileDescriptor;
-    }
-
-    public int getTtcIndex() {
-        return mTtcIndex;
-    }
-
-    public String getFontVariationSettings() {
-        return mFontVariationSettings;
-    }
-
-    public int getWeight() {
-        return mWeight;
-    }
-
-    public boolean getItalic() {
-        return mItalic;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(mFileDescriptor, flags);
-        dest.writeInt(mTtcIndex);
-        dest.writeString(mFontVariationSettings);
-        dest.writeInt(mWeight);
-        dest.writeBoolean(mItalic);
-    }
-
-    private FontResult(Parcel in) {
-        mFileDescriptor = in.readParcelable(null);
-        mTtcIndex = in.readInt();
-        mFontVariationSettings = in.readString();
-        mWeight = in.readInt();
-        mItalic = in.readBoolean();
-    }
-
-    public static final Parcelable.Creator<FontResult> CREATOR =
-            new Parcelable.Creator<FontResult>() {
-                @Override
-                public FontResult createFromParcel(Parcel in) {
-                    return new FontResult(in);
-                }
-
-                @Override
-                public FontResult[] newArray(int size) {
-                    return new FontResult[size];
-                }
-            };
-}
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 5c64566..ea804d0 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -17,7 +17,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SdkConstant;
 import android.annotation.WorkerThread;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -199,12 +201,14 @@
      * {@link Build.VERSION_CODES#N_MR1} will only receive this broadcast if they register for it
      * at runtime.
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED";
 
     /**
      * Broadcast Action: Indicates the contents of the keychain has changed. Sent when a KeyChain
      * entry is added, modified or removed.
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_KEYCHAIN_CHANGED = "android.security.action.KEYCHAIN_CHANGED";
 
     /**
@@ -216,6 +220,7 @@
      * <li>A CA is added or removed from the trust store</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_TRUST_STORE_CHANGED =
             "android.security.action.TRUST_STORE_CHANGED";
 
@@ -223,6 +228,7 @@
      * Broadcast Action: Indicates that the access permissions for a private key have changed.
      *
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_KEY_ACCESS_CHANGED =
             "android.security.action.KEY_ACCESS_CHANGED";
 
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 00d786a..244d6e5 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -93,6 +93,16 @@
      */
     public static final int FLAG_ENCRYPTED = 1;
 
+    /**
+     * A private flag that's only available to system server to indicate that this key is part of
+     * device encryption flow so it receives special treatment from keystore. For example this key
+     * will not be super encrypted, and it will be stored separately under an unique UID instead
+     * of the caller UID i.e. SYSTEM.
+     *
+     * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
+     */
+    public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3;
+
     // States
     public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
 
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 64b10ab..bab4010 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -351,6 +351,9 @@
             }
         } else if (param instanceof KeyProtection) {
             spec = (KeyProtection) param;
+            if (spec.isCriticalToDeviceEncryption()) {
+                flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
+            }
         } else {
             throw new KeyStoreException(
                     "Unsupported protection parameter class:" + param.getClass().getName()
@@ -719,6 +722,10 @@
         } catch (IllegalArgumentException | IllegalStateException e) {
             throw new KeyStoreException(e);
         }
+        int flags = 0;
+        if (params.isCriticalToDeviceEncryption()) {
+            flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
+        }
 
         Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
         String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias;
@@ -728,7 +735,7 @@
                 KeymasterDefs.KM_KEY_FORMAT_RAW,
                 keyMaterial,
                 mUid,
-                0, // flags
+                flags,
                 new KeyCharacteristics());
         if (errorCode != KeyStore.NO_ERROR) {
             throw new KeyStoreException("Failed to import secret key. Keystore error code: "
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index 2592a97..2eb0663 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -227,6 +227,7 @@
     private final boolean mUserAuthenticationValidWhileOnBody;
     private final boolean mInvalidatedByBiometricEnrollment;
     private final long mBoundToSecureUserId;
+    private final boolean mCriticalToDeviceEncryption;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -242,7 +243,8 @@
             int userAuthenticationValidityDurationSeconds,
             boolean userAuthenticationValidWhileOnBody,
             boolean invalidatedByBiometricEnrollment,
-            long boundToSecureUserId) {
+            long boundToSecureUserId,
+            boolean criticalToDeviceEncryption) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -259,6 +261,7 @@
         mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
         mBoundToSecureUserId = boundToSecureUserId;
+        mCriticalToDeviceEncryption = criticalToDeviceEncryption;
     }
 
     /**
@@ -458,6 +461,16 @@
     }
 
     /**
+     * Return whether this key is critical to the device encryption flow.
+     *
+     * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION
+     * @hide
+     */
+    public boolean isCriticalToDeviceEncryption() {
+        return mCriticalToDeviceEncryption;
+    }
+
+    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -477,6 +490,7 @@
         private boolean mInvalidatedByBiometricEnrollment = true;
 
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
+        private boolean mCriticalToDeviceEncryption = false;
         /**
          * Creates a new instance of the {@code Builder}.
          *
@@ -817,6 +831,20 @@
         }
 
         /**
+         * Set whether this key is critical to the device encryption flow
+         *
+         * This is a special flag only available to system servers to indicate the current key
+         * is part of the device encryption flow.
+         *
+         * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION
+         * @hide
+         */
+        public Builder setCriticalToDeviceEncryption(boolean critical) {
+            mCriticalToDeviceEncryption = critical;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -837,7 +865,8 @@
                     mUserAuthenticationValidityDurationSeconds,
                     mUserAuthenticationValidWhileOnBody,
                     mInvalidatedByBiometricEnrollment,
-                    mBoundToSecureUserId);
+                    mBoundToSecureUserId,
+                    mCriticalToDeviceEncryption);
         }
     }
 }
diff --git a/media/java/android/media/VolumeShaper.java b/media/java/android/media/VolumeShaper.java
index 1dda6a4..8f4721f 100644
--- a/media/java/android/media/VolumeShaper.java
+++ b/media/java/android/media/VolumeShaper.java
@@ -301,7 +301,7 @@
                 .setInterpolatorType(INTERPOLATOR_TYPE_LINEAR)
                 .setCurve(new float[] {0.f, 1.f} /* times */,
                         new float[] {0.f, 1.f} /* volumes */)
-                .setDurationMillis(1000.)
+                .setDuration(1000)
                 .build();
 
         /**
@@ -314,7 +314,7 @@
                 .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
                 .setCurve(new float[] {0.f, 1.f} /* times */,
                         new float[] {0.f, 1.f}  /* volumes */)
-                .setDurationMillis(1000.)
+                .setDuration(1000)
                 .build();
 
         /**
@@ -348,12 +348,12 @@
             SINE_RAMP = new VolumeShaper.Configuration.Builder()
                 .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
                 .setCurve(times, sines)
-                .setDurationMillis(1000.)
+                .setDuration(1000)
                 .build();
             SCURVE_RAMP = new VolumeShaper.Configuration.Builder()
                 .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
                 .setCurve(times, scurve)
-                .setDurationMillis(1000.)
+                .setDuration(1000)
                 .build();
         }
 
@@ -569,8 +569,9 @@
         /**
          * Returns the duration of the volume shape in milliseconds.
          */
-        public double getDurationMillis() {
-            return mDurationMs;
+        public long getDuration() {
+            // casting is safe here as the duration was set as a long in the Builder
+            return (long) mDurationMs;
         }
 
         /**
@@ -700,7 +701,7 @@
          *             .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
          *             .setCurve(new float[] { 0.f, 1.f }, // times
          *                       new float[] { 0.f, 1.f }) // volumes
-         *             .setDurationMillis(1000.)
+         *             .setDuration(1000)
          *             .build();
          * </pre>
          * <p>
@@ -731,7 +732,7 @@
                 mId = configuration.getId();
                 mOptionFlags = configuration.getAllOptionFlags();
                 mInterpolatorType = configuration.getInterpolatorType();
-                mDurationMs = configuration.getDurationMillis();
+                mDurationMs = configuration.getDuration();
                 mTimes = configuration.getTimes().clone();
                 mVolumes = configuration.getVolumes().clone();
             }
@@ -810,12 +811,12 @@
              * @throws IllegalArgumentException if {@code durationMillis}
              *         is not strictly positive.
              */
-            public @NonNull Builder setDurationMillis(double durationMillis) {
-                if (durationMillis <= 0.) {
+            public @NonNull Builder setDuration(long durationMillis) {
+                if (durationMillis <= 0) {
                     throw new IllegalArgumentException(
                             "duration: " + durationMillis + " not positive");
                 }
-                mDurationMs = durationMillis;
+                mDurationMs = (double) durationMillis;
                 return this;
             }
 
@@ -833,7 +834,7 @@
              * time (x) coordinates should be monotonically increasing, from 0.f to 1.f;
              * volume (y) coordinates must be within 0.f to 1.f.
              * <p>
-             * The time scale is set by {@link #setDurationMillis}.
+             * The time scale is set by {@link #setDuration}.
              * <p>
              * @param times an array of float values representing
              *        the time line of the volume curve.
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 71f9ba2..2e8b0ae 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -19,8 +19,10 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SdkConstant;
 import android.annotation.StringDef;
 import android.annotation.SystemApi;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -90,6 +92,7 @@
      * @hide
      */
     @SystemApi
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_CHANNEL_BROWSABLE_REQUESTED =
             "android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED";
 
@@ -105,6 +108,7 @@
      *     integer.</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_REQUEST_CHANNEL_BROWSABLE =
             "android.media.tv.action.REQUEST_CHANNEL_BROWSABLE";
 
@@ -119,6 +123,7 @@
      *     <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the disabled preview program ID.</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED =
             "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
 
@@ -133,6 +138,7 @@
      *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the disabled "watch next" program ID.</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED =
             "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
 
@@ -146,6 +152,7 @@
      *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the ID of the new watch next program.</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT =
             "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
 
@@ -163,6 +170,7 @@
      *         <code>AndroidManifest.xml</code>.</li>
      * </ul>
      */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_INITIALIZE_PROGRAMS =
             "android.media.tv.action.INITIALIZE_PROGRAMS";
 
diff --git a/packages/CompanionDeviceManager/res/layout/buttons.xml b/packages/CompanionDeviceManager/res/layout/buttons.xml
index 350a791..7de0035 100644
--- a/packages/CompanionDeviceManager/res/layout/buttons.xml
+++ b/packages/CompanionDeviceManager/res/layout/buttons.xml
@@ -29,14 +29,14 @@
         android:id="@+id/button_cancel"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/cancel"
+        android:text="@android:string/cancel"
         style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
     />
     <Button
         android:id="@+id/button_pair"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/pair"
+        android:text="@android:string/ok"
         style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
     />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 469c1fb..c4372eb 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -20,15 +20,9 @@
     <string name="app_label">Companion Device Manager</string>
 
     <!-- Title of the device selection dialog. -->
-    <string name="chooser_title">Pair with &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; via Bluetooth?</string>
+    <string name="chooser_title">Link with &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt;</string>
 
     <!-- Title of the device pairing confirmation dialog. -->
-    <string name="confirmation_title">Pair &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; with &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt; via Bluetooth?</string>
-
-    <!-- Label on the pair button in a companion device chooser/confirmation dialog -->
-    <string name="pair">Pair</string>
-
-    <!-- Label on the cancel button in a companion device chooser/confirmation dialog -->
-    <string name="cancel">Cancel</string>
+    <string name="confirmation_title">Link &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; with &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt;</string>
 
 </resources>
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index f3d8983..f54b6fb 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -21,6 +21,8 @@
     android:versionName="1"
     coreApp="true">
 
+    <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
+
     <application android:label="@string/app_name"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true">
@@ -32,6 +34,14 @@
             </intent-filter>
         </service>
 
+        <service android:name=".resolver.LRResolverRankerService"
+                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
+                 android:priority="-1" >
+            <intent-filter>
+                <action android:name="android.service.resolver.ResolverRankerService" />
+            </intent-filter>
+        </service>
+
         <library android:name="android.ext.services"/>
     </application>
 
diff --git a/core/java/com/android/internal/app/LRResolverRankerService.java b/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
similarity index 99%
rename from core/java/com/android/internal/app/LRResolverRankerService.java
rename to packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
index 1cad7c7..9d7a568 100644
--- a/core/java/com/android/internal/app/LRResolverRankerService.java
+++ b/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.app;
+package android.ext.services.resolver;
 
 import android.content.Context;
 import android.content.Intent;
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index e15df14..044392c 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -130,6 +130,12 @@
     <!-- Bluetooth settings. The user-visible string that is used whenever referring to the SAP profile (sharing SIM card). -->
     <string name="bluetooth_profile_sap">SIM Access</string>
 
+    <!-- Bluetooth settings. The user-visible string for the setting controlling whether to use a high-quality codec if the device supports it, along with the name of the codec (eg AAC, LDAC, aptX) -->
+    <string name="bluetooth_profile_a2dp_high_quality">Use high quality audio: <xliff:g id="codec_name">%1$s</xliff:g></string>
+
+    <!-- Bluetooth settings. Similar to bluetooth_profile_a2dp_high_quality, but used when the device supports high quality audio but we don't know which codec that will be used. -->
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec">Use high quality audio</string>
+
     <!-- Bluetooth settings.  Connection options screen.  The summary for the A2DP checkbox preference when A2DP is connected. -->
     <string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
     <!-- Bluetooth settings.  Connection options screen.  The summary for the headset checkbox preference when headset is connected. -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index af247bd..a0eadd0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -17,6 +17,7 @@
 
 import android.annotation.LayoutRes;
 import android.annotation.Nullable;
+import android.app.ActionBar;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -27,7 +28,6 @@
 import android.content.res.TypedArray;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.provider.Settings;
 import android.util.ArraySet;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -117,14 +117,6 @@
         super.onPause();
     }
 
-    /**
-     * Gets the name of the intent action of the default setting app. Used to launch setting app
-     * when Settings Home is clicked.
-     */
-    public String getSettingAction() {
-        return Settings.ACTION_SETTINGS;
-    }
-
     public void addCategoryListener(CategoryListener listener) {
         mCategoryListeners.add(listener);
     }
@@ -142,7 +134,7 @@
 
     @Override
     public void setContentView(@LayoutRes int layoutResID) {
-        final ViewGroup parent = (ViewGroup) findViewById(R.id.content_frame);
+        final ViewGroup parent = findViewById(R.id.content_frame);
         if (parent != null) {
             parent.removeAllViews();
         }
@@ -159,11 +151,14 @@
         ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params);
     }
 
-    public void showMenuIcon() {
-        getActionBar().setDisplayHomeAsUpEnabled(true);
+    private void showMenuIcon() {
+        final ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
     }
 
-    protected void onCategoriesChanged() {
+    private void onCategoriesChanged() {
         final int N = mCategoryListeners.size();
         for (int i = 0; i < N; i++) {
             mCategoryListeners.get(i).onCategoriesChanged();
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
index 752b5b0..003f905 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
@@ -16,7 +16,12 @@
 
 package com.android.settingslib.drawer;
 
-import android.app.Activity;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
+
 import android.app.Instrumentation;
 import android.content.Intent;
 import android.support.test.InstrumentationRegistry;
@@ -24,23 +29,12 @@
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.settingslib.R;
-
-import com.google.common.truth.Truth;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
 
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SettingsDrawerActivityTest {
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index a8629f8..e9dadc5 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -94,49 +94,9 @@
     <!-- Default for Settings.Secure.SYNC_PARENT_SOUNDS -->
     <bool name="def_sync_parent_sounds">true</bool>
 
-    <!-- Default for Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION -->
-    <bool name="def_accessibility_script_injection">false</bool>
-
     <!-- Default for Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD -->
     <bool name="def_accessibility_speak_password">true</bool>
 
-    <!-- Default for Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS -->
-    <string name="def_accessibility_web_content_key_bindings" translatable="false">
-            <!-- DPAD/Trackball UP - traverse previous on current axis and send an event. -->
-            0x13=0x01000100;
-            <!-- DPAD/Trackball DOWN - traverse next on current axis and send an event. -->
-            0x14=0x01010100;
-            <!-- DPAD/Trackball LEFT - traverse previous on the character navigation axis and send event. -->
-            0x15=0x02000001;
-            <!-- DPAD/Trackball RIGHT - traverse next on the character navigation axis end send event. -->
-            0x16=0x02010001;
-            <!-- Alt+DPAD/Trackball UP - go to the top of the document. -->
-            0x200000013=0x02000601;
-            <!-- Alt+DPAD/Trackball DOWN - go to the bottom of the document. -->
-            0x200000014=0x02010601;
-            <!-- Alt+DPAD/Trackball LEFT - transition from an axis to another and sends an event.-->
-            <!-- Axis transitions: 2 -> 1; -->
-            0x200000015=0x03020101;
-            <!-- Alt+DPAD/Trackball RIGHT - transition from an axis to another and sends an event. -->
-            <!-- Axis transitions:  1 -> 2; -->
-            0x200000016=0x03010201;
-            <!-- Alt+g - go to the previous heading and send an event. -->
-            0x200000023=0x02000301;
-            <!-- Alt+h - go to the next heading and send an event. -->
-            0x200000024=0x02010301;
-            <!-- Alt+COMMA - transition to sentence navigation axis and send an event. -->
-            <!-- Axis transitions:  7 -> 2; -->
-            0x200000037=0x03070201;
-            <!-- Alt+PERIOD - transition to default web view behavior axis and send an event. -->
-            <!-- Axis transitions:  0 -> 7; 1 - > 7; 2 -> 7; -->
-            0x200000038=0x03000701:0x03010701:0x03020701;
-    </string>
-
-    <!-- Default for Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION_URL -->
-    <string name="def_accessibility_screen_reader_url" translatable="false">
-        https://ssl.gstatic.com/accessibility/javascript/android/AndroidVox_v1.js
-    </string>
-
     <!-- Default for Settings.Secure.TOUCH_EXPLORATION_ENABLED -->
     <bool name="def_touch_exploration_enabled">false</bool>
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index a645a56..b777d41 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -820,27 +820,8 @@
 
         if (upgradeVersion == 57) {
             /*
-             * New settings to:
-             *  1. Enable injection of accessibility scripts in WebViews.
-             *  2. Define the key bindings for traversing web content in WebViews.
+             * No longer initializing deleted setting ACCESSIBILITY_SCRIPT_INJECTION.
              */
-            db.beginTransaction();
-            SQLiteStatement stmt = null;
-            try {
-                stmt = db.compileStatement("INSERT INTO secure(name,value)"
-                        + " VALUES(?,?);");
-                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
-                        R.bool.def_accessibility_script_injection);
-                stmt.close();
-                stmt = db.compileStatement("INSERT INTO secure(name,value)"
-                        + " VALUES(?,?);");
-                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
-                        R.string.def_accessibility_web_content_key_bindings);
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
-                if (stmt != null) stmt.close();
-            }
             upgradeVersion = 58;
         }
 
@@ -1085,18 +1066,7 @@
         }
 
         if (upgradeVersion == 74) {
-            // URL from which WebView loads a JavaScript based screen-reader.
-            db.beginTransaction();
-            SQLiteStatement stmt = null;
-            try {
-                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
-                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
-                        R.string.def_accessibility_screen_reader_url);
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
-                if (stmt != null) stmt.close();
-            }
+            // No longer using URL from which WebView loads a JavaScript based screen-reader.
             upgradeVersion = 75;
         }
         if (upgradeVersion == 75) {
@@ -1147,19 +1117,7 @@
         }
 
         if (upgradeVersion == 78) {
-            // The JavaScript based screen-reader URL changes in JellyBean.
-            db.beginTransaction();
-            SQLiteStatement stmt = null;
-            try {
-                stmt = db.compileStatement("INSERT OR REPLACE INTO secure(name,value)"
-                        + " VALUES(?,?);");
-                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
-                        R.string.def_accessibility_screen_reader_url);
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
-                if (stmt != null) stmt.close();
-            }
+            // ACCESSIBILITY_SCREEN_READER_URL has been removed
             upgradeVersion = 79;
         }
 
@@ -2443,12 +2401,6 @@
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                     R.bool.def_mount_ums_notify_enabled);
 
-            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
-                    R.bool.def_accessibility_script_injection);
-
-            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
-                    R.string.def_accessibility_web_content_key_bindings);
-
             loadIntegerSetting(stmt, Settings.Secure.LONG_PRESS_TIMEOUT,
                     R.integer.def_long_press_timeout_millis);
 
@@ -2458,9 +2410,6 @@
             loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
                     R.bool.def_accessibility_speak_password);
 
-            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
-                    R.string.def_accessibility_screen_reader_url);
-
             if (SystemProperties.getBoolean("ro.lockscreen.disable.default", false) == true) {
                 loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1");
             } else {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 1c51773..d1d59b2 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -238,7 +238,6 @@
         // these features working after the restore.
         switch (name) {
             case Settings.Secure.ACCESSIBILITY_ENABLED:
-            case Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION:
             case Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD:
             case Settings.Secure.TOUCH_EXPLORATION_ENABLED:
             case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index bac694f..885573e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1057,15 +1057,6 @@
                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
                 SecureSettingsProto.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
         dumpSetting(s, p,
-                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
-                SecureSettingsProto.ACCESSIBILITY_SCRIPT_INJECTION);
-        dumpSetting(s, p,
-                Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
-                SecureSettingsProto.ACCESSIBILITY_SCREEN_READER_URL);
-        dumpSetting(s, p,
-                Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
-                SecureSettingsProto.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS);
-        dumpSetting(s, p,
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                 SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
         dumpSetting(s, p,
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 55f32d7..bf39bc4 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -22,9 +22,6 @@
         android:sharedUserId="android.uid.systemui"
         coreApp="true">
 
-    <protected-broadcast android:name="com.android.systemui.action.PLUGIN_CHANGED" />
-
-
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
index a8daed5..f663315 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -155,10 +155,6 @@
                 new ComponentName(info.mPackage, info.mClass),
                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                 PackageManager.DONT_KILL_APP);
-        final String pkg = info.mPackage;
-        final Intent intent = new Intent(PluginManager.PLUGIN_CHANGED,
-                pkg != null ? Uri.fromParts("package", pkg, null) : null);
-        mContext.sendBroadcast(intent);
     }
 
     public <T> boolean dependsOn(Plugin p, Class<T> cls) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 143d934..7bc591f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -192,8 +192,9 @@
                         // and the old last stack active time, they were not visible and in the
                         // TaskStack so we don't need to remove any associated TaskViews but we do
                         // need to load the task id's from the system
-                        RecentsTaskLoadPlan loadPlan = Recents.getTaskLoader().createLoadPlan(ctx);
-                        loadPlan.preloadRawTasks(false /* includeFrontMostExcludedTask */);
+                        RecentsTaskLoader loader = Recents.getTaskLoader();
+                        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(ctx);
+                        loader.preloadRawTasks(loadPlan, false /* includeFrontMostExcludedTask */);
                         List<ActivityManager.RecentTaskInfo> tasks = loadPlan.getRawTasks();
                         for (int i = tasks.size() - 1; i >= 0; i--) {
                             ActivityManager.RecentTaskInfo task = tasks.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 164138e..53a9eae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -108,36 +108,39 @@
      * task stacks and update recents accordingly.
      */
     class TaskStackListenerImpl extends TaskStackListener {
+
         @Override
-        public void onTaskStackChanged() {
+        public void onTaskStackChangedBackground() {
             // Preloads the next task
             RecentsConfiguration config = Recents.getConfiguration();
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
-                RecentsTaskLoader loader = Recents.getTaskLoader();
-                SystemServicesProxy ssp = Recents.getSystemServices();
-                ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
 
                 // Load the next task only if we aren't svelte
+                SystemServicesProxy ssp = Recents.getSystemServices();
+                ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
+                RecentsTaskLoader loader = Recents.getTaskLoader();
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
                 loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
-                RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+
                 // This callback is made when a new activity is launched and the old one is paused
                 // so ignore the current activity and try and preload the thumbnail for the
                 // previous one.
-                if (runningTaskInfo != null) {
-                    launchOpts.runningTaskId = runningTaskInfo.id;
+                VisibilityReport visibilityReport;
+                synchronized (mDummyStackView) {
+                    mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */);
+                    updateDummyStackViewLayout(plan.getTaskStack(),
+                            getWindowRect(null /* windowRectOverride */));
+
+                    // Launched from app is always the worst case (in terms of how many
+                    // thumbnails/tasks visible)
+                    RecentsActivityLaunchState launchState = new RecentsActivityLaunchState();
+                    launchState.launchedFromApp = true;
+                    mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */, launchState);
+                    visibilityReport = mDummyStackView.computeStackVisibilityReport();
                 }
-                mDummyStackView.setTasks(plan.getTaskStack(), false /* allowNotify */);
-                updateDummyStackViewLayout(plan.getTaskStack(),
-                        getWindowRect(null /* windowRectOverride */));
 
-                // Launched from app is always the worst case (in terms of how many thumbnails/tasks
-                // visible)
-                RecentsActivityLaunchState launchState = new RecentsActivityLaunchState();
-                launchState.launchedFromApp = true;
-                mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */, launchState);
-
-                VisibilityReport visibilityReport = mDummyStackView.computeStackVisibilityReport();
+                RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+                launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1;
                 launchOpts.numVisibleTasks = visibilityReport.numVisibleTasks;
                 launchOpts.numVisibleTaskThumbnails = visibilityReport.numVisibleThumbnails;
                 launchOpts.onlyLoadForCache = true;
@@ -221,9 +224,10 @@
     }
 
     public void onConfigurationChanged() {
-        Resources res = mContext.getResources();
         reloadResources();
-        mDummyStackView.reloadOnConfigurationChange();
+        synchronized (mDummyStackView) {
+            mDummyStackView.reloadOnConfigurationChange();
+        }
     }
 
     /**
@@ -393,7 +397,6 @@
 
             RecentsTaskLoader loader = Recents.getTaskLoader();
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
-            sInstanceLoadPlan.preloadRawTasks(!isHomeStackVisible.value);
             loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value);
             TaskStack stack = sInstanceLoadPlan.getTaskStack();
             if (stack.getTaskCount() > 0) {
@@ -633,16 +636,18 @@
         calculateWindowStableInsets(systemInsets, windowRect);
         windowRect.offsetTo(0, 0);
 
-        TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
+        synchronized (mDummyStackView) {
+            TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
 
-        // Rebind the header bar and draw it for the transition
-        stackLayout.setSystemInsets(systemInsets);
-        if (stack != null) {
-            stackLayout.getTaskStackBounds(displayRect, windowRect, systemInsets.top,
-                    systemInsets.left, systemInsets.right, mTaskStackBounds);
-            stackLayout.reset();
-            stackLayout.initialize(displayRect, windowRect, mTaskStackBounds,
-                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
+            // Rebind the header bar and draw it for the transition
+            stackLayout.setSystemInsets(systemInsets);
+            if (stack != null) {
+                stackLayout.getTaskStackBounds(displayRect, windowRect, systemInsets.top,
+                        systemInsets.left, systemInsets.right, mTaskStackBounds);
+                stackLayout.reset();
+                stackLayout.initialize(displayRect, windowRect, mTaskStackBounds,
+                        TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
+            }
         }
     }
 
@@ -663,47 +668,52 @@
      */
     private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) {
         Rect windowRect = getWindowRect(windowRectOverride);
-        updateDummyStackViewLayout(stack, windowRect);
-        if (stack != null) {
-            TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
-            mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
-            // Get the width of a task view so that we know how wide to draw the header bar.
-            int taskViewWidth = 0;
-            if (mDummyStackView.useGridLayout()) {
-                TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm();
-                gridLayout.initialize(windowRect);
-                taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */,
-                        stack.getTaskCount(), new TaskViewTransform(), stackLayout).rect.width();
-            } else {
-                Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
-                if (!taskViewBounds.isEmpty()) {
-                    taskViewWidth = taskViewBounds.width();
+        int taskViewWidth = 0;
+        boolean useGridLayout = false;
+        synchronized (mDummyStackView) {
+            useGridLayout = mDummyStackView.useGridLayout();
+            updateDummyStackViewLayout(stack, windowRect);
+            if (stack != null) {
+                TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
+                mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
+                // Get the width of a task view so that we know how wide to draw the header bar.
+                if (useGridLayout) {
+                    TaskGridLayoutAlgorithm gridLayout = mDummyStackView.getGridAlgorithm();
+                    gridLayout.initialize(windowRect);
+                    taskViewWidth = (int) gridLayout.getTransform(0 /* taskIndex */,
+                            stack.getTaskCount(), new TaskViewTransform(),
+                            stackLayout).rect.width();
+                } else {
+                    Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
+                    if (!taskViewBounds.isEmpty()) {
+                        taskViewWidth = taskViewBounds.width();
+                    }
                 }
             }
+        }
 
-            if (taskViewWidth > 0) {
-                synchronized (mHeaderBarLock) {
-                    if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
-                            mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
-                        if (mDummyStackView.useGridLayout()) {
-                            mHeaderBar.setShouldDarkenBackgroundColor(true);
-                            mHeaderBar.setNoUserInteractionState();
-                        }
-                        mHeaderBar.forceLayout();
-                        mHeaderBar.measure(
-                                MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
-                                MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
+        if (stack != null && taskViewWidth > 0) {
+            synchronized (mHeaderBarLock) {
+                if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
+                        mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
+                    if (useGridLayout) {
+                        mHeaderBar.setShouldDarkenBackgroundColor(true);
+                        mHeaderBar.setNoUserInteractionState();
                     }
-                    mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
+                    mHeaderBar.forceLayout();
+                    mHeaderBar.measure(
+                            MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
+                            MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
                 }
+                mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
+            }
 
-                // Update the transition bitmap to match the new header bar height
-                if (mThumbTransitionBitmapCache == null ||
-                        (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
-                        (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
-                    mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
-                            mTaskBarHeight, Bitmap.Config.ARGB_8888);
-                }
+            // Update the transition bitmap to match the new header bar height
+            if (mThumbTransitionBitmapCache == null ||
+                    (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
+                    (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
+                mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
+                        mTaskBarHeight, Bitmap.Config.ARGB_8888);
             }
         }
     }
@@ -764,16 +774,21 @@
      * Creates the activity options for an app->recents transition.
      */
     private ActivityOptions getThumbnailTransitionActivityOptions(
-            ActivityManager.RunningTaskInfo runningTask, TaskStackView stackView,
-                    Rect windowOverrideRect) {
+            ActivityManager.RunningTaskInfo runningTask, Rect windowOverrideRect) {
         if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
             ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
-            ArrayList<Task> tasks = stackView.getStack().getStackTasks();
-            TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
-            TaskStackViewScroller stackScroller = stackView.getScroller();
+            ArrayList<Task> tasks;
+            TaskStackLayoutAlgorithm stackLayout;
+            TaskStackViewScroller stackScroller;
 
-            stackView.updateLayoutAlgorithm(true /* boundScroll */);
-            stackView.updateToInitialState();
+            synchronized (mDummyStackView) {
+                tasks = mDummyStackView.getStack().getStackTasks();
+                stackLayout = mDummyStackView.getStackAlgorithm();
+                stackScroller = mDummyStackView.getScroller();
+
+                mDummyStackView.updateLayoutAlgorithm(true /* boundScroll */);
+                mDummyStackView.updateToInitialState();
+            }
 
             for (int i = tasks.size() - 1; i >= 0; i--) {
                 Task task = tasks.get(i);
@@ -795,7 +810,7 @@
         } else {
             // Update the destination rect
             Task toTask = new Task();
-            TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask,
+            TaskViewTransform toTransform = getThumbnailTransitionTransform(mDummyStackView, toTask,
                     windowOverrideRect);
             Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
                             mThumbTransitionBitmapCache);
@@ -919,8 +934,10 @@
         updateHeaderBarLayout(stack, windowOverrideRect);
 
         // Prepare the dummy stack for the transition
-        TaskStackLayoutAlgorithm.VisibilityReport stackVr =
-                mDummyStackView.computeStackVisibilityReport();
+        TaskStackLayoutAlgorithm.VisibilityReport stackVr;
+        synchronized (mDummyStackView) {
+            stackVr = mDummyStackView.computeStackVisibilityReport();
+        }
 
         // Update the remaining launch state
         launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
@@ -936,8 +953,7 @@
             opts = getUnknownTransitionActivityOptions();
         } else if (useThumbnailTransition) {
             // Try starting with a thumbnail transition
-            opts = getThumbnailTransitionActivityOptions(runningTask, mDummyStackView,
-                    windowOverrideRect);
+            opts = getThumbnailTransitionActivityOptions(runningTask, windowOverrideRect);
         } else {
             // If there is no thumbnail transition, but is launching from home into recents, then
             // use a quick home transition
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 2f12282..a9e1f61 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -61,6 +61,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -149,6 +150,10 @@
      * to reduce IPC calls from system services. These callbacks will be called on the main thread.
      */
     public abstract static class TaskStackListener {
+        /**
+         * NOTE: This call is made of the thread that the binder call comes in on.
+         */
+        public void onTaskStackChangedBackground() { }
         public void onTaskStackChanged() { }
         public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
         public void onActivityPinned(String packageName) { }
@@ -187,8 +192,20 @@
      * This simply passes callbacks to listeners through {@link H}.
      * */
     private android.app.TaskStackListener mTaskStackListener = new android.app.TaskStackListener() {
+
+        private final List<SystemServicesProxy.TaskStackListener> mTmpListeners = new ArrayList<>();
+
         @Override
         public void onTaskStackChanged() throws RemoteException {
+            // Call the task changed callback for the non-ui thread listeners first
+            synchronized (mTaskStackListeners) {
+                mTmpListeners.clear();
+                mTmpListeners.addAll(mTaskStackListeners);
+            }
+            for (int i = mTmpListeners.size() - 1; i >= 0; i--) {
+                mTmpListeners.get(i).onTaskStackChangedBackground();
+            }
+
             mHandler.removeMessages(H.ON_TASK_STACK_CHANGED);
             mHandler.sendEmptyMessage(H.ON_TASK_STACK_CHANGED);
         }
@@ -309,10 +326,7 @@
      * Returns the single instance of the {@link SystemServicesProxy}.
      * This should only be called on the main thread.
      */
-    public static SystemServicesProxy getInstance(Context context) {
-        if (!Looper.getMainLooper().isCurrentThread()) {
-            throw new RuntimeException("Must be called on the UI thread");
-        }
+    public static synchronized SystemServicesProxy getInstance(Context context) {
         if (sSystemServicesProxy == null) {
             sSystemServicesProxy = new SystemServicesProxy(context);
         }
@@ -1136,13 +1150,15 @@
     public void registerTaskStackListener(TaskStackListener listener) {
         if (mIam == null) return;
 
-        mTaskStackListeners.add(listener);
-        if (mTaskStackListeners.size() == 1) {
-            // Register mTaskStackListener to IActivityManager only once if needed.
-            try {
-                mIam.registerTaskStackListener(mTaskStackListener);
-            } catch (Exception e) {
-                Log.w(TAG, "Failed to call registerTaskStackListener", e);
+        synchronized (mTaskStackListeners) {
+            mTaskStackListeners.add(listener);
+            if (mTaskStackListeners.size() == 1) {
+                // Register mTaskStackListener to IActivityManager only once if needed.
+                try {
+                    mIam.registerTaskStackListener(mTaskStackListener);
+                } catch (Exception e) {
+                    Log.w(TAG, "Failed to call registerTaskStackListener", e);
+                }
             }
         }
     }
@@ -1245,74 +1261,80 @@
 
         @Override
         public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case ON_TASK_STACK_CHANGED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onTaskStackChanged();
+            synchronized (mTaskStackListeners) {
+                switch (msg.what) {
+                    case ON_TASK_STACK_CHANGED: {
+                    Trace.beginSection("onTaskStackChanged");
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskStackChanged();
+                        }
+                    Trace.endSection();
+                        break;
                     }
-                    break;
-                }
-                case ON_TASK_SNAPSHOT_CHANGED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
-                                (TaskSnapshot) msg.obj);
+                    case ON_TASK_SNAPSHOT_CHANGED: {
+                    Trace.beginSection("onTaskSnapshotChanged");
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskSnapshotChanged(msg.arg1,
+                                    (TaskSnapshot) msg.obj);
+                        }
+                    Trace.endSection();
+                        break;
                     }
-                    break;
-                }
-                case ON_ACTIVITY_PINNED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onActivityPinned((String) msg.obj);
+                    case ON_ACTIVITY_PINNED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityPinned((String) msg.obj);
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_ACTIVITY_UNPINNED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onActivityUnpinned();
+                    case ON_ACTIVITY_UNPINNED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityUnpinned();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onPinnedActivityRestartAttempt();
+                    case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedActivityRestartAttempt();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_PINNED_STACK_ANIMATION_STARTED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onPinnedStackAnimationStarted();
+                    case ON_PINNED_STACK_ANIMATION_STARTED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedStackAnimationStarted();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_PINNED_STACK_ANIMATION_ENDED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
+                    case ON_PINNED_STACK_ANIMATION_ENDED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onPinnedStackAnimationEnded();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_ACTIVITY_FORCED_RESIZABLE: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onActivityForcedResizable(
-                                (String) msg.obj, msg.arg1, msg.arg2);
+                    case ON_ACTIVITY_FORCED_RESIZABLE: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityForcedResizable(
+                                    (String) msg.obj, msg.arg1, msg.arg2);
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onActivityDismissingDockedStack();
+                    case ON_ACTIVITY_DISMISSING_DOCKED_STACK: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityDismissingDockedStack();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onActivityLaunchOnSecondaryDisplayFailed();
+                    case ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onActivityLaunchOnSecondaryDisplayFailed();
+                        }
+                        break;
                     }
-                    break;
-                }
-                case ON_TASK_PROFILE_LOCKED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
+                    case ON_TASK_PROFILE_LOCKED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
+                        }
+                        break;
                     }
-                    break;
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 78c71a1..4b53cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -103,8 +103,10 @@
     /**
      * An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent
      * to most-recent order.
+     *
+     * Note: Do not lock, callers should synchronize on the loader before making this call.
      */
-    public synchronized void preloadRawTasks(boolean includeFrontMostExcludedTask) {
+    void preloadRawTasks(boolean includeFrontMostExcludedTask) {
         int currentUserId = UserHandle.USER_CURRENT;
         updateCurrentQuietProfilesCache(currentUserId);
         SystemServicesProxy ssp = Recents.getSystemServices();
@@ -123,8 +125,11 @@
      * The tasks will be ordered by:
      * - least-recent to most-recent stack tasks
      * - least-recent to most-recent freeform tasks
+     *
+     * Note: Do not lock, since this can be calling back to the loader, which separately also drives
+     * this call (callers should synchronize on the loader before making this call).
      */
-    public synchronized void preloadPlan(RecentsTaskLoader loader, int runningTaskId,
+    void preloadPlan(RecentsTaskLoader loader, int runningTaskId,
             boolean includeFrontMostExcludedTask) {
         Resources res = mContext.getResources();
         ArrayList<Task> allTasks = new ArrayList<>();
@@ -223,8 +228,11 @@
 
     /**
      * Called to apply the actual loading based on the specified conditions.
+     *
+     * Note: Do not lock, since this can be calling back to the loader, which separately also drives
+     * this call (callers should synchronize on the loader before making this call).
      */
-    public synchronized void executePlan(Options opts, RecentsTaskLoader loader) {
+    void executePlan(Options opts, RecentsTaskLoader loader) {
         Resources res = mContext.getResources();
 
         // Iterate through each of the tasks and load them according to the load conditions.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 5e78b61..0b4498c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -31,6 +31,7 @@
 import android.util.Log;
 import android.util.LruCache;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsConfiguration;
@@ -243,7 +244,9 @@
     private final TaskResourceLoadQueue mLoadQueue;
     private final BackgroundTaskLoader mLoader;
     private final HighResThumbnailLoader mHighResThumbnailLoader;
+    @GuardedBy("this")
     private final TaskKeyStrongCache<ThumbnailData> mThumbnailCache = new TaskKeyStrongCache<>();
+    @GuardedBy("this")
     private final TaskKeyStrongCache<ThumbnailData> mTempCache = new TaskKeyStrongCache<>();
     private final int mMaxThumbnailCacheSize;
     private final int mMaxIconCacheSize;
@@ -318,14 +321,20 @@
         return plan;
     }
 
+    /** Preloads raw recents tasks using the specified plan to store the output. */
+    public synchronized void preloadRawTasks(RecentsTaskLoadPlan plan,
+            boolean includeFrontMostExcludedTask) {
+        plan.preloadRawTasks(includeFrontMostExcludedTask);
+    }
+
     /** Preloads recents tasks using the specified plan to store the output. */
-    public void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
+    public synchronized void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
             boolean includeFrontMostExcludedTask) {
         plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask);
     }
 
     /** Begins loading the heavy task data according to the specified options. */
-    public void loadTasks(Context context, RecentsTaskLoadPlan plan,
+    public synchronized void loadTasks(Context context, RecentsTaskLoadPlan plan,
             RecentsTaskLoadPlan.Options opts) {
         if (opts == null) {
             throw new RuntimeException("Requires load options");
@@ -380,8 +389,7 @@
      * Handles signals from the system, trimming memory when requested to prevent us from running
      * out of memory.
      */
-    public void onTrimMemory(int level) {
-        RecentsConfiguration config = Recents.getConfiguration();
+    public synchronized void onTrimMemory(int level) {
         switch (level) {
             case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                 // Stop the loader immediately when the UI is no longer visible
@@ -516,7 +524,7 @@
     /**
      * Returns the cached thumbnail if the task key is not expired, updating the cache if it is.
      */
-    ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached,
+    synchronized ThumbnailData getAndUpdateThumbnail(Task.TaskKey taskKey, boolean loadIfNotCached,
             boolean storeInCache) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
@@ -616,12 +624,15 @@
         }
     }
 
-    public void dump(String prefix, PrintWriter writer) {
+    public synchronized void dump(String prefix, PrintWriter writer) {
         String innerPrefix = prefix + "  ";
 
         writer.print(prefix); writer.println(TAG);
         writer.print(prefix); writer.println("Icon Cache");
         mIconCache.dump(innerPrefix, writer);
+        writer.print(prefix); writer.println("Thumbnail Cache");
         mThumbnailCache.dump(innerPrefix, writer);
+        writer.print(prefix); writer.println("Temp Thumbnail Cache");
+        mTempCache.dump(innerPrefix, writer);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 32e3df6..18a9bab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -1711,6 +1711,13 @@
         }
     }
 
+    private void clearPrefetchingTask() {
+        if (mPrefetchingTask != null) {
+            Recents.getTaskLoader().unloadTaskData(mPrefetchingTask);
+        }
+        mPrefetchingTask = null;
+    }
+
     /**** TaskViewCallbacks Implementation ****/
 
     @Override
@@ -2201,6 +2208,13 @@
         if (!event.visible && mTaskViewFocusFrame != null) {
             mTaskViewFocusFrame.moveGridTaskViewFocus(null);
         }
+        if (!event.visible) {
+            List<TaskView> taskViews = new ArrayList<>(getTaskViews());
+            for (int i = 0; i < taskViews.size(); i++) {
+                mViewPool.returnViewToPool(taskViews.get(i));
+            }
+            clearPrefetchingTask();
+        }
     }
 
     public void reloadOnConfigurationChange() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 4dec6c7..2cf06c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -262,17 +262,15 @@
 
     private boolean hasImportanceChanged() {
         return mSingleNotificationChannel != null &&
+                mChannelEnabledSwitch != null &&
                 mStartingUserImportance != getSelectedImportance();
     }
 
     private void saveImportance() {
-        if (mSingleNotificationChannel == null) {
+        if (!hasImportanceChanged()) {
             return;
         }
-        int selectedImportance = getSelectedImportance();
-        if (selectedImportance == mStartingUserImportance) {
-            return;
-        }
+        final int selectedImportance = getSelectedImportance();
         MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
                 selectedImportance - mStartingUserImportance);
         mSingleNotificationChannel.setImportance(selectedImportance);
@@ -386,7 +384,7 @@
 
     @Override
     public boolean willBeRemoved() {
-        return !mChannelEnabledSwitch.isChecked();
+        return mChannelEnabledSwitch != null && !mChannelEnabledSwitch.isChecked();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
index dfa5cbd..6a573f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
@@ -19,7 +19,7 @@
 import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
 
 /**
- * For mocking because AccessibilyManager is final for some reason...
+ * For mocking because AccessibilityManager is final for some reason...
  */
 public class AccessibilityManagerWrapper implements
         CallbackController<AccessibilityServicesStateChangeListener> {
@@ -32,7 +32,7 @@
 
     @Override
     public void addCallback(AccessibilityServicesStateChangeListener listener) {
-        mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener);
+        mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener, null);
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 907928f..2b14b31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -778,4 +778,9 @@
         enabledSwitch.setChecked(true);
         assertEquals(View.VISIBLE, settingsLink.getVisibility());
     }
+
+    @Test
+    public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception {
+        assertFalse(mNotificationInfo.willBeRemoved());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 8808988..f516d74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -20,7 +20,9 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothProfile;
+import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
 
 import com.android.settingslib.bluetooth.BluetoothEventManager;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -31,10 +33,13 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 public class BluetoothControllerImplTest extends SysuiTestCase {
 
     private LocalBluetoothManager mMockBluetoothManager;
@@ -47,7 +52,7 @@
 
     @Before
     public void setup() throws Exception {
-        mTestableLooper = new TestableLooper();
+        mTestableLooper = TestableLooper.get(this);
         mMockBluetoothManager = mDependency.injectMockDependency(LocalBluetoothManager.class);
         mDevices = new ArrayList<>();
         mMockDeviceManager = mock(CachedBluetoothDeviceManager.class);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0003941..b6dfdd1 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -775,7 +775,6 @@
             if ((flags & UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0) {
                 // Set the temporary state, and use it instead of settings
                 userState.mIsTouchExplorationEnabled = false;
-                userState.mIsEnhancedWebAccessibilityEnabled = false;
                 userState.mIsDisplayMagnificationEnabled = false;
                 userState.mIsNavBarMagnificationEnabled = false;
                 userState.mIsAutoclickEnabled = false;
@@ -826,7 +825,6 @@
             }
 
             userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
-            userState.mIsEnhancedWebAccessibilityEnabled = false;
             userState.mIsDisplayMagnificationEnabled = false;
             userState.mIsNavBarMagnificationEnabled = false;
             userState.mIsAutoclickEnabled = false;
@@ -1727,7 +1725,6 @@
         updateFilterKeyEventsLocked(userState);
         updateTouchExplorationLocked(userState);
         updatePerformGesturesLocked(userState);
-        updateEnhancedWebAccessibilityLocked(userState);
         updateDisplayDaltonizerLocked(userState);
         updateDisplayInversionLocked(userState);
         updateMagnificationLocked(userState);
@@ -1846,7 +1843,6 @@
         somethingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
         somethingChanged |= readTouchExplorationEnabledSettingLocked(userState);
         somethingChanged |= readHighTextContrastEnabledSettingLocked(userState);
-        somethingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
         somethingChanged |= readMagnificationEnabledSettingsLocked(userState);
         somethingChanged |= readAutoclickEnabledSettingLocked(userState);
         somethingChanged |= readAccessibilityShortcutSettingLocked(userState);
@@ -1907,17 +1903,6 @@
         return false;
     }
 
-    private boolean readEnhancedWebAccessibilityEnabledChangedLocked(UserState userState) {
-         final boolean enhancedWeAccessibilityEnabled = Settings.Secure.getIntForUser(
-                mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
-                0, userState.mUserId) == 1;
-         if (enhancedWeAccessibilityEnabled != userState.mIsEnhancedWebAccessibilityEnabled) {
-             userState.mIsEnhancedWebAccessibilityEnabled = enhancedWeAccessibilityEnabled;
-             return true;
-         }
-         return false;
-    }
-
     private boolean readHighTextContrastEnabledSettingLocked(UserState userState) {
         final boolean highTextContrastEnabled = Settings.Secure.getIntForUser(
                 mContext.getContentResolver(),
@@ -2084,40 +2069,6 @@
         return false;
     }
 
-    private void updateEnhancedWebAccessibilityLocked(UserState userState) {
-        boolean enabled = false;
-        final int serviceCount = userState.mBoundServices.size();
-        for (int i = 0; i < serviceCount; i++) {
-            Service service = userState.mBoundServices.get(i);
-            if (canRequestAndRequestsEnhancedWebAccessibilityLocked(service)) {
-                enabled = true;
-                break;
-            }
-        }
-        if (enabled != userState.mIsEnhancedWebAccessibilityEnabled) {
-            userState.mIsEnhancedWebAccessibilityEnabled = enabled;
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0,
-                        userState.mUserId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    private boolean canRequestAndRequestsEnhancedWebAccessibilityLocked(Service service) {
-        if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) {
-            return false;
-        }
-        if (service.mIsAutomation || (service.mAccessibilityServiceInfo.getCapabilities()
-               & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0) {
-            return true;
-        }
-        return false;
-    }
-
     private void updateDisplayDaltonizerLocked(UserState userState) {
         DisplayAdjustmentUtils.applyDaltonizerSetting(mContext, userState.mUserId);
     }
@@ -2697,8 +2648,6 @@
 
         boolean mRequestTouchExplorationMode;
 
-        boolean mRequestEnhancedWebAccessibility;
-
         boolean mRequestFilterKeyEvents;
 
         boolean mRetrieveInteractiveWindows;
@@ -2854,8 +2803,6 @@
 
             mRequestTouchExplorationMode = (info.flags
                     & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
-            mRequestEnhancedWebAccessibility = (info.flags
-                    & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
             mRequestFilterKeyEvents = (info.flags
                     & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
             mRetrieveInteractiveWindows = (info.flags
@@ -4933,7 +4880,6 @@
 
         public boolean mIsTouchExplorationEnabled;
         public boolean mIsTextHighContrastEnabled;
-        public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
         public boolean mIsNavBarMagnificationEnabled;
         public boolean mIsAutoclickEnabled;
@@ -5002,7 +4948,6 @@
             mEnabledServices.clear();
             mTouchExplorationGrantedServices.clear();
             mIsTouchExplorationEnabled = false;
-            mIsEnhancedWebAccessibilityEnabled = false;
             mIsDisplayMagnificationEnabled = false;
             mIsNavBarMagnificationEnabled = false;
             mServiceAssignedToAccessibilityButton = null;
@@ -5051,9 +4996,6 @@
         private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
                 .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
 
-        private final Uri mEnhancedWebAccessibilityUri = Settings.Secure
-                .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION);
-
         private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
 
@@ -5093,8 +5035,6 @@
             contentResolver.registerContentObserver(
                     mTouchExplorationGrantedAccessibilityServicesUri,
                     false, this, UserHandle.USER_ALL);
-            contentResolver.registerContentObserver(mEnhancedWebAccessibilityUri,
-                    false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
                     mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
@@ -5144,10 +5084,6 @@
                     if (readTouchExplorationGrantedAccessibilityServicesLocked(userState)) {
                         onUserStateChangedLocked(userState);
                     }
-                } else if (mEnhancedWebAccessibilityUri.equals(uri)) {
-                    if (readEnhancedWebAccessibilityEnabledChangedLocked(userState)) {
-                        onUserStateChangedLocked(userState);
-                    }
                 } else if (mDisplayDaltonizerEnabledUri.equals(uri)
                         || mDisplayDaltonizerUri.equals(uri)) {
                     updateDisplayDaltonizerLocked(userState);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 1b5b2c6..88adbf4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -73,6 +73,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Entry point service for autofill management.
@@ -81,7 +82,6 @@
  * {@link AutofillManagerServiceImpl} per user; the real work is done by
  * {@link AutofillManagerServiceImpl} itself.
  */
-// TODO(b/33197203): Handle removing of packages
 public final class AutofillManagerService extends SystemService {
 
     private static final String TAG = "AutofillManagerService";
@@ -109,10 +109,8 @@
     @GuardedBy("mLock")
     private final SparseBooleanArray mDisabledUsers = new SparseBooleanArray();
 
-    // TODO(b/33197203): set a different max (or disable it) on low-memory devices.
     private final LocalLog mRequestsHistory = new LocalLog(20);
 
-    // TODO(b/33197203): is this still needed?
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -376,7 +374,6 @@
         public int startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
                 AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
                 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");
@@ -487,6 +484,22 @@
         }
 
         @Override
+        public boolean isServiceSupported(int userId) {
+            synchronized (mLock) {
+                return !mDisabledUsers.get(userId);
+            }
+        }
+
+        @Override
+        public boolean isServiceEnabled(int userId, String packageName) {
+            synchronized (mLock) {
+                final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+                if (service == null) return false;
+                return Objects.equals(packageName, service.getPackageName());
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
             synchronized (mLock) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 85fc580..238cdd5 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -16,9 +16,6 @@
 
 package com.android.server.autofill;
 
-import static android.service.autofill.AutofillService.EXTRA_SESSION_ID;
-import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
-import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
 import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
 import static android.view.autofill.AutofillManager.NO_SESSION;
 
@@ -27,10 +24,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.ActivityManager;
 import android.app.AppGlobals;
-import android.app.assist.AssistStructure;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -50,7 +44,6 @@
 import android.service.autofill.AutofillServiceInfo;
 import android.service.autofill.FillEventHistory;
 import android.service.autofill.FillEventHistory.Event;
-import android.service.autofill.FillRequest;
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.text.TextUtils;
@@ -66,7 +59,6 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.IResultReceiver;
 import com.android.server.autofill.ui.AutoFillUI;
 
 import java.io.PrintWriter;
@@ -120,8 +112,6 @@
      * <p>They're kept until the {@link AutofillService} finished handling a request, an error
      * occurs, or the session times out.
      */
-    // TODO(b/33197203): need to make sure service is bound while callback is pending and/or
-    // use WeakReference
     @GuardedBy("mLock")
     private final SparseArray<Session> mSessions = new SparseArray<>();
 
@@ -129,59 +119,6 @@
     @GuardedBy("mLock")
     private FillEventHistory mEventHistory;
 
-    /**
-     * Receiver of assist data from the app's {@link Activity}.
-     */
-    private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
-        @Override
-        public void send(int resultCode, Bundle resultData) throws RemoteException {
-            if (VERBOSE) {
-                Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
-            }
-
-            final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
-            if (structure == null) {
-                Slog.wtf(TAG, "no assist structure for id " + resultCode);
-                return;
-            }
-
-            final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
-            if (receiverExtras == null) {
-                Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
-                return;
-            }
-
-            final int sessionId = receiverExtras.getInt(EXTRA_SESSION_ID);
-            final Session session;
-            synchronized (mLock) {
-                session = mSessions.get(sessionId);
-                if (session == null) {
-                    Slog.w(TAG, "no server session for " + sessionId);
-                    return;
-                }
-                // TODO(b/33197203): since service is fetching the data (to use for save later),
-                // we should optimize what's sent (for example, remove layout containers,
-                // color / font info, etc...)
-                session.setStructureLocked(structure);
-            }
-
-
-            // TODO(b/33197203, b/33269702): Must fetch the data so it's available later on
-            // handleSave(), even if if the activity is gone by then, but structure.ensureData()
-            // gives a ONE_WAY warning because system_service could block on app calls.
-            // We need to change AssistStructure so it provides a "one-way" writeToParcel()
-            // method that sends all the data
-            structure.ensureData();
-
-            // Sanitize structure before it's sent to service.
-            structure.sanitizeForParceling(true);
-
-            // TODO(b/33197203): Need to pipe the bundle
-            FillRequest request = new FillRequest(structure, null, session.mFlags);
-            session.mRemoteFillService.onFillRequest(request);
-        }
-    };
-
     AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
             int userId, AutoFillUI ui, boolean disabled) {
         mContext = context;
@@ -193,11 +130,10 @@
     }
 
     CharSequence getServiceName() {
-        if (mInfo == null) {
+        final String packageName = getPackageName();
+        if (packageName == null) {
             return null;
         }
-        final ComponentName serviceComponent = mInfo.getServiceInfo().getComponentName();
-        final String packageName = serviceComponent.getPackageName();
 
         try {
             final PackageManager pm = mContext.getPackageManager();
@@ -209,6 +145,14 @@
         }
     }
 
+    String getPackageName() {
+        if (mInfo == null) {
+            return null;
+        }
+        final ComponentName serviceComponent = mInfo.getServiceInfo().getComponentName();
+        return serviceComponent.getPackageName();
+    }
+
     private String getComponentNameFromSettings() {
         return Settings.Secure.getStringForUser(
                 mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
@@ -398,28 +342,6 @@
                 mInfo.getServiceInfo().getComponentName(), packageName);
         mSessions.put(newSession.id, newSession);
 
-        /*
-         * TODO(b/33197203): apply security checks below:
-         * - checks if disabled by secure settings / device policy
-         * - log operation using noteOp()
-         * - check flags
-         * - display disclosure if needed
-         */
-        try {
-            final Bundle receiverExtras = new Bundle();
-            receiverExtras.putInt(EXTRA_SESSION_ID, sessionId);
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
-                        receiverExtras, activityToken)) {
-                    Slog.w(TAG, "failed to request autofill data for " + activityToken);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        } catch (RemoteException e) {
-            // Should not happen, it's a local call.
-        }
         return newSession;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 70e97c4..5964172 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,7 +16,12 @@
 
 package com.android.server.autofill;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
 import android.os.Bundle;
+import android.view.autofill.AutofillId;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -24,7 +29,8 @@
 
 final class Helper {
 
-    static final boolean DEBUG = true; // TODO(b/33197203): set to false when stable
+    // TODO(b/36141126): set to false and remove guard from places that should always be on
+    static final boolean DEBUG = true;
     static final boolean VERBOSE = false;
 
     static void append(StringBuilder builder, Bundle bundle) {
@@ -52,4 +58,37 @@
     private Helper() {
         throw new UnsupportedOperationException("contains static members only");
     }
+
+    static ViewNode findViewNodeById(@NonNull AssistStructure structure, @NonNull AutofillId id) {
+        final int size = structure.getWindowNodeCount();
+        for (int i = 0; i < size; i++) {
+            final AssistStructure.WindowNode window = structure.getWindowNodeAt(i);
+            final ViewNode root = window.getRootViewNode();
+            if (id.equals(root.getAutofillId())) {
+                return root;
+            }
+            final ViewNode child = findViewNodeById(root, id);
+            if (child != null) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    static ViewNode findViewNodeById(@NonNull ViewNode parent, @NonNull AutofillId id) {
+        final int childrenSize = parent.getChildCount();
+        if (childrenSize > 0) {
+            for (int i = 0; i < childrenSize; i++) {
+                final ViewNode child = parent.getChildAt(i);
+                if (id.equals(child.getAutofillId())) {
+                    return child;
+                }
+                final ViewNode grandChild = findViewNodeById(child, id);
+                if (grandChild != null && id.equals(grandChild.getAutofillId())) {
+                    return grandChild;
+                }
+            }
+        }
+        return null;
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 4d0f380..432a092 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -134,6 +134,23 @@
         mCallbacks.onServiceDied(this);
     }
 
+    /**
+     * Cancel the currently pending request.
+     *
+     * <p>This can be used when the request is unnecessary or will be superceeded by a request that
+     * will soon be queued.
+     */
+    public void cancelCurrentRequest() {
+        if (mDestroyed) {
+            return;
+        }
+
+        if (mPendingRequest != null) {
+            mPendingRequest.cancel();
+            mPendingRequest = null;
+        }
+    }
+
     public void onFillRequest(@NonNull FillRequest request) {
         cancelScheduledUnbind();
         final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 4bc3872..a00a397 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -18,6 +18,8 @@
 package com.android.server.autofill;
 
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
+import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
+import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
 import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
 import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
 import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
@@ -25,19 +27,22 @@
 
 import static com.android.server.autofill.Helper.DEBUG;
 import static com.android.server.autofill.Helper.VERBOSE;
+import static com.android.server.autofill.Helper.findViewNodeById;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.AutofillOverlay;
 import android.app.assist.AssistStructure.ViewNode;
-import android.app.assist.AssistStructure.WindowNode;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.graphics.Rect;
 import android.metrics.LogMaker;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcelable;
@@ -64,14 +69,16 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.ArrayUtils;
 import com.android.server.autofill.ui.AutoFillUI;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A session for a given activity.
@@ -85,14 +92,12 @@
  * to fill the activity but it requires authentication first, that response need to be held
  * until the user authenticates or it times out.
  */
-// TODO(b/33197203): make sure sessions are removed (and tested by CTS):
-// - On all authentication scenarios.
-// - When user does not interact back after a while.
-// - When service is unbound.
 final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
         AutoFillUI.AutoFillUiCallback {
     private static final String TAG = "AutofillSession";
 
+    private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
+
     private final AutofillManagerServiceImpl mService;
     private final HandlerCaller mHandlerCaller;
     private final Object mLock;
@@ -100,6 +105,8 @@
 
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
+    private static AtomicInteger sIdCounter = new AtomicInteger();
+
     /** Id of the session */
     public final int id;
 
@@ -127,8 +134,7 @@
     @GuardedBy("mLock")
     private IAutoFillManagerClient mClient;
 
-    @GuardedBy("mLock")
-    RemoteFillService mRemoteFillService;
+    private final RemoteFillService mRemoteFillService;
 
     @GuardedBy("mLock")
     private SparseArray<FillResponse> mResponses;
@@ -167,7 +173,124 @@
     /**
      * Flags used to start the session.
      */
-    int mFlags;
+    private final int mFlags;
+
+    /**
+     * Receiver of assist data from the app's {@link Activity}.
+     */
+    private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
+        @Override
+        public void send(int resultCode, Bundle resultData) throws RemoteException {
+            if (VERBOSE) {
+                Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
+            }
+
+            final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
+            if (structure == null) {
+                Slog.wtf(TAG, "no assist structure for id " + resultCode);
+                return;
+            }
+
+            final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
+            if (receiverExtras == null) {
+                Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
+                return;
+            }
+
+            final int requestId = receiverExtras.getInt(EXTRA_REQUEST_ID);
+
+            if (DEBUG) {
+                Slog.d(TAG, "New structure for requestId " + requestId + ": " + structure);
+            }
+
+            synchronized (mLock) {
+                // TODO(b/35708678): Must fetch the data so it's available later on handleSave(),
+                // even if if the activity is gone by then, but structure .ensureData() gives a
+                // ONE_WAY warning because system_service could block on app calls. We need to
+                // change AssistStructure so it provides a "one-way" writeToParcel() method that
+                // sends all the data
+                structure.ensureData();
+
+                // Sanitize structure before it's sent to service.
+                structure.sanitizeForParceling(true);
+
+                mStructure = structure;
+            }
+
+            fillStructureWithAllowedValues(mStructure);
+
+            FillRequest request = new FillRequest(requestId, mStructure, mClientState, mFlags);
+            mRemoteFillService.onFillRequest(request);
+        }
+    };
+
+    /**
+     * Updates values of the nodes in the structure so that:
+     * - proper node is focused
+     * - autofillValue is sent back to service when it was previously autofilled
+     *
+     * @param structure The structure to be filled
+     */
+    private void fillStructureWithAllowedValues(@NonNull AssistStructure structure) {
+        final int numViewStates = mViewStates.size();
+        for (int i = 0; i < numViewStates; i++) {
+            final ViewState viewState = mViewStates.valueAt(i);
+
+            final ViewNode node = findViewNodeById(structure, viewState.id);
+            if (node == null) {
+                if (DEBUG) {
+                    Slog.w(TAG, "fillStructureWithAllowedValues(): no node for " + viewState.id);
+                }
+                continue;
+            }
+
+            final AutofillValue initialValue = viewState.getInitialValue();
+            final AutofillValue filledValue = viewState.getAutofilledValue();
+            final AutofillOverlay overlay = new AutofillOverlay();
+            if (filledValue != null && !filledValue.equals(initialValue)) {
+                overlay.value = filledValue;
+            }
+            if (mCurrentViewId != null) {
+                overlay.focused = mCurrentViewId.equals(viewState.id);
+            }
+
+            node.setAutofillOverlay(overlay);
+        }
+    }
+
+    /**
+     * Reads a new structure and then request a new fill response from the fill service.
+     */
+    private void requestNewFillResponseLocked() {
+        final int requestId = sIdCounter.getAndIncrement();
+
+        if (DEBUG) {
+            Slog.d(TAG, "Requesting structure for requestId " + requestId);
+        }
+
+        // If the focus changes very quickly before the first request is returned each focus change
+        // triggers a new partition and we end up with many duplicate partitions. This is
+        // enhanced as the focus change can be much faster than the taking of the assist structure.
+        // Hence remove the currently queued request and replace it with the one queued after the
+        // structure is taken. This causes only one fill request per bust of focus changes.
+        mRemoteFillService.cancelCurrentRequest();
+
+        try {
+            final Bundle receiverExtras = new Bundle();
+            receiverExtras.putInt(EXTRA_REQUEST_ID, requestId);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
+                        receiverExtras, mActivityToken)) {
+                    Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        } catch (RemoteException e) {
+            // Should not happen, it's a local call.
+        }
+    }
 
     Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
             @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
@@ -251,7 +374,7 @@
         }
         synchronized (mLock) {
             if (response.getAuthentication() != null) {
-                // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
+                // TODO(b/37424539): proper implementation
                 mResponseWaitingAuth = response;
             }
             processResponseLocked(response, requestId);
@@ -326,7 +449,7 @@
     // FillServiceCallbacks
     @Override
     public void onServiceDied(RemoteFillService service) {
-        // TODO(b/33197203): implement
+        // TODO(b/337565347): implement
     }
 
     // AutoFillUiCallback
@@ -437,10 +560,6 @@
         mHasCallback = hasIt;
     }
 
-    public void setStructureLocked(AssistStructure structure) {
-        mStructure = structure;
-    }
-
     /**
      * Shows the save UI, when session can be saved.
      *
@@ -579,7 +698,7 @@
                 continue;
             }
             final AutofillId id = entry.getKey();
-            final ViewNode node = findViewNodeByIdLocked(id);
+            final ViewNode node = findViewNodeById(mStructure, id);
             if (node == null) {
                 Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
                 continue;
@@ -599,7 +718,7 @@
             mStructure.dump();
         }
 
-        // TODO(b/33197203): Implement partitioning properly
+        // TODO(b/37426206): Implement partitioning properly
         final int lastResponseIdx = getLastResponseIndex();
         final int requestId = mResponses.keyAt(lastResponseIdx);
         final FillContext fillContext = new FillContext(requestId, mStructure);
@@ -610,24 +729,61 @@
         mRemoteFillService.onSaveRequest(saveRequest);
     }
 
+    /**
+     * Determines if a new partition should be started for an id.
+     *
+     * @param id The id of the view that is entered
+     *
+     * @return {@code true} iff a new partition should be started
+     */
+    private boolean shouldStartNewPartitionLocked(@NonNull AutofillId id) {
+        if (mResponses == null) {
+            return true;
+        }
+
+        final int numResponses = mResponses.size();
+        for (int responseNum = 0; responseNum < numResponses; responseNum++) {
+            final FillResponse response = mResponses.valueAt(responseNum);
+
+            if (ArrayUtils.contains(response.getIgnoredIds(), id)) {
+                return false;
+            }
+
+            final SaveInfo saveInfo = response.getSaveInfo();
+            if (saveInfo != null) {
+                if (ArrayUtils.contains(saveInfo.getOptionalIds(), id)
+                        || ArrayUtils.contains(saveInfo.getRequiredIds(), id)) {
+                    return false;
+                }
+            }
+
+            final ArrayList<Dataset> datasets = response.getDatasets();
+            if (datasets != null) {
+                final int numDatasets = datasets.size();
+
+                for (int dataSetNum = 0; dataSetNum < numDatasets; dataSetNum++) {
+                    final ArrayList fields = datasets.get(dataSetNum).getFieldIds();
+
+                    if (fields != null && fields.contains(id)) {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
     void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
         ViewState viewState = mViewStates.get(id);
 
         if (viewState == null) {
-            if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED)) != 0) {
+            if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED | FLAG_VIEW_ENTERED)) != 0) {
                 if (DEBUG) {
                     Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
                 }
                 viewState = new ViewState(this, id, value, this, ViewState.STATE_INITIAL);
                 mViewStates.put(id, viewState);
-            } else if (mStructure != null && (flags & FLAG_VIEW_ENTERED) != 0) {
-                if (isIgnoredLocked(id)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Not starting partition for ignored view id " + id);
-                    }
-                    return;
-                }
-                viewState = startPartitionLocked(id, value);
             } else {
                 if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
                 return;
@@ -639,6 +795,7 @@
             mCurrentViewId = viewState.id;
             viewState.update(value, virtualBounds);
             viewState.setState(ViewState.STATE_STARTED_SESSION);
+            requestNewFillResponseLocked();
             return;
         }
 
@@ -668,6 +825,19 @@
         }
 
         if ((flags & FLAG_VIEW_ENTERED) != 0) {
+            if (shouldStartNewPartitionLocked(id)) {
+                // TODO(b/37424539): proper implementation
+                if (mResponseWaitingAuth != null && ((flags & FLAG_START_SESSION) == 0)) {
+                    viewState.setState(ViewState.STATE_WAITING_RESPONSE_AUTH);
+                } else if ((flags & FLAG_START_SESSION) == 0){
+                    if (DEBUG) {
+                        Slog.d(TAG, "Starting partition for view id " + viewState.id);
+                    }
+                    viewState.setState(ViewState.STATE_STARTED_PARTITION);
+                    requestNewFillResponseLocked();
+                }
+            }
+
             // Remove the UI if the ViewState has changed.
             if (mCurrentViewId != viewState.id) {
                 mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
@@ -691,49 +861,6 @@
         Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
     }
 
-    private ViewState startPartitionLocked(AutofillId id, AutofillValue value) {
-        // TODO(b/33197203 , b/35707731): temporary workaround until partitioning supports auth
-        if (mResponseWaitingAuth != null) {
-            final ViewState viewState =
-                    new ViewState(this, id, value, this, ViewState.STATE_WAITING_RESPONSE_AUTH);
-            mViewStates.put(id, viewState);
-            return viewState;
-        }
-        if (DEBUG) {
-            Slog.d(TAG, "Starting partition for view id " + id);
-        }
-        final ViewState newViewState =
-                new ViewState(this, id, value, this,ViewState.STATE_STARTED_PARTITION);
-        mViewStates.put(id, newViewState);
-
-        // Must update value of nodes so:
-        // - proper node is focused
-        // - autofillValue is sent back to service when it was previously autofilled
-        for (int i = 0; i < mViewStates.size(); i++) {
-            final ViewState viewState = mViewStates.valueAt(i);
-
-            final ViewNode node = findViewNodeByIdLocked(viewState.id);
-            if (node == null) {
-                Slog.w(TAG, "startPartitionLocked(): no node for " + viewState.id);
-                continue;
-            }
-
-            final AutofillValue initialValue = viewState.getInitialValue();
-            final AutofillValue filledValue = viewState.getAutofilledValue();
-            final AutofillOverlay overlay = new AutofillOverlay();
-            if (filledValue != null && !filledValue.equals(initialValue)) {
-                overlay.value = filledValue;
-            }
-            overlay.focused = id.equals(viewState.id);
-            node.setAutofillOverlay(overlay);
-        }
-
-        FillRequest request = new FillRequest(mStructure, mClientState, 0);
-        mRemoteFillService.onFillRequest(request);
-
-        return newViewState;
-    }
-
     @Override
     public void onFillReady(FillResponse response, AutofillId filledId,
             @Nullable AutofillValue value) {
@@ -751,11 +878,6 @@
 
     private void notifyUnavailableToClient() {
         synchronized (mLock) {
-            if (mCurrentViewId == null) {
-                // TODO(b/33197203): temporary sanity check; should never happen
-                Slog.w(TAG, "notifyUnavailable(): mCurrentViewId is null");
-                return;
-            }
             if (!mHasCallback) return;
             try {
                 mClient.notifyNoFillUi(id, mWindowToken, mCurrentViewId);
@@ -922,7 +1044,7 @@
             }
 
             // ...or handle authentication.
-            // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
+            // TODO(b/37424539): proper implementation
             mService.setDatasetAuthenticationSelected(dataset.getId());
             mDatasetWaitingAuth = dataset;
             setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
@@ -958,23 +1080,6 @@
         }
     }
 
-    private boolean isIgnoredLocked(@NonNull AutofillId id) {
-        if (mResponses == null) return false;
-
-        for (int i = mResponses.size() - 1; i >= 0; i--) {
-            final FillResponse response = mResponses.valueAt(i);
-            final AutofillId[] ignoredIds = response.getIgnoredIds();
-            if (ignoredIds == null) continue;
-            for (int j = 0; j < ignoredIds.length; j++) {
-                final AutofillId ignoredId = ignoredIds[j];
-                if (ignoredId != null && ignoredId.equals(id)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     void dumpLocked(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("id: "); pw.println(id);
         pw.print(prefix); pw.print("uid: "); pw.println(uid);
@@ -992,7 +1097,7 @@
         }
         if (VERBOSE) {
             pw.print(prefix); pw.print("mStructure: " );
-            // TODO(b/33197203): add method do dump AssistStructure on pw
+            // TODO: add method on AssistStructure to dump on pw
             if (mStructure != null) {
                 pw.println("look at logcat" );
                 mStructure.dump(); // dumps to logcat
@@ -1027,39 +1132,6 @@
         }
     }
 
-    private ViewNode findViewNodeByIdLocked(AutofillId id) {
-        final int size = mStructure.getWindowNodeCount();
-        for (int i = 0; i < size; i++) {
-            final WindowNode window = mStructure.getWindowNodeAt(i);
-            final ViewNode root = window.getRootViewNode();
-            if (id.equals(root.getAutofillId())) {
-                return root;
-            }
-            final ViewNode child = findViewNodeByIdLocked(root, id);
-            if (child != null) {
-                return child;
-            }
-        }
-        return null;
-    }
-
-    private ViewNode findViewNodeByIdLocked(ViewNode parent, AutofillId id) {
-        final int childrenSize = parent.getChildCount();
-        if (childrenSize > 0) {
-            for (int i = 0; i < childrenSize; i++) {
-                final ViewNode child = parent.getChildAt(i);
-                if (id.equals(child.getAutofillId())) {
-                    return child;
-                }
-                final ViewNode grandChild = findViewNodeByIdLocked(child, id);
-                if (grandChild != null && id.equals(grandChild.getAutofillId())) {
-                    return grandChild;
-                }
-            }
-        }
-        return null;
-    }
-
     void destroyLocked() {
         mRemoteFillService.destroy();
         mUi.setCallback(null);
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index ea5f113..3967f59 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -61,7 +61,7 @@
     public static final int STATE_STARTED_PARTITION = 0x20;
     /** User select a dataset in this view, but service must authenticate first. */
     public static final int STATE_WAITING_DATASET_AUTH = 0x40;
-    // TODO(b/33197203 , b/35707731): temporary workaround until partitioning supports auth
+    // TODO(b/37424539): temporary workaround until partitioning supports auth
     public static final int STATE_WAITING_RESPONSE_AUTH = 0x80;
 
     public final AutofillId id;
@@ -151,9 +151,9 @@
         mState &= ~state;
     }
 
-    // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
-    // it can change  the value and update the UI; similarly, should replace code that
-    // directly sets mAutoFilLValue to use encapsulation.
+    // TODO: refactor / rename / document this method (and maybeCallOnFillReady) to make it clear
+    // that it can change the value and update the UI; similarly, should replace code that
+    // directly sets mAutofillValue to use encapsulation.
     void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) {
         if (autofillValue != null) {
             mCurrentValue = autofillValue;
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 b68e3b1..bb47e5b 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -117,7 +117,7 @@
             final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             content.measure(widthMeasureSpec, heightMeasureSpec);
             decor.setOnClickListener(v -> mCallback.onResponsePicked(response));
-            // TODO(b/33197203 , b/36660292): temporary limiting maximum height and minimum width
+            // TODO(b/37567439): temporary limiting maximum height and minimum width
             mContentWidth = Math.max(content.getMeasuredWidth(), 1000);
             mContentHeight = Math.min(content.getMeasuredHeight(), 500);
 
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 41b70a1..9bb0f86 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -36,6 +36,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.FeatureInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.net.NetworkPolicyManager;
@@ -203,13 +204,15 @@
             checkNotNull(request, "Request cannot be null");
             checkNotNull(callback, "Callback cannot be null");
             checkCallerIsSystemOr(callingPackage);
+            int userId = getCallingUserId();
+            checkUsesFeature(callingPackage, userId);
             final long callingIdentity = Binder.clearCallingIdentity();
             try {
-                //TODO bindServiceAsUser
-                getContext().bindService(
+                getContext().bindServiceAsUser(
                         new Intent().setComponent(SERVICE_TO_BIND_TO),
                         createServiceConnection(request, callback, callingPackage),
-                        Context.BIND_AUTO_CREATE);
+                        Context.BIND_AUTO_CREATE,
+                        UserHandle.of(userId));
             } finally {
                 Binder.restoreCallingIdentity(callingIdentity);
             }
@@ -219,6 +222,7 @@
         public List<String> getAssociations(String callingPackage, int userId)
                 throws RemoteException {
             checkCallerIsSystemOr(callingPackage, userId);
+            checkUsesFeature(callingPackage, getCallingUserId());
             return CollectionUtils.map(
                     readAllAssociations(userId, callingPackage),
                     a -> a.deviceAddress);
@@ -230,6 +234,7 @@
                 throws RemoteException {
             checkNotNull(deviceMacAddress);
             checkCallerIsSystemOr(callingPackage);
+            checkUsesFeature(callingPackage, getCallingUserId());
             updateAssociations(associations -> CollectionUtils.remove(associations,
                     new Association(getCallingUserId(), deviceMacAddress, callingPackage)));
         }
@@ -282,12 +287,25 @@
 
         private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
             checkCallerIsSystemOr(callingPackage);
-            checkState(!ArrayUtils.isEmpty(readAllAssociations(getCallingUserId(), callingPackage)),
+            int userId = getCallingUserId();
+            checkState(!ArrayUtils.isEmpty(readAllAssociations(userId, callingPackage)),
                     "App must have an association before calling this API");
+            checkUsesFeature(callingPackage, userId);
+        }
+
+        private void checkUsesFeature(String pkg, int userId) {
+            FeatureInfo[] reqFeatures = getPackageInfo(pkg, userId).reqFeatures;
+            String requiredFeature = PackageManager.FEATURE_COMPANION_DEVICE_SETUP;
+            int numFeatures = ArrayUtils.size(reqFeatures);
+            for (int i = 0; i < numFeatures; i++) {
+                if (requiredFeature.equals(reqFeatures[i].name)) return;
+            }
+            throw new IllegalStateException("Must declare uses-feature "
+                    + requiredFeature
+                    + " in manifest to use this API");
         }
     }
 
-
     private int getCallingUserId() {
         return UserHandle.getUserId(Binder.getCallingUid());
     }
@@ -398,7 +416,9 @@
         return Binder.withCleanCallingIdentity(() -> {
             try {
                 return getContext().getPackageManager().getPackageInfoAsUser(
-                        packageName, PackageManager.GET_PERMISSIONS, userId);
+                        packageName,
+                        PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS,
+                        userId);
             } catch (PackageManager.NameNotFoundException e) {
                 Slog.e(LOG_TAG, "Failed to get PackageInfo for package " + packageName, e);
                 return null;
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index d25b3cc..114d761 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -16,9 +16,6 @@
 
 package com.android.server;
 
-import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
-import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
-
 import android.Manifest.permission;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -36,8 +33,6 @@
 import android.net.NetworkKey;
 import android.net.NetworkScoreManager;
 import android.net.NetworkScorerAppData;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
 import android.net.ScoredNetwork;
 import android.net.Uri;
 import android.net.wifi.ScanResult;
@@ -46,24 +41,18 @@
 import android.net.wifi.WifiScanner;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
-import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Pair;
-import android.util.TimedRemoteCaller;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -80,9 +69,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
@@ -99,7 +85,6 @@
 
     private final Context mContext;
     private final NetworkScorerAppManager mNetworkScorerAppManager;
-    private final AtomicReference<RequestRecommendationCaller> mReqRecommendationCallerRef;
     @GuardedBy("mScoreCaches")
     private final Map<Integer, RemoteCallbackList<INetworkScoreCache>> mScoreCaches;
     /** Lock used to update mPackageMonitor when scorer package changes occur. */
@@ -113,7 +98,6 @@
     private NetworkScorerPackageMonitor mPackageMonitor;
     @GuardedBy("mServiceConnectionLock")
     private ScoringServiceConnection mServiceConnection;
-    private volatile long mRecommendationRequestTimeoutMs;
 
     private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
         @Override
@@ -256,9 +240,6 @@
         mContext.registerReceiverAsUser(
                 mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/,
                 null /* scheduler */);
-        mReqRecommendationCallerRef = new AtomicReference<>(
-                new RequestRecommendationCaller(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS));
-        mRecommendationRequestTimeoutMs = TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS;
         mHandler = new ServiceHandler(looper);
         mContentObserver = new DispatchingContentObserver(context, mHandler);
         mServiceConnProducer = serviceConnProducer;
@@ -295,10 +276,6 @@
         mContentObserver.observe(packageNameUri,
                 ServiceHandler.MSG_RECOMMENDATIONS_PACKAGE_CHANGED);
 
-        final Uri timeoutUri = Global.getUriFor(Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS);
-        mContentObserver.observe(timeoutUri,
-                ServiceHandler.MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED);
-
         final Uri settingUri = Global.getUriFor(Global.NETWORK_RECOMMENDATIONS_ENABLED);
         mContentObserver.observe(settingUri,
                 ServiceHandler.MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED);
@@ -827,87 +804,6 @@
     }
 
     @Override
-    public RecommendationResult requestRecommendation(RecommendationRequest request) {
-        mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
-        throwIfCalledOnMainThread();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            final INetworkRecommendationProvider provider = getRecommendationProvider();
-            if (provider != null) {
-                try {
-                    final RequestRecommendationCaller caller = mReqRecommendationCallerRef.get();
-                    return caller.getRecommendationResult(provider, request);
-                } catch (RemoteException | TimeoutException e) {
-                    Log.w(TAG, "Failed to request a recommendation.", e);
-                    // TODO: 12/15/16 - Keep track of failures.
-                }
-            }
-
-            if (DBG) {
-                Log.d(TAG, "Returning the default network recommendation.");
-            }
-
-            if (request != null && request.getDefaultWifiConfig() != null) {
-                return RecommendationResult.createConnectRecommendation(
-                        request.getDefaultWifiConfig());
-            }
-            return RecommendationResult.createDoNotConnectRecommendation();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Request a recommendation for the best network to connect to
-     * taking into account the inputs from the {@link RecommendationRequest}.
-     *
-     * @param request a {@link RecommendationRequest} instance containing the details of the request
-     * @param remoteCallback a {@link IRemoteCallback} instance to invoke when the recommendation
-     *                       is available.
-     * @throws SecurityException if the caller is not the system
-     */
-    @Override
-    public void requestRecommendationAsync(RecommendationRequest request,
-            RemoteCallback remoteCallback) {
-        mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
-
-        final OneTimeCallback oneTimeCallback = new OneTimeCallback(remoteCallback);
-        final Pair<RecommendationRequest, OneTimeCallback> pair =
-                Pair.create(request, oneTimeCallback);
-        final Message timeoutMsg = mHandler.obtainMessage(
-                ServiceHandler.MSG_RECOMMENDATION_REQUEST_TIMEOUT, pair);
-        final INetworkRecommendationProvider provider = getRecommendationProvider();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            if (provider != null) {
-                try {
-                    mHandler.sendMessageDelayed(timeoutMsg, mRecommendationRequestTimeoutMs);
-                    provider.requestRecommendation(request, new IRemoteCallback.Stub() {
-                        @Override
-                        public void sendResult(Bundle data) throws RemoteException {
-                            // Remove the timeout message
-                            mHandler.removeMessages(timeoutMsg.what, pair);
-                            oneTimeCallback.sendResult(data);
-                        }
-                    }, 0 /*sequence*/);
-                    return;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to request a recommendation.", e);
-                    // TODO: 12/15/16 - Keep track of failures.
-                    // Remove the timeout message
-                    mHandler.removeMessages(timeoutMsg.what, pair);
-                    // Will fall through and send back the default recommendation.
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        // Else send back the default recommendation.
-        sendDefaultRecommendationResponse(request, oneTimeCallback);
-    }
-
-    @Override
     public boolean requestScores(NetworkKey[] networks) {
         mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
         final long token = Binder.clearCallingIdentity();
@@ -941,7 +837,6 @@
                 return;
             }
             writer.println("Current scorer: " + currentScorer);
-            writer.println("RecommendationRequestTimeoutMs: " + mRecommendationRequestTimeoutMs);
 
             sendCacheUpdateCallback(new BiConsumer<INetworkScoreCache, Object>() {
                 @Override
@@ -996,12 +891,6 @@
         }
     }
 
-    private void throwIfCalledOnMainThread() {
-        if (Thread.currentThread() == mContext.getMainLooper().getThread()) {
-            throw new RuntimeException("Cannot invoke on the main thread");
-        }
-    }
-
     @Nullable
     private INetworkRecommendationProvider getRecommendationProvider() {
         synchronized (mServiceConnectionLock) {
@@ -1012,19 +901,6 @@
         return null;
     }
 
-    @VisibleForTesting
-    public void refreshRecommendationRequestTimeoutMs() {
-        final ContentResolver cr = mContext.getContentResolver();
-        long timeoutMs = Settings.Global.getLong(cr,
-                Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, -1L /*default*/);
-        if (timeoutMs < 0) {
-            timeoutMs = TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS;
-        }
-        if (DBG) Log.d(TAG, "Updating the recommendation request timeout to " + timeoutMs + " ms");
-        mRecommendationRequestTimeoutMs = timeoutMs;
-        mReqRecommendationCallerRef.set(new RequestRecommendationCaller(timeoutMs));
-    }
-
     // The class and methods need to be public for Mockito to work.
     @VisibleForTesting
     public static class ScoringServiceConnection implements ServiceConnection {
@@ -1114,93 +990,10 @@
         }
     }
 
-    /**
-     * Executes the async requestRecommendation() call with a timeout.
-     */
-    private static final class RequestRecommendationCaller
-            extends TimedRemoteCaller<RecommendationResult> {
-        private final IRemoteCallback mCallback;
-
-        RequestRecommendationCaller(long callTimeoutMillis) {
-            super(callTimeoutMillis);
-            mCallback = new IRemoteCallback.Stub() {
-                @Override
-                public void sendResult(Bundle data) throws RemoteException {
-                    final RecommendationResult result =
-                            data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
-                    final int sequence = data.getInt(EXTRA_SEQUENCE, -1);
-                    if (VERBOSE) Log.v(TAG, "callback received for sequence " + sequence);
-                    onRemoteMethodResult(result, sequence);
-                }
-            };
-        }
-
-        /**
-         * Runs the requestRecommendation() call on the given {@link INetworkRecommendationProvider}
-         * instance.
-         *
-         * @param target the {@link INetworkRecommendationProvider} to request a recommendation
-         *               from
-         * @param request the {@link RecommendationRequest} from the calling client
-         * @return a {@link RecommendationResult} from the provider
-         * @throws RemoteException if the call failed
-         * @throws TimeoutException if the call took longer than the set timeout
-         */
-        RecommendationResult getRecommendationResult(INetworkRecommendationProvider target,
-                RecommendationRequest request) throws RemoteException, TimeoutException {
-            final int sequence = onBeforeRemoteCall();
-            if (VERBOSE) Log.v(TAG, "getRecommendationResult() seq=" + sequence);
-            target.requestRecommendation(request, mCallback, sequence);
-            return getResultTimed(sequence);
-        }
-    }
-
-    /**
-     * A wrapper around {@link RemoteCallback} that guarantees
-     * {@link RemoteCallback#sendResult(Bundle)} will be invoked at most once.
-     */
-    @VisibleForTesting
-    public static final class OneTimeCallback {
-        private final RemoteCallback mRemoteCallback;
-        private final AtomicBoolean mCallbackRun;
-
-        public OneTimeCallback(RemoteCallback remoteCallback) {
-            mRemoteCallback = remoteCallback;
-            mCallbackRun = new AtomicBoolean(false);
-        }
-
-        public void sendResult(Bundle data) {
-            if (mCallbackRun.compareAndSet(false, true)) {
-                mRemoteCallback.sendResult(data);
-            }
-        }
-    }
-
-    private static void sendDefaultRecommendationResponse(RecommendationRequest request,
-            OneTimeCallback remoteCallback) {
-        if (DBG) {
-            Log.d(TAG, "Returning the default network recommendation.");
-        }
-
-        final RecommendationResult result;
-        if (request != null && request.getDefaultWifiConfig() != null) {
-            result = RecommendationResult.createConnectRecommendation(
-                    request.getDefaultWifiConfig());
-        } else {
-            result = RecommendationResult.createDoNotConnectRecommendation();
-        }
-
-        final Bundle data = new Bundle();
-        data.putParcelable(EXTRA_RECOMMENDATION_RESULT, result);
-        remoteCallback.sendResult(data);
-    }
-
     @VisibleForTesting
     public final class ServiceHandler extends Handler {
-        public static final int MSG_RECOMMENDATION_REQUEST_TIMEOUT = 1;
-        public static final int MSG_RECOMMENDATIONS_PACKAGE_CHANGED = 2;
-        public static final int MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED = 3;
-        public static final int MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED = 4;
+        public static final int MSG_RECOMMENDATIONS_PACKAGE_CHANGED = 1;
+        public static final int MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED = 2;
 
         public ServiceHandler(Looper looper) {
             super(looper);
@@ -1210,26 +1003,11 @@
         public void handleMessage(Message msg) {
             final int what = msg.what;
             switch (what) {
-                case MSG_RECOMMENDATION_REQUEST_TIMEOUT:
-                    if (DBG) {
-                        Log.d(TAG, "Network recommendation request timed out.");
-                    }
-                    final Pair<RecommendationRequest, OneTimeCallback> pair =
-                            (Pair<RecommendationRequest, OneTimeCallback>) msg.obj;
-                    final RecommendationRequest request = pair.first;
-                    final OneTimeCallback remoteCallback = pair.second;
-                    sendDefaultRecommendationResponse(request, remoteCallback);
-                    break;
-
                 case MSG_RECOMMENDATIONS_PACKAGE_CHANGED:
                 case MSG_RECOMMENDATION_ENABLED_SETTING_CHANGED:
                     refreshBinding();
                     break;
 
-                case MSG_RECOMMENDATION_REQUEST_TIMEOUT_CHANGED:
-                    refreshRecommendationRequestTimeoutMs();
-                    break;
-
                 default:
                     Log.w(TAG,"Unknown message: " + what);
             }
diff --git a/services/core/java/com/android/server/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/SyntheticPasswordCrypto.java
index 12d91c5..71ab2a5 100644
--- a/services/core/java/com/android/server/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/SyntheticPasswordCrypto.java
@@ -139,12 +139,14 @@
             keyStore.load(null);
             KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
                     .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .setCriticalToDeviceEncryption(true);
             if (sid != 0) {
                 builder.setUserAuthenticationRequired(true)
                         .setBoundToSpecificSecureUserId(sid)
                         .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
             }
+
             keyStore.setEntry(keyAlias,
                     new KeyStore.SecretKeyEntry(secretKey),
                     builder.build());
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index adb55b9..018e41b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -112,6 +112,7 @@
 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;
@@ -752,10 +753,12 @@
         synchronized (accounts.dbLock) {
             synchronized (accounts.cacheLock) {
                 Map<String, Integer> packagesToVisibility;
+                List<String> accountRemovedReceivers;
                 if (notify) {
                     if (isSpecialPackageKey(packageName)) {
                         packagesToVisibility =
                                 getRequestingPackages(account, accounts);
+                        accountRemovedReceivers = getAccountRemovedReceivers(account, accounts);
                     } else {
                         if (!packageExistsForUser(packageName, accounts.userId)) {
                             return false; // package is not installed.
@@ -763,15 +766,20 @@
                         packagesToVisibility = new HashMap<>();
                         packagesToVisibility.put(packageName,
                                 resolveAccountVisibility(account, packageName, accounts));
+                        accountRemovedReceivers = new ArrayList<>();
+                        if (shouldNotifyPackageOnAccountRemoval(account, packageName, accounts)) {
+                            accountRemovedReceivers.add(packageName);
+                        }
                     }
                 } else {
-                    // Notifications will not be send.
+                    // Notifications will not be send - only used during add account.
                     if (!isSpecialPackageKey(packageName) &&
                             !packageExistsForUser(packageName, accounts.userId)) {
                         // package is not installed and not meta value.
                         return false;
                     }
-                    packagesToVisibility = new HashMap<>();
+                    packagesToVisibility = Collections.emptyMap();
+                    accountRemovedReceivers = Collections.emptyList();
                 }
 
                 if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) {
@@ -781,11 +789,14 @@
                 if (notify) {
                     for (Entry<String, Integer> packageToVisibility : packagesToVisibility
                             .entrySet()) {
-                        if (packageToVisibility.getValue()
-                                != AccountManager.VISIBILITY_NOT_VISIBLE) {
+                        if (shouldNotifyOnVisibilityChange(packageToVisibility.getValue(),
+                                resolveAccountVisibility(account, packageName, accounts))) {
                             notifyPackage(packageToVisibility.getKey(), accounts);
                         }
                     }
+                    for (String packageNameToNotify : accountRemovedReceivers) {
+                        sendAccountRemovedBroadcast(account, packageNameToNotify, accounts.userId);
+                    }
                     sendAccountsChangedBroadcast(accounts.userId);
                 }
                 return true;
@@ -889,10 +900,11 @@
     // Send notification to all packages which can potentially see the account
     private void sendNotificationAccountUpdated(Account account, UserAccounts accounts) {
         Map<String, Integer> packagesToVisibility = getRequestingPackages(account, accounts);
-        // packages with VISIBILITY_USER_MANAGED_NOT_VISIBL still get notification.
-        // Should we notify VISIBILITY_NOT_VISIBLE packages when account is added?
+
         for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
-            if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
+            if ((packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE)
+                    && (packageToVisibility.getValue()
+                        != AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE)) {
                 notifyPackage(packageToVisibility.getKey(), accounts);
             }
         }
@@ -931,6 +943,44 @@
         return result;
     }
 
+    // Returns a list of packages listening to ACTION_ACCOUNT_REMOVED able to see the account.
+    private List<String> getAccountRemovedReceivers(Account account, UserAccounts accounts) {
+        Intent intent = new Intent(AccountManager.ACTION_ACCOUNT_REMOVED);
+        intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        List<ResolveInfo> receivers =
+            mPackageManager.queryBroadcastReceiversAsUser(intent, 0, accounts.userId);
+        List<String> result = new ArrayList<>();
+        if (receivers == null) {
+            return result;
+        }
+        for (ResolveInfo resolveInfo: receivers) {
+            String packageName = resolveInfo.activityInfo.applicationInfo.packageName;
+            int visibility = resolveAccountVisibility(account, packageName, accounts);
+            if (visibility == AccountManager.VISIBILITY_VISIBLE
+                || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE) {
+                result.add(packageName);
+            }
+        }
+        return result;
+    }
+
+    // Returns true if given package is listening to ACTION_ACCOUNT_REMOVED and can see the account.
+    private boolean shouldNotifyPackageOnAccountRemoval(Account account,
+            String packageName, UserAccounts accounts) {
+        int visibility = resolveAccountVisibility(account, packageName, accounts);
+        if (visibility != AccountManager.VISIBILITY_VISIBLE
+            && visibility != AccountManager.VISIBILITY_USER_MANAGED_VISIBLE) {
+            return false;
+        }
+
+        Intent intent = new Intent(AccountManager.ACTION_ACCOUNT_REMOVED);
+        intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        intent.setPackage(packageName);
+        List<ResolveInfo> receivers =
+            mPackageManager.queryBroadcastReceiversAsUser(intent, 0, accounts.userId);
+        return (receivers != null && receivers.size() > 0);
+    }
+
     private boolean packageExistsForUser(String packageName, int userId) {
         try {
             long identityToken = clearCallingIdentity();
@@ -959,9 +1009,12 @@
         mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId));
     }
 
-    private void sendAccountRemovedBroadcast(int userId) {
+    private void sendAccountRemovedBroadcast(Account account, String packageName, int userId) {
         Intent intent = new Intent(AccountManager.ACTION_ACCOUNT_REMOVED);
         intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        intent.setPackage(packageName);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
         mContext.sendBroadcastAsUser(intent, new UserHandle(userId));
     }
 
@@ -1087,6 +1140,8 @@
                                     + "'s registered authenticator no longer exist.");
                             Map<String, Integer> packagesToVisibility =
                                     getRequestingPackages(account, accounts);
+                            List<String> accountRemovedReceivers =
+                                getAccountRemovedReceivers(account, accounts);
                             accountsDb.beginTransaction();
                             try {
                                 accountsDb.deleteDeAccount(accountId);
@@ -1112,12 +1167,14 @@
 
                             for (Entry<String, Integer> packageToVisibility :
                                     packagesToVisibility.entrySet()) {
-                                if (packageToVisibility.getValue()
-                                        != AccountManager.VISIBILITY_NOT_VISIBLE) {
+                                if (shouldNotifyOnVisibilityChange(packageToVisibility.getValue(),
+                                        AccountManager.VISIBILITY_NOT_VISIBLE)) {
                                     notifyPackage(packageToVisibility.getKey(), accounts);
                                 }
                             }
-                            sendAccountRemovedBroadcast(accounts.userId);
+                            for (String packageName : accountRemovedReceivers) {
+                                sendAccountRemovedBroadcast(account, packageName, accounts.userId);
+                            }
                         } else {
                             ArrayList<String> accountNames = accountNamesByType.get(account.type);
                             if (accountNames == null) {
@@ -1147,6 +1204,14 @@
         }
     }
 
+    private boolean shouldNotifyOnVisibilityChange(int oldVisibility, int newVisibility) {
+        boolean oldVisible = (oldVisibility == AccountManager.VISIBILITY_VISIBLE) ||
+            (oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+        boolean newVisible = (newVisibility == AccountManager.VISIBILITY_VISIBLE) ||
+            (newVisibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+        return oldVisible == newVisible;
+    }
+
     private SparseBooleanArray getUidsOfInstalledOrUpdatedPackagesAsUser(int userId) {
         // Get the UIDs of all apps that might have data on the device. We want
         // to preserve user data if the app might otherwise be storing data.
@@ -1911,6 +1976,8 @@
         }
         synchronized (accounts.dbLock) {
             synchronized (accounts.cacheLock) {
+                List<String> accountRemovedReceivers =
+                    getAccountRemovedReceivers(accountToRename, accounts);
                 accounts.accountsDb.beginTransaction();
                 Account renamedAccount = new Account(newName, accountToRename.type);
                 if ((accounts.accountsDb.findCeAccountId(renamedAccount) >= 0)) {
@@ -1978,7 +2045,9 @@
 
                 sendNotificationAccountUpdated(resultAccount, accounts);
                 sendAccountsChangedBroadcast(accounts.userId);
-                sendAccountRemovedBroadcast(accounts.userId);
+                for (String packageName : accountRemovedReceivers) {
+                    sendAccountRemovedBroadcast(accountToRename, packageName, accounts.userId);
+                }
             }
         }
         return resultAccount;
@@ -2181,6 +2250,8 @@
             synchronized (accounts.cacheLock) {
                 Map<String, Integer> packagesToVisibility = getRequestingPackages(account,
                         accounts);
+                List<String> accountRemovedReceivers =
+                    getAccountRemovedReceivers(account, accounts);
                 accounts.accountsDb.beginTransaction();
                 // Set to a dummy value, this will only be used if the database
                 // transaction succeeds.
@@ -2206,15 +2277,18 @@
                     removeAccountFromCacheLocked(accounts, account);
                     for (Entry<String, Integer> packageToVisibility : packagesToVisibility
                             .entrySet()) {
-                        if (packageToVisibility.getValue()
-                                != AccountManager.VISIBILITY_NOT_VISIBLE) {
+                        if ((packageToVisibility.getValue() == AccountManager.VISIBILITY_VISIBLE)
+                                || (packageToVisibility.getValue()
+                                    == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE)) {
                             notifyPackage(packageToVisibility.getKey(), accounts);
                         }
                     }
 
                     // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred.
                     sendAccountsChangedBroadcast(accounts.userId);
-                    sendAccountRemovedBroadcast(accounts.userId);
+                    for (String packageName : accountRemovedReceivers) {
+                        sendAccountRemovedBroadcast(account, packageName, accounts.userId);
+                    }
                     String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE
                             : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE;
                     logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 099894c..f02dc3c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19152,6 +19152,12 @@
                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
                     break;
+                case "com.android.launcher.action.INSTALL_SHORTCUT":
+                    // As of O, we no longer support this broadcasts, even for pre-O apps.
+                    // Apps should now be using ShortcutManager.pinRequestShortcut().
+                    Log.w(TAG, "Broadcast " + action
+                            + " no longer supported. It will not be delivered.");
+                    return ActivityManager.BROADCAST_SUCCESS;
             }
 
             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 6e84ed6..5f55411 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -62,6 +62,8 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.res.Configuration.EMPTY;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
 import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
 import static android.os.Build.VERSION_CODES.HONEYCOMB;
@@ -139,6 +141,7 @@
 import android.service.voice.IVoiceInteractionSession;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.view.AppTransitionAnimationSpec;
@@ -240,13 +243,8 @@
     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
     long pauseTime;         // last time we started pausing the activity
     long launchTickTime;    // base time for launch tick messages
-    // TODO: Refactor mLastReportedConfiguration and mLastReportedOverrideConfiguration to use a
-    // MergedConfiguration object for clarity.
-    private Configuration mLastReportedConfiguration; // configuration activity was last running in
-    // Overridden configuration by the activity task
-    // WARNING: Reference points to {@link TaskRecord#getMergedOverrideConfig}, so its internal
-    // state should never be altered directly.
-    private Configuration mLastReportedOverrideConfiguration;
+    // Last configuration reported to the activity in the client process.
+    private MergedConfiguration mLastReportedConfiguration;
     private int mLastReportedDisplayId;
     CompatibilityInfo compat;// last used compatibility mode
     ActivityRecord resultTo; // who started this entry, so will get our reply
@@ -274,11 +272,13 @@
                                         // completed
     boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
     int configChangeFlags;  // which config values have changed
-    boolean keysPaused;     // has key dispatching been paused for it?
+    private boolean keysPaused;     // has key dispatching been paused for it?
     int launchMode;         // the launch mode activity attribute.
     boolean visible;        // does this activity's window need to be shown?
     boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
                                      // might hide this activity?
+    private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
+                                        // process that it is hidden.
     boolean sleeping;       // have we told the activity to sleep?
     boolean nowVisible;     // is this activity's window visible?
     boolean idle;           // has the activity gone idle?
@@ -344,10 +344,7 @@
     /**
      * Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)}
      */
-    private final Configuration mTmpConfig1 = new Configuration();
-    private final Configuration mTmpConfig2 = new Configuration();
-    private final Configuration mTmpConfig3 = new Configuration();
-    private final Point mTmpPoint = new Point();
+    private final Configuration mTmpConfig = new Configuration();
     private final Rect mTmpBounds = new Rect();
 
     private static String startingWindowStateToString(int state) {
@@ -398,10 +395,9 @@
                 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
                 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
                 pw.print(" theme=0x"); pw.println(Integer.toHexString(theme));
-        pw.print(prefix); pw.print("mLastReportedConfiguration=");
-                pw.println(mLastReportedConfiguration);
-        pw.print(prefix); pw.print("mLastReportedOverrideConfiguration=");
-                pw.println(mLastReportedOverrideConfiguration);
+        pw.println(prefix + "mLastReportedConfigurations:");
+        mLastReportedConfiguration.dump(pw, prefix + " ");
+
         pw.print(prefix); pw.print("CurrentConfiguration="); pw.println(getConfiguration());
         if (!getOverrideConfiguration().equals(EMPTY)) {
             pw.println(prefix + "OverrideConfiguration=" + getOverrideConfiguration());
@@ -523,6 +519,9 @@
                     else TimeUtils.formatDuration(lastVisibleTime, now, pw);
                     pw.println();
         }
+        if (mDeferHidingClient) {
+            pw.println(prefix + "mDeferHidingClient=" + mDeferHidingClient);
+        }
         if (deferRelaunchUntilPaused || configChangeFlags != 0) {
             pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
                     pw.print(" configChangeFlags=");
@@ -799,8 +798,7 @@
         resolvedType = _resolvedType;
         componentSpecified = _componentSpecified;
         rootVoiceInteraction = _rootVoiceInteraction;
-        mLastReportedConfiguration = new Configuration(_configuration);
-        mLastReportedOverrideConfiguration = new Configuration();
+        mLastReportedConfiguration = new MergedConfiguration(_configuration);
         resultTo = _resultTo;
         resultWho = _resultWho;
         requestCode = _reqCode;
@@ -1567,18 +1565,31 @@
         return mWindowContainerController.screenshotApplications(getDisplayId(), w, h, scale);
     }
 
+    void setDeferHidingClient(boolean deferHidingClient) {
+        if (mDeferHidingClient == deferHidingClient) {
+            return;
+        }
+        mDeferHidingClient = deferHidingClient;
+        if (!mDeferHidingClient && !visible) {
+            // Hiding the client is no longer deferred and the app isn't visible still, go ahead and
+            // update the visibility.
+            setVisibility(false);
+        }
+    }
+
     void setVisibility(boolean visible) {
-        mWindowContainerController.setVisibility(visible);
+        mWindowContainerController.setVisibility(visible, mDeferHidingClient);
     }
 
     // TODO: Look into merging with #setVisibility()
     void setVisible(boolean newVisible) {
         visible = newVisible;
+        mDeferHidingClient = !visible && mDeferHidingClient;
         if (!visible && mUpdateTaskThumbnailWhenHidden) {
             updateThumbnailLocked(screenshotActivityLocked(), null /* description */);
             mUpdateTaskThumbnailWhenHidden = false;
         }
-        mWindowContainerController.setVisibility(visible);
+        setVisibility(visible);
         final ArrayList<ActivityContainer> containers = mChildContainers;
         for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
             final ActivityContainer container = containers.get(containerNdx);
@@ -2191,15 +2202,15 @@
      * global configuration is sent to the client for this activity.
      */
     void setLastReportedGlobalConfiguration(@NonNull Configuration config) {
-        mLastReportedConfiguration.setTo(config);
+        mLastReportedConfiguration.setGlobalConfiguration(config);
     }
 
     /**
-     * Set the last reported merged override configuration to the client. Should be called whenever
+     * Set the last reported configuration to the client. Should be called whenever
      * a new merged configuration is sent to the client for this activity.
      */
-    void setLastReportedMergedOverrideConfiguration(@NonNull Configuration config) {
-        mLastReportedOverrideConfiguration.setTo(config);
+    void setLastReportedConfiguration(@NonNull MergedConfiguration config) {
+        mLastReportedConfiguration.setTo(config);
     }
 
     /** Call when override config was sent to the Window Manager to update internal records. */
@@ -2207,7 +2218,7 @@
     // we should only set this when we actually report to the activity which is what the method
     // setLastReportedMergedOverrideConfiguration() does. Investigate if this is really needed.
     void onOverrideConfigurationSent() {
-        mLastReportedOverrideConfiguration.setTo(getMergedOverrideConfiguration());
+        mLastReportedConfiguration.setOverrideConfiguration(getMergedOverrideConfiguration());
     }
 
     @Override
@@ -2223,18 +2234,20 @@
     }
 
     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
-    private boolean updateOverrideConfiguration() {
+    private void updateOverrideConfiguration() {
+        mTmpConfig.unset();
         computeBounds(mTmpBounds);
         if (mTmpBounds.equals(mBounds)) {
-            return false;
+            return;
         }
+
         mBounds.set(mTmpBounds);
         // Bounds changed...update configuration to match.
-        mTmpConfig1.unset();
-        task.computeOverrideConfiguration(mTmpConfig1, mBounds, null /* insetBounds */,
-                false /* overrideWidth */, false /* overrideHeight */);
-        onOverrideConfigurationChanged(mTmpConfig1);
-        return true;
+        if (!mBounds.isEmpty()) {
+            task.computeOverrideConfiguration(mTmpConfig, mBounds, null /* insetBounds */,
+                    false /* overrideWidth */, false /* overrideHeight */);
+        }
+        onOverrideConfigurationChanged(mTmpConfig);
     }
 
     /**
@@ -2262,12 +2275,12 @@
         int maxActivityHeight = containingAppHeight;
 
         if (containingAppWidth < containingAppHeight) {
-            // Width is the shorter side, so we use that to figure-out what the max. height should
-            // be given the aspect ratio.
+            // Width is the shorter side, so we use that to figure-out what the max. height
+            // should be given the aspect ratio.
             maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
         } else {
-            // Height is the shorter side, so we use that to figure-out what the max. width should
-            // be given the aspect ratio.
+            // Height is the shorter side, so we use that to figure-out what the max. width
+            // should be given the aspect ratio.
             maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
         }
 
@@ -2337,9 +2350,8 @@
         // nothing to do.  We test the full configuration instead of the global and merged override
         // configurations because there are cases (like moving a task to the pinned stack) where
         // the combine configurations are equal, but would otherwise differ in the override config
-        mTmpConfig1.setTo(mLastReportedConfiguration);
-        mTmpConfig1.updateFrom(mLastReportedOverrideConfiguration);
-        if (getConfiguration().equals(mTmpConfig1) && !forceNewConfig && !displayChanged) {
+        mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
+        if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration & display unchanged in " + this);
             return true;
@@ -2350,18 +2362,12 @@
 
         // Find changes between last reported merged configuration and the current one. This is used
         // to decide whether to relaunch an activity or just report a configuration change.
-        final int changes = getConfigurationChanges(mTmpConfig1);
-
-        // Preserve configuration used to generate this set of configuration changes.
-        mTmpConfig3.setTo(mTmpConfig1);
+        final int changes = getConfigurationChanges(mTmpConfig);
 
         // Update last reported values.
-        final Configuration newGlobalConfig = service.getGlobalConfiguration();
         final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
-        mTmpConfig1.setTo(mLastReportedConfiguration);
-        mTmpConfig2.setTo(mLastReportedOverrideConfiguration);
-        mLastReportedConfiguration.setTo(newGlobalConfig);
-        mLastReportedOverrideConfiguration.setTo(newMergedOverrideConfig);
+        mLastReportedConfiguration.setConfiguration(service.getGlobalConfiguration(),
+                newMergedOverrideConfig);
 
         if (changes == 0 && !forceNewConfig) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2395,10 +2401,9 @@
                 "Checking to restart " + info.name + ": changed=0x"
                         + Integer.toHexString(changes) + ", handles=0x"
                         + Integer.toHexString(info.getRealConfigChanged())
-                        + ", newGlobalConfig=" + newGlobalConfig
-                        + ", newMergedOverrideConfig=" + newMergedOverrideConfig);
+                        + ", mLastReportedConfiguration=" + mLastReportedConfiguration);
 
-        if (shouldRelaunchLocked(changes, mTmpConfig3) || forceNewConfig) {
+        if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
             // Aha, the activity isn't handling the change, so DIE DIE DIE.
             configChangeFlags |= changes;
             startFreezingScreenLocked(app, globalChanges);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c3f346b..728a3b9 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1406,6 +1406,8 @@
                     prev.state = STOPPING;
                 } else if ((!prev.visible && !hasVisibleBehindActivity())
                         || mService.isSleepingOrShuttingDownLocked()) {
+                    // Clear out any deferred client hide we might currently have.
+                    prev.setDeferHidingClient(false);
                     // If we were visible then resumeTopActivities will release resources before
                     // stopping.
                     addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
@@ -2024,11 +2026,12 @@
         try {
             final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
                     "makeInvisible", true /* noThrow */, true /* beforeStopping */);
-            // We don't want to call setVisible(false) to avoid notifying the client of this
-            // intermittent invisible state if it can enter Pip and isn't stopped or stopping.
-            if (!canEnterPictureInPicture || r.state == STOPPING || r.state == STOPPED) {
-                r.setVisible(false);
-            }
+            // Defer telling the client it is hidden if it can enter Pip and isn't current stopped
+            // or stopping. This gives it a chance to enter Pip in onPause().
+            final boolean deferHidingClient = canEnterPictureInPicture
+                    && r.state != STOPPING && r.state != STOPPED;
+            r.setDeferHidingClient(deferHidingClient);
+            r.setVisible(false);
 
             switch (r.state) {
                 case STOPPING:
@@ -2053,15 +2056,6 @@
                     if (visibleBehind == r) {
                         releaseBackgroundResources(r);
                     } else {
-                        // If this activity is in a state where it can currently enter
-                        // picture-in-picture, then don't immediately schedule the idle now in case
-                        // the activity tries to enterPictureInPictureMode() later. Otherwise,
-                        // we will try and stop the activity next time idle is processed.
-
-                        if (canEnterPictureInPicture) {
-                            // We set r.visible=false so that Stop will later call setVisible for us
-                            r.visible = false;
-                        }
                         addToStopping(r, true /* scheduleIdle */,
                                 canEnterPictureInPicture /* idleDelayed */);
                     }
@@ -2343,20 +2337,22 @@
 
         mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
 
-        final boolean prevCanPip = prev != null && prev.checkEnterPictureInPictureState(
-                "resumeTopActivity", true /* noThrow */, userLeaving /* beforeStopping */);
+        boolean lastResumedCanPip = false;
+        final ActivityStack lastFocusedStack = mStackSupervisor.getLastStack();
+        if (lastFocusedStack != null && lastFocusedStack != this) {
+            // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
+            // represent the last resumed activity. However, the last focus stack does if it isn't null.
+            final ActivityRecord lastResumed = lastFocusedStack.mResumedActivity;
+            lastResumedCanPip = lastResumed != null && lastResumed.checkEnterPictureInPictureState(
+                    "resumeTopActivity", true /* noThrow */, userLeaving /* beforeStopping */);
+        }
         // If the flag RESUME_WHILE_PAUSING is set, then continue to schedule the previous activity
         // to be paused, while at the same time resuming the new resume activity only if the
         // previous activity can't go into Pip since we want to give Pip activities a chance to
         // enter Pip before resuming the next activity.
-        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
-        // TODO: This would be go to have however, the various call points that pass in
-        // prev need to be corrected first. In some cases the prev is equal to the next e.g. launch
-        // an app from home. And, is come other cases it is null e.g. press home button after
-        // launching an app. The doc on the method says prev. is null expect for the case we are
-        // coming from pause. We need to see if that is a valid thing and also if all the code in
-        // this method using prev. are setup to function like that.
-        //&& !prevCanPip;
+        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
+                && !lastResumedCanPip;
+
         boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
         if (mResumedActivity != null) {
             if (DEBUG_STATES) Slog.d(TAG_STATES,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fb8c161..bff3ce3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -162,6 +162,7 @@
 import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.IntArray;
+import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -1443,17 +1444,16 @@
             // a Binder interface which would create a new Configuration. Consequently we have to
             // always create a new Configuration here.
 
-            final Configuration globalConfiguration =
-                new Configuration(mService.getGlobalConfiguration());
-            r.setLastReportedGlobalConfiguration(globalConfiguration);
-            final Configuration mergedOverrideConfiguration =
-                new Configuration(r.getMergedOverrideConfiguration());
-            r.setLastReportedMergedOverrideConfiguration(mergedOverrideConfiguration);
+            final MergedConfiguration mergedConfiguration = new MergedConfiguration(
+                    mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
+            r.setLastReportedConfiguration(mergedConfiguration);
 
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                     System.identityHashCode(r), r.info,
-                    globalConfiguration,
-                    mergedOverrideConfiguration, r.compat,
+                    // TODO: Have this take the merged configuration instead of separate global and
+                    // override configs.
+                    mergedConfiguration.getGlobalConfiguration(),
+                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                     r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                     r.persistentState, results, newIntents, !andResume,
                     mService.isNextTransitionForward(), profilerInfo);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index dc636e5..056fec5 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -2212,11 +2212,6 @@
 
     /** Returns the bounds that should be used to launch this task. */
     Rect getLaunchBounds() {
-        // If we're over lockscreen, forget about stack bounds and use fullscreen.
-        if (mService.mStackSupervisor.mKeyguardController.isKeyguardShowing()) {
-            return null;
-        }
-
         if (mStack == null) {
             return null;
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eea5473..457cf87 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6044,8 +6044,8 @@
                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
-        accessibilityManager.addTouchExplorationStateChangeListener(this);
-        accessibilityManager.addAccessibilityServicesStateChangeListener(this);
+        accessibilityManager.addTouchExplorationStateChangeListener(this, null);
+        accessibilityManager.addAccessibilityServicesStateChangeListener(this, null);
     }
 
     //---------------------------------------------------------------------------------
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 9eda929..b0f84fe 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -46,32 +46,28 @@
 public final class PlaybackActivityMonitor
         implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer {
 
-    public final static String TAG = "AudioService.PlaybackActivityMonitor";
+    public static final String TAG = "AudioService.PlaybackActivityMonitor";
 
-    private final static boolean DEBUG = false;
-    private final static int VOLUME_SHAPER_SYSTEM_DUCK_ID = 1;
+    private static final boolean DEBUG = false;
+    private static final int VOLUME_SHAPER_SYSTEM_DUCK_ID = 1;
 
-    private final VolumeShaper.Configuration DUCK_VSHAPE =
+    private static final VolumeShaper.Configuration DUCK_VSHAPE =
             new VolumeShaper.Configuration.Builder()
                 .setId(VOLUME_SHAPER_SYSTEM_DUCK_ID)
                 .setCurve(new float[] { 0.f, 1.f } /* times */,
                     new float[] { 1.f, 0.2f } /* volumes */)
                 .setOptionFlags(VolumeShaper.Configuration.OPTION_FLAG_CLOCK_TIME)
-                .setDurationMillis(MediaFocusControl.getFocusRampTimeMs(
+                .setDuration(MediaFocusControl.getFocusRampTimeMs(
                     AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
                     new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION)
                             .build()))
                 .build();
-    private final VolumeShaper.Configuration DUCK_ID =
+    private static final VolumeShaper.Configuration DUCK_ID =
             new VolumeShaper.Configuration(VOLUME_SHAPER_SYSTEM_DUCK_ID);
-    private final VolumeShaper.Operation PLAY_CREATE_IF_NEEDED =
+    private static final VolumeShaper.Operation PLAY_CREATE_IF_NEEDED =
             new VolumeShaper.Operation.Builder(VolumeShaper.Operation.PLAY)
                     .createIfNeeded()
                     .build();
-    private final VolumeShaper.Operation TERMINATE =
-            new VolumeShaper.Operation.Builder()
-                    .terminate()
-                    .build();
 
     private final ArrayList<PlayMonitorClient> mClients = new ArrayList<PlayMonitorClient>();
     // a public client is one that needs an anonymized version of the playback configurations, we
@@ -166,14 +162,7 @@
         synchronized(mPlayerLock) {
             final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
             if (checkConfigurationCaller(piid, apc, binderUid)) {
-                try {
-                    apc.getPlayerProxy().applyVolumeShaper(
-                            DUCK_ID,
-                            TERMINATE);
-                } catch (Exception e) { /* silent failure, happens with binder failure */ }
                 mPlayers.remove(new Integer(piid));
-            } else {
-                Log.e(TAG, "Error releasing player " + piid);
             }
         }
     }
@@ -206,16 +195,16 @@
     }
 
     /**
-     * Check that piid and uid are valid for the given configuration.
+     * Check that piid and uid are valid for the given valid configuration.
      * @param piid the piid of the player.
      * @param apc the configuration found for this piid.
      * @param binderUid actual uid of client trying to signal a player state/event/attributes.
-     * @return true if the call is valid and the change should proceed, false otherwise.
+     * @return true if the call is valid and the change should proceed, false otherwise. Always
+     *      returns false when apc is null.
      */
     private static boolean checkConfigurationCaller(int piid,
             final AudioPlaybackConfiguration apc, int binderUid) {
         if (apc == null) {
-            Log.e(TAG, "Invalid operation: unknown player " + piid);
             return false;
         } else if ((binderUid != 0) && (apc.getClientUid() != binderUid)) {
             Log.e(TAG, "Forbidden operation from uid " + binderUid + " for player " + piid);
@@ -509,7 +498,7 @@
     /**
      * Inner class to track clients that want to be notified of playback updates
      */
-    private final static class PlayMonitorClient implements IBinder.DeathRecipient {
+    private static final class PlayMonitorClient implements IBinder.DeathRecipient {
 
         // can afford to be static because only one PlaybackActivityMonitor ever instantiated
         static PlaybackActivityMonitor sListenerDeathMonitor;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9f693df..1e7d076 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3648,7 +3648,7 @@
             if (DBG) Slog.v(TAG, "Interrupting!");
 
             Uri soundUri = record.getSound();
-            hasValidSound = (soundUri != null);
+            hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
             long[] vibration = record.getVibration();
             // Demote sound to vibration if vibration missing & phone in vibration mode.
             if (vibration == null
@@ -3659,10 +3659,7 @@
             }
             hasValidVibrate = vibration != null;
 
-            // We can alert, and we're allowed to alert, but if the developer asked us to only do
-            // it once, and we already have, then don't.
-            if (!(record.isUpdate
-                    && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
+            if (!shouldMuteNotificationLocked(record)) {
 
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
                 if (hasValidSound) {
@@ -3716,6 +3713,24 @@
         }
     }
 
+    boolean shouldMuteNotificationLocked(final NotificationRecord record) {
+        final Notification notification = record.getNotification();
+        if(record.isUpdate
+                && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
+            return true;
+        }
+        if (record.sbn.isGroup()) {
+            if (notification.isGroupSummary()
+                    && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_CHILDREN) {
+                return true;
+            } else if (notification.isGroupChild()
+                    && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_SUMMARY) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private boolean playSound(final NotificationRecord record, Uri soundUri) {
         boolean looping = (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0;
         // do not play notifications if there is a user of exclusive audio focus
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 221b2bb..32de316 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -561,7 +561,7 @@
             updateConfig();
             return;
         }
-        if (channel.getImportance() < NotificationManager.IMPORTANCE_NONE
+        if (channel.getImportance() < NotificationManager.IMPORTANCE_MIN
                 || channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
             throw new IllegalArgumentException("Invalid importance level");
         }
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index a8bb809..46be232 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -20,6 +20,7 @@
 import android.os.Binder;
 import android.os.ISchedulingPolicyService;
 import android.os.Process;
+import android.util.Log;
 
 /**
  * The implementation of the scheduling policy service interface.
@@ -50,16 +51,24 @@
         // since if not the case then the getThreadGroupLeader() test will also fail.
         if (!isPermitted() || prio < PRIORITY_MIN ||
                 prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
-            return PackageManager.PERMISSION_DENIED;
+           return PackageManager.PERMISSION_DENIED;
+        }
+        if (Binder.getCallingUid() != Process.BLUETOOTH_UID) {
+            try {
+                // make good use of our CAP_SYS_NICE capability
+                Process.setThreadGroup(tid, !isForApp ?
+                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
+            } catch (RuntimeException e) {
+                Log.e(TAG, "Failed setThreadGroup: " + e);
+                return PackageManager.PERMISSION_DENIED;
+           }
         }
         try {
-            // make good use of our CAP_SYS_NICE capability
-            Process.setThreadGroup(tid, !isForApp ?
-                    Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
             // must be in this order or it fails the schedulability constraint
             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK,
-                prio);
+                                       prio);
         } catch (RuntimeException e) {
+            Log.e(TAG, "Failed setThreadScheduler: " + e);
             return PackageManager.PERMISSION_DENIED;
         }
         return PackageManager.PERMISSION_GRANTED;
@@ -74,6 +83,7 @@
         switch (Binder.getCallingUid()) {
         case Process.AUDIOSERVER_UID: // fastcapture, fastmixer
         case Process.CAMERASERVER_UID: // camera high frame rate recording
+        case Process.BLUETOOTH_UID: // Bluetooth audio playback
             return true;
         default:
             return false;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d0a28f9..4aa19ee 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7683,6 +7683,7 @@
                 }
                 // instant application; filter out non-exposed provider
                 if (instantAppPkgName != null
+                        && !isInstantApp
                         && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
                     return null;
                 }
@@ -14117,9 +14118,6 @@
         synchronized (mPackages) {
             boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
             if (packageName != null) {
-                result |= updateIntentVerificationStatus(packageName,
-                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
-                        userId);
                 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
                         packageName, userId);
             }
@@ -18588,6 +18586,7 @@
             destroyAppDataLIF(pkg, userId,
                     StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
             destroyAppProfilesLIF(pkg, userId);
+            clearDefaultBrowserIfNeededForUser(ps.name, userId);
             removeKeystoreDataIfNeeded(nextUserId, ps.appId);
             schedulePackageCleaning(ps.name, nextUserId, false);
             synchronized (mPackages) {
@@ -19309,12 +19308,18 @@
         }
     }
 
+    /** Clears state for all users, and touches intent filter verification policy */
     void clearDefaultBrowserIfNeeded(String packageName) {
         for (int oneUserId : sUserManager.getUserIds()) {
-            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
-            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
+            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
+        }
+    }
+
+    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
+        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
             if (packageName.equals(defaultBrowserPackageName)) {
-                setDefaultBrowserPackageName(null, oneUserId);
+                setDefaultBrowserPackageName(null, userId);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 554deae..cea031e 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1386,7 +1386,11 @@
         if (userId == UserHandle.USER_ALL) {
             return false;
         }
-        mDefaultBrowserApp.put(userId, packageName);
+        if (packageName != null) {
+            mDefaultBrowserApp.put(userId, packageName);
+        } else {
+            mDefaultBrowserApp.remove(userId);
+        }
         writePackageRestrictionsLPr(userId);
         return true;
     }
diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
index 364bf28..ebb9450 100644
--- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
@@ -193,6 +193,7 @@
                 0
                         | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                         | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 ,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
index ee615fd..d7cdf08 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/vr/CompatibilityDisplay.java
@@ -3,6 +3,7 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import android.app.ActivityManagerInternal;
+import android.app.CompatibilityDisplayProperties;
 import android.app.Service;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -35,9 +36,9 @@
     private final static boolean DEBUG = false;
 
     // TODO: Go over these values and figure out what is best
-    private final static int HEIGHT = 1800;
-    private final static int WIDTH = 1400;
-    private final static int DPI = 320;
+    private int mVirtualDisplayHeight;
+    private int mVirtualDisplayWidth;
+    private int mVirtualDisplayDpi;
     private final static int STOP_VIRTUAL_DISPLAY_DELAY_MILLIS = 2000;
 
     private final static String DEBUG_ACTION_SET_MODE =
@@ -49,6 +50,28 @@
     private final static String DEBUG_EXTRA_SURFACE =
             "com.android.server.vr.CompatibilityDisplay.EXTRA_SURFACE";
 
+    /**
+     * The default width of the VR virtual display
+     */
+    public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400;
+
+    /**
+     * The default height of the VR virtual display
+     */
+    public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800;
+
+    /**
+     * The default height of the VR virtual dpi.
+     */
+    public static final int DEFAULT_VR_DISPLAY_DPI = 320;
+
+    /**
+     * The minimum height, width and dpi of VR virtual display.
+     */
+    public static final int MIN_VR_DISPLAY_WIDTH = 1;
+    public static final int MIN_VR_DISPLAY_HEIGHT = 1;
+    public static final int MIN_VR_DISPLAY_DPI = 1;
+
     private final ActivityManagerInternal mActivityManagerInternal;
     private final DisplayManager mDisplayManager;
     private final IVrManager mVrManager;
@@ -81,6 +104,9 @@
         mDisplayManager = displayManager;
         mActivityManagerInternal = activityManagerInternal;
         mVrManager = vrManager;
+        mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH;
+        mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT;
+        mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI;
     }
 
     /**
@@ -107,7 +133,6 @@
             // TODO: STOPSHIP Remove createVirtualDisplay conditional before launching.
             if (createVirtualDisplay) {
                 startVirtualDisplay();
-                startImageReader();
             }
         } else {
             // Stop virtual display to test exit condition
@@ -165,6 +190,47 @@
     }
 
     /**
+     * Sets the resolution and DPI of the compatibility virtual display used to display
+     * 2D applications in VR mode.
+     *
+     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+     *
+     * @param compatDisplayProperties Properties of the virtual display for 2D applications
+     * in VR mode.
+     */
+    public void setVirtualDisplayProperties(CompatibilityDisplayProperties compatDisplayProperties) {
+        synchronized(mVdLock) {
+            if (DEBUG) {
+                Log.i(TAG, "VD setVirtualDisplayProperties: res = " +
+                        compatDisplayProperties.getWidth() + "X" + compatDisplayProperties.getHeight() +
+                        ", dpi = " + compatDisplayProperties.getDpi());
+            }
+
+            if (compatDisplayProperties.getWidth() < MIN_VR_DISPLAY_WIDTH ||
+                compatDisplayProperties.getHeight() < MIN_VR_DISPLAY_HEIGHT ||
+                compatDisplayProperties.getDpi() < MIN_VR_DISPLAY_DPI) {
+                throw new IllegalArgumentException (
+                        "Illegal argument: height, width, dpi cannot be negative. res = " +
+                        compatDisplayProperties.getWidth() + "X" + compatDisplayProperties.getHeight() +
+                        ", dpi = " + compatDisplayProperties.getDpi());
+            }
+
+            mVirtualDisplayWidth = compatDisplayProperties.getWidth();
+            mVirtualDisplayHeight = compatDisplayProperties.getHeight();
+            mVirtualDisplayDpi = compatDisplayProperties.getDpi();
+
+            if (mVirtualDisplay != null) {
+                mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
+                    mVirtualDisplayDpi);
+                ImageReader oldImageReader = mImageReader;
+                mImageReader = null;
+                startImageReader();
+                oldImageReader.close();
+            }
+        }
+    }
+
+    /**
      * Returns the virtual display ID if one currently exists, otherwise returns
      * {@link INVALID_DISPLAY_ID}.
      *
@@ -175,7 +241,7 @@
             if (mVirtualDisplay != null) {
                 int virtualDisplayId = mVirtualDisplay.getDisplay().getDisplayId();
                 if (DEBUG) {
-                    Log.e(TAG, "VD id: " + virtualDisplayId);
+                    Log.i(TAG, "VD id: " + virtualDisplayId);
                 }
                 return virtualDisplayId;
             }
@@ -202,12 +268,15 @@
                 return;
             }
 
-            mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display", WIDTH, HEIGHT,
-                    DPI, null /* Surface */, 0 /* flags */);
+            mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display",
+                    mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
+                    null /* Surface */, 0 /* flags */);
 
             if (mVirtualDisplay != null) {
                 mActivityManagerInternal.setVrCompatibilityDisplayId(
                     mVirtualDisplay.getDisplay().getDisplayId());
+                // Now create the ImageReader to supply a Surface to the new virtual display.
+                startImageReader();
             } else {
                 Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
                 mActivityManagerInternal.setVrCompatibilityDisplayId(INVALID_DISPLAY);
@@ -215,9 +284,7 @@
             }
         }
 
-        if (DEBUG) {
-            Log.d(TAG, "VD created: " + mVirtualDisplay);
-        }
+        Log.i(TAG, "VD created: " + mVirtualDisplay);
     }
 
     /**
@@ -241,6 +308,7 @@
                                 mVirtualDisplay.release();
                                 mVirtualDisplay = null;
                             }
+                            stopImageReader();
                         }
                     }
                }
@@ -279,11 +347,23 @@
      */
     private void startImageReader() {
         if (mImageReader == null) {
-            mImageReader = ImageReader.newInstance(WIDTH, HEIGHT, PixelFormat.RGBA_8888,
-                2 /* maxImages */);
+            mImageReader = ImageReader.newInstance(mVirtualDisplayWidth, mVirtualDisplayHeight,
+                PixelFormat.RGBA_8888, 2 /* maxImages */);
+            Log.i(TAG, "VD startImageReader: res = " + mVirtualDisplayWidth + "X" +
+                    mVirtualDisplayHeight + ", dpi = " + mVirtualDisplayDpi);
         }
         synchronized (mVdLock) {
             setSurfaceLocked(mImageReader.getSurface());
         }
     }
+
+    /**
+     * Cleans up the ImageReader.
+     */
+    private void stopImageReader() {
+        if (mImageReader != null) {
+            mImageReader.close();
+            mImageReader = null;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 358861d..63c6195 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -16,6 +16,7 @@
 package com.android.server.vr;
 
 import android.annotation.NonNull;
+import android.app.CompatibilityDisplayProperties;
 import android.content.ComponentName;
 import android.service.vr.IPersistentVrStateCallbacks;
 
@@ -82,6 +83,18 @@
     public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
 
     /**
+     * Sets the resolution and DPI of the compatibility virtual display used to display
+     * 2D applications in VR mode.
+     *
+     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+     *
+     * @param compatDisplayProp Properties of the virtual display for 2D applications
+     * in VR mode.
+     */
+    public abstract void setCompatibilityDisplayProperties(
+            CompatibilityDisplayProperties compatDisplayProp);
+
+    /**
      * Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
      * remain in VR mode even if the foreground does not specify Vr mode being enabled. Mainly used
      * by VR viewers to indicate that a device is placed in a VR viewer.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index cc08918..860b241 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -21,6 +21,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
+import android.app.CompatibilityDisplayProperties;
 import android.app.NotificationManager;
 import android.annotation.NonNull;
 import android.content.ComponentName;
@@ -427,6 +428,13 @@
         }
 
         @Override
+        public void setCompatibilityDisplayProperties(
+                CompatibilityDisplayProperties compatDisplayProp) {
+            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
+            VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+        }
+
+        @Override
         public int getCompatibilityDisplayId() {
             return VrManagerService.this.getCompatibilityDisplayId();
         }
@@ -541,6 +549,12 @@
         }
 
         @Override
+        public void setCompatibilityDisplayProperties(
+            CompatibilityDisplayProperties compatDisplayProp) {
+            VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+        }
+
+        @Override
         public int getCompatibilityDisplayId() {
             return VrManagerService.this.getCompatibilityDisplayId();
         }
@@ -642,16 +656,12 @@
                     false, mOverlayToken, null, oldUserId);
         }
 
-        if (!mVrModeEnabled) {
-            return;
-        }
-
         // Apply the restrictions for the current user based on vr state
         String[] exemptions = (exemptedPackage == null) ? new String[0] :
                 new String[] { exemptedPackage };
 
         appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
-                true, mOverlayToken, exemptions, newUserId);
+                mVrModeEnabled, mOverlayToken, exemptions, newUserId);
     }
 
     private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
@@ -1106,6 +1116,15 @@
         }
     }
 
+    public void setCompatibilityDisplayProperties(
+        CompatibilityDisplayProperties compatDisplayProp) {
+        if (mCompatibilityDisplay != null) {
+            mCompatibilityDisplay.setVirtualDisplayProperties(compatDisplayProp);
+            return;
+        }
+        Slog.w(TAG, "CompatibilityDisplay is null!");
+    }
+
     private int getCompatibilityDisplayId() {
         if (mCompatibilityDisplay != null) {
             return mCompatibilityDisplay.getVirtualDisplayId();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 292734d..c625cbe 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -323,7 +323,7 @@
         }
     }
 
-    public void setVisibility(boolean visible) {
+    public void setVisibility(boolean visible, boolean deferHidingClient) {
         synchronized(mWindowMap) {
             if (mContainer == null) {
                 Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
@@ -342,6 +342,7 @@
             mService.mClosingApps.remove(wtoken);
             wtoken.waitingToShow = false;
             wtoken.hiddenRequested = !visible;
+            wtoken.mDeferHidingClient = deferHidingClient;
 
             if (!visible) {
                 // If the app is dead while it was visible, we kept its dead window on screen.
@@ -368,15 +369,12 @@
                         wtoken.waitingToShow = true;
                     }
 
-                    if (wtoken.clientHidden) {
-                        // In the case where we are making an app visible
-                        // but holding off for a transition, we still need
-                        // to tell the client to make its windows visible so
-                        // they get drawn.  Otherwise, we will wait on
-                        // performing the transition until all windows have
-                        // been drawn, they never will be, and we are sad.
-                        wtoken.clientHidden = false;
-                        wtoken.sendAppVisibilityToClients();
+                    if (wtoken.isClientHidden()) {
+                        // In the case where we are making an app visible but holding off for a
+                        // transition, we still need to tell the client to make its windows visible
+                        // so they get drawn. Otherwise, we will wait on performing the transition
+                        // until all windows have been drawn, they never will be, and we are sad.
+                        wtoken.setClientHidden(false);
                     }
                 }
                 wtoken.requestUpdateWallpaperIfNeeded();
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 936739b..3c2dfa5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -129,7 +129,11 @@
     boolean hiddenRequested;
 
     // Have we told the window clients to hide themselves?
-    boolean clientHidden;
+    private boolean mClientHidden;
+
+    // If true we will defer setting mClientHidden to true and reporting to the client that it is
+    // hidden.
+    boolean mDeferHidingClient;
 
     // Last visibility state we reported to the app token.
     boolean reportedVisible;
@@ -178,6 +182,8 @@
 
     private boolean mDisbalePreviewScreenshots;
 
+    Task mLastParent;
+
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
             boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -310,16 +316,25 @@
         }
     }
 
+    boolean isClientHidden() {
+        return mClientHidden;
+    }
+
+    void setClientHidden(boolean hideClient) {
+        if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
+            return;
+        }
+        mClientHidden = hideClient;
+        sendAppVisibilityToClients();
+    }
+
     boolean setVisibility(WindowManager.LayoutParams lp,
             boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
 
         boolean delayed = false;
         inPendingTransaction = false;
 
-        if (clientHidden == visible) {
-            clientHidden = !visible;
-            sendAppVisibilityToClients();
-        }
+        setClientHidden(!visible);
 
         // Allow for state changes and animation to be applied if:
         // * token is transitioning visibility state
@@ -743,19 +758,21 @@
     void onParentSet() {
         super.onParentSet();
 
+        final Task task = getTask();
+
         // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
         // access visual elements like the {@link DisplayContent}. We must remove any associations
         // such as animations.
         if (!mReparenting) {
-            final Task task = getTask();
             if (task == null) {
                 // It is possible we have been marked as a closing app earlier. We must remove ourselves
                 // from this list so we do not participate in any future animations.
                 mService.mClosingApps.remove(this);
-            } else if (task.mStack != null) {
+            } else if (mLastParent != null && mLastParent.mStack != null) {
                 task.mStack.mExitingAppTokens.remove(this);
             }
         }
+        mLastParent = task;
     }
 
     void postWindowRemoveStartingWindowCleanup(WindowState win) {
@@ -1161,10 +1178,7 @@
                 hidden = false;
                 hiddenRequested = false;
             }
-            if (clientHidden != fromToken.clientHidden) {
-                clientHidden = fromToken.clientHidden;
-                sendAppVisibilityToClients();
-            }
+            setClientHidden(fromToken.mClientHidden);
             fromToken.mAppAnimator.transferCurrentAnimation(
                     mAppAnimator, tStartingWindow.mWinAnimator);
 
@@ -1529,10 +1543,9 @@
         pw.print(prefix); pw.print("task="); pw.println(getTask());
         pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
                 pw.print(" mOrientation="); pw.println(mOrientation);
-        pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
-                pw.print(" clientHidden="); pw.print(clientHidden);
-                pw.print(" reportedDrawn="); pw.print(reportedDrawn);
-                pw.print(" reportedVisible="); pw.println(reportedVisible);
+        pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
+            + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
+            + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
         if (paused) {
             pw.print(prefix); pw.print("paused="); pw.println(paused);
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1823610..e2f313a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2245,7 +2245,7 @@
                 wsa.destroySurface();
                 mService.mForceRemoves.add(w);
                 mTmpWindow = w;
-            } else if (w.mAppToken != null && w.mAppToken.clientHidden) {
+            } else if (w.mAppToken != null && w.mAppToken.isClientHidden()) {
                 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
                         + w + " surface=" + wsa.mSurfaceController
                         + " token=" + w.mAppToken
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a1b1cd0..60b136f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -674,7 +674,7 @@
                 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
                     wallpaperDestroyed = true;
                 }
-                win.destroyOrSaveSurface();
+                win.destroyOrSaveSurfaceUnchecked();
             } while (i > 0);
             mService.mDestroySurface.clear();
         }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4262d12..bc749e1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -439,7 +439,7 @@
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken token = mChildren.get(i);
             // skip hidden (or about to hide) apps
-            if (token.mIsExiting || token.clientHidden || token.hiddenRequested) {
+            if (token.mIsExiting || token.isClientHidden() || token.hiddenRequested) {
                 continue;
             }
             final WindowState win = token.findMainWindow();
@@ -607,7 +607,7 @@
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final AppWindowToken token = mChildren.get(i);
             // skip hidden (or about to hide) apps
-            if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) {
+            if (!token.mIsExiting && !token.isClientHidden() && !token.hiddenRequested) {
                 return token;
             }
         }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 1feb743..da7a9f0 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -733,10 +733,17 @@
         outTempTaskBounds.setEmpty();
 
         // When the home stack is resizable, should always have the same stack and task bounds
-        if (mStackId == HOME_STACK_ID && findHomeTask().isResizeable()) {
-            // Calculate the home stack bounds when in docked mode
-            getDisplayContent().mDividerControllerLocked
-                    .getHomeStackBoundsInDockedMode(outStackBounds);
+        if (mStackId == HOME_STACK_ID) {
+            if (findHomeTask().isResizeable()) {
+                // Calculate the home stack bounds when in docked mode and the home stack is
+                // resizeable.
+                getDisplayContent().mDividerControllerLocked
+                        .getHomeStackBoundsInDockedMode(outStackBounds);
+            } else {
+                // Home stack isn't resizeable, so don't specify stack bounds.
+                outStackBounds.setEmpty();
+            }
+
             outTempTaskBounds.set(outStackBounds);
             return;
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2a01aa2..6cde53a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1470,7 +1470,7 @@
             if (mInTouchMode) {
                 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
             }
-            if (win.mAppToken == null || !win.mAppToken.clientHidden) {
+            if (win.mAppToken == null || !win.mAppToken.isClientHidden()) {
                 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
             }
 
@@ -1950,7 +1950,7 @@
             }
             if (viewVisibility == View.VISIBLE &&
                     (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
-                            || !win.mAppToken.clientHidden)) {
+                            || !win.mAppToken.isClientHidden())) {
                 result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
                         oldVisibility);
                 try {
@@ -2141,7 +2141,12 @@
             if (mInputMethodWindow == win) {
                 setInputMethodWindowLocked(null);
             }
-            win.destroyOrSaveSurface();
+            boolean stopped = win.mAppToken != null ? win.mAppToken.mAppStopped : false;
+            // We set mDestroying=true so AppWindowToken#notifyAppStopped in-to destroy surfaces
+            // will later actually destroy the surface if we do not do so here. Normally we leave
+            // this to the exit animation.
+            win.mDestroying = true;
+            win.destroySurface(false, stopped);
         }
         // TODO(multidisplay): Magnification is supported only for the default display.
         if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b9776a3..67516c1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1399,7 +1399,7 @@
      * @return true if the window should be considered while evaluating allDrawn flags.
      */
     boolean mightAffectAllDrawn(boolean visibleOnly) {
-        final boolean isViewVisible = (mAppToken == null || !mAppToken.clientHidden)
+        final boolean isViewVisible = (mAppToken == null || !mAppToken.isClientHidden())
                 && (mViewVisibility == View.VISIBLE) && !mWindowRemovalAllowed;
         return (isOnScreen() && (!visibleOnly || isViewVisible)
                 || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION
@@ -2312,7 +2312,7 @@
      * interacts with it.
      */
     boolean shouldKeepVisibleDeadAppWindow() {
-        if (!isWinVisibleLw() || mAppToken == null || mAppToken.clientHidden) {
+        if (!isWinVisibleLw() || mAppToken == null || mAppToken.isClientHidden()) {
             // Not a visible app window or the app isn't dead.
             return false;
         }
@@ -2570,12 +2570,24 @@
     void sendAppVisibilityToClients() {
         super.sendAppVisibilityToClients();
 
-        final boolean clientHidden = mAppToken.clientHidden;
+        final boolean clientHidden = mAppToken.isClientHidden();
         if (mAttrs.type == TYPE_APPLICATION_STARTING && clientHidden) {
             // Don't hide the starting window.
             return;
         }
 
+        if (clientHidden) {
+            // Once we are notifying the client that it's visibility has changed, we need to prevent
+            // it from destroying child surfaces until the animation has finished. We do this by
+            // detaching any surface control the client added from the client.
+            for (int i = mChildren.size() - 1; i >= 0; --i) {
+                final WindowState c = mChildren.get(i);
+                c.mWinAnimator.detachChildren();
+            }
+
+            mWinAnimator.detachChildren();
+        }
+
         try {
             if (DEBUG_VISIBILITY) Slog.v(TAG,
                     "Setting visibility of " + this + ": " + (!clientHidden));
@@ -2698,7 +2710,7 @@
                     + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed
                     + " win.mRemoveOnExit=" + mRemoveOnExit);
             if (!cleanupOnResume || mRemoveOnExit) {
-                destroyOrSaveSurface();
+                destroyOrSaveSurfaceUnchecked();
             }
             if (mRemoveOnExit) {
                 removeImmediately();
@@ -2713,7 +2725,10 @@
         return destroyedSomething;
     }
 
-    void destroyOrSaveSurface() {
+    // Destroy or save the application surface without checking
+    // various indicators of whether the client has released the surface.
+    // This is in general unsafe, and most callers should use {@link #destroySurface}
+    void destroyOrSaveSurfaceUnchecked() {
         mSurfaceSaved = shouldSaveSurface();
         if (mSurfaceSaved) {
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index b945cf1..2236b59 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -341,7 +341,7 @@
             mAnimation.cancel();
             mAnimation = null;
             mLocalAnimating = false;
-            mWin.destroyOrSaveSurface();
+            mWin.destroyOrSaveSurfaceUnchecked();
         }
     }
 
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index d383aea..d4904f5 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -15,6 +15,11 @@
  */
 package com.android.server.notification;
 
+import static android.app.Notification.GROUP_ALERT_ALL;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
@@ -186,19 +191,26 @@
     private NotificationRecord getCustomLightsNotification() {
         return getNotificationRecord(mId, false /* insistent */, true /* once */,
                 false /* noisy */, true /* buzzy*/, true /* lights */,
-                true /* defaultVibration */, true /* defaultSound */, false /* defaultLights */);
+                true /* defaultVibration */, true /* defaultSound */, false /* defaultLights */,
+                null, Notification.GROUP_ALERT_ALL);
     }
 
     private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
             boolean noisy, boolean buzzy, boolean lights) {
-        return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true, true);
+        return getNotificationRecord(id, insistent, once, noisy, buzzy, lights, true, true, true,
+                null, Notification.GROUP_ALERT_ALL);
+    }
+
+    private NotificationRecord getBeepyNotificationRecord(String groupKey, int groupAlertBehavior) {
+        return getNotificationRecord(mId, false, false, true, false, false, true, true, true,
+                groupKey, groupAlertBehavior);
     }
 
     private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
             boolean noisy, boolean buzzy, boolean lights, boolean defaultVibration,
-            boolean defaultSound, boolean defaultLights) {
+            boolean defaultSound, boolean defaultLights, String groupKey, int groupAlertBehavior) {
         NotificationChannel channel =
-                new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_HIGH);
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH);
         final Builder builder = new Builder(getContext())
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -237,6 +249,9 @@
         }
         builder.setDefaults(defaults);
 
+        builder.setGroup(groupKey);
+        builder.setGroupAlertBehavior(groupAlertBehavior);
+
         Notification n = builder.build();
         if (insistent) {
             n.flags |= Notification.FLAG_INSISTENT;
@@ -544,7 +559,7 @@
     }
 
     @Test
-    public void testInsistenteVibrate() throws Exception {
+    public void testInsistentVibrate() throws Exception {
         NotificationRecord r = getInsistentBuzzyNotification();
 
         mService.buzzBeepBlinkLocked(r);
@@ -566,6 +581,71 @@
     }
 
     @Test
+    public void testGroupAlertSummarySilenceChild() throws Exception {
+        NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
+
+        mService.buzzBeepBlinkLocked(child);
+
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testGroupAlertSummaryNoSilenceSummary() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_SUMMARY);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mService.buzzBeepBlinkLocked(summary);
+
+        verifyBeepLooped();
+    }
+
+    @Test
+    public void testGroupAlertSummaryNoSilenceNonGroupChild() throws Exception {
+        NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_SUMMARY);
+
+        mService.buzzBeepBlinkLocked(nonGroup);
+
+        verifyBeepLooped();
+    }
+
+    @Test
+    public void testGroupAlertChildSilenceSummary() throws Exception {
+        NotificationRecord summary = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+        summary.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
+
+        mService.buzzBeepBlinkLocked(summary);
+
+        verifyNeverBeep();
+    }
+
+    @Test
+    public void testGroupAlertChildNoSilenceChild() throws Exception {
+        NotificationRecord child = getBeepyNotificationRecord("a", GROUP_ALERT_CHILDREN);
+
+        mService.buzzBeepBlinkLocked(child);
+
+        verifyBeepLooped();
+    }
+
+    @Test
+    public void testGroupAlertChildNoSilenceNonGroupSummary() throws Exception {
+        NotificationRecord nonGroup = getBeepyNotificationRecord(null, GROUP_ALERT_CHILDREN);
+
+        mService.buzzBeepBlinkLocked(nonGroup);
+
+        verifyBeepLooped();
+    }
+
+    @Test
+    public void testGroupAlertAllNoSilenceGroup() throws Exception {
+        NotificationRecord group = getBeepyNotificationRecord("a", GROUP_ALERT_ALL);
+
+        mService.buzzBeepBlinkLocked(group);
+
+        verifyBeepLooped();
+    }
+
+    @Test
     public void testHonorAlertOnlyOnceForBuzz() throws Exception {
         NotificationRecord r = getBuzzyNotification();
         NotificationRecord s = getBuzzyOnceNotification();
@@ -680,6 +760,23 @@
         verifyStopVibrate();
     }
 
+    @Test
+    public void testEmptyUriSoundTreatedAsNoSound() throws Exception {
+        NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, null);
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+        mService.addNotification(r);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 92534a1..d057eb5 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -53,9 +53,10 @@
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
-import android.support.test.annotation.UiThreadTest;
 import android.support.test.InstrumentationRegistry;
+import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -63,6 +64,7 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -70,6 +72,8 @@
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 public class NotificationManagerServiceTest {
     private static final long WAIT_FOR_IDLE_TIMEOUT = 2;
     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
@@ -109,7 +113,6 @@
     }
 
     @Before
-    @UiThreadTest
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mNotificationManagerService = new TestableNotificationManagerService(mContext);
@@ -124,7 +127,7 @@
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
         // Use this testable looper.
-        mTestableLooper = new TestableLooper(false);
+        mTestableLooper = TestableLooper.get(this);
 
         mListener = mNotificationListeners.new ManagedServiceInfo(
                 null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
@@ -165,7 +168,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
@@ -177,7 +179,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
         try {
             mBinderService.createNotificationChannels("test_pkg",
@@ -189,7 +190,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateNotificationChannels_TwoChannels() throws Exception {
         final NotificationChannel channel1 =
                 new NotificationChannel("id1", "name", NotificationManager.IMPORTANCE_DEFAULT);
@@ -202,7 +202,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateNotificationChannels_SecondCreateDoesNotChangeImportance()
             throws Exception {
         final NotificationChannel channel =
@@ -221,7 +220,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateNotificationChannels_IdenticalChannelsInListIgnoresSecond()
             throws Exception {
         final NotificationChannel channel1 =
@@ -236,7 +234,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testBlockedNotifications_suspended() throws Exception {
         NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
@@ -249,7 +246,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testBlockedNotifications_blockedChannel() throws Exception {
         NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
@@ -263,7 +259,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testBlockedNotifications_blockedApp() throws Exception {
         NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
         when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
@@ -277,7 +272,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
@@ -288,7 +282,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
@@ -300,7 +293,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
@@ -315,7 +307,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -328,7 +319,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -341,7 +331,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -355,7 +344,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -369,7 +357,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -382,7 +369,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
@@ -396,7 +382,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -411,7 +396,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testTvExtenderChannelOverride_onTv() throws Exception {
         mNotificationManagerService.setIsTelevision(true);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
@@ -427,7 +411,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testTvExtenderChannelOverride_notOnTv() throws Exception {
         mNotificationManagerService.setIsTelevision(false);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
@@ -443,7 +426,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -469,7 +451,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCreateChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -490,7 +471,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testUpdateChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -509,7 +489,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testDeleteChannelNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -526,7 +505,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testDeleteChannelGroupNotifyListener() throws Exception {
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -543,7 +521,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -561,7 +538,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -583,7 +559,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -609,7 +584,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -624,7 +598,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -643,7 +616,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -666,7 +638,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -680,7 +651,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -698,7 +668,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
@@ -719,7 +688,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testHasCompanionDevice_failure() throws Exception {
         when(mCompanionMgr.getAssociations(anyString(), anyInt())).thenThrow(
                 new IllegalArgumentException());
@@ -727,7 +695,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testHasCompanionDevice_noService() throws Exception {
         mNotificationManagerService = new TestableNotificationManagerService(mContext);
 
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 303054e..bc5c29d 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -18,6 +18,7 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
 
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
@@ -504,12 +505,23 @@
 
     @Test
     public void testCreateChannel_blocked() throws Exception {
-        mHelper.setImportance(PKG, UID, NotificationManager.IMPORTANCE_NONE);
+        mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
 
         mHelper.createNotificationChannel(PKG, UID,
                 new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
     }
 
+    @Test
+    public void testCreateChannel_ImportanceNone() throws Exception {
+        try {
+            mHelper.createNotificationChannel(PKG, UID,
+                    new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true);
+            fail("Was allowed to create a blocked channel");
+        } catch (IllegalArgumentException e) {
+            // yay
+        }
+    }
+
 
     @Test
     public void testUpdate() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 985e5ea..c78488f 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -16,25 +16,18 @@
 
 package com.android.server;
 
-import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
-import static android.net.NetworkRecommendationProvider.EXTRA_SEQUENCE;
 import static android.net.NetworkScoreManager.CACHE_FILTER_NONE;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertSame;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -55,8 +48,6 @@
 import android.net.NetworkKey;
 import android.net.NetworkScoreManager;
 import android.net.NetworkScorerAppData;
-import android.net.RecommendationRequest;
-import android.net.RecommendationResult;
 import android.net.ScoredNetwork;
 import android.net.Uri;
 import android.net.WifiKey;
@@ -69,13 +60,11 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -145,9 +134,6 @@
 
     private ContentResolver mContentResolver;
     private NetworkScoreService mNetworkScoreService;
-    private RecommendationRequest mRecommendationRequest;
-    private RemoteCallback mRemoteCallback;
-    private OnResultListener mOnResultListener;
     private HandlerThread mHandlerThread;
     private List<ScanResult> mScanResults;
 
@@ -177,13 +163,6 @@
         WifiConfiguration configuration = new WifiConfiguration();
         configuration.SSID = "NetworkScoreServiceTest_SSID";
         configuration.BSSID = "NetworkScoreServiceTest_BSSID";
-        mRecommendationRequest = new RecommendationRequest.Builder()
-            .setDefaultWifiConfig(configuration).build();
-        mOnResultListener = new OnResultListener();
-        mRemoteCallback = new RemoteCallback(mOnResultListener);
-        Settings.Global.putLong(mContentResolver,
-                Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, -1L);
-        mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
         populateScanResults();
     }
 
@@ -215,7 +194,6 @@
         verify(mNetworkScorerAppManager).updateState();
         verify(mNetworkScorerAppManager).migrateNetworkScorerAppSettingIfNeeded();
         verify(mServiceConnection).bind(mContext);
-
     }
 
     @Test
@@ -256,160 +234,6 @@
     }
 
     @Test
-    public void testRequestRecommendation_noPermission() throws Exception {
-        doThrow(new SecurityException()).when(mContext)
-            .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
-                anyString());
-        try {
-            mNetworkScoreService.requestRecommendation(mRecommendationRequest);
-            fail("REQUEST_NETWORK_SCORES not enforced.");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testRequestRecommendation_mainThread() throws Exception {
-        when(mContext.getMainLooper()).thenReturn(Looper.myLooper());
-        try {
-            mNetworkScoreService.requestRecommendation(mRecommendationRequest);
-            fail("requestRecommendation run on main thread.");
-        } catch (RuntimeException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testRequestRecommendation_providerNotConnected() throws Exception {
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-
-        final RecommendationResult result =
-                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
-        assertNotNull(result);
-        assertEquals(mRecommendationRequest.getDefaultWifiConfig(),
-                result.getWifiConfiguration());
-    }
-
-    @Test
-    public void testRequestRecommendation_providerThrowsRemoteException() throws Exception {
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-        doThrow(new RemoteException()).when(mRecommendationProvider)
-                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
-                        anyInt());
-        mNetworkScoreService.onUserUnlocked(0);
-
-        final RecommendationResult result =
-                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
-        assertNotNull(result);
-        assertEquals(mRecommendationRequest.getDefaultWifiConfig(),
-                result.getWifiConfiguration());
-    }
-
-    @Test
-    public void testRequestRecommendation_resultReturned() throws Exception {
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-        final WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.SSID = "testRequestRecommendation_resultReturned_SSID";
-        wifiConfiguration.BSSID = "testRequestRecommendation_resultReturned_BSSID";
-        final RecommendationResult providerResult = RecommendationResult
-                .createConnectRecommendation(wifiConfiguration);
-        final Bundle bundle = new Bundle();
-        bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
-        doAnswer(invocation -> {
-            bundle.putInt(EXTRA_SEQUENCE, invocation.getArgument(2));
-            invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
-            return null;
-        }).when(mRecommendationProvider)
-                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
-                        anyInt());
-        mNetworkScoreService.onUserUnlocked(0);
-
-        final RecommendationResult result =
-                mNetworkScoreService.requestRecommendation(mRecommendationRequest);
-        assertNotNull(result);
-        assertEquals(providerResult.getWifiConfiguration().SSID,
-                result.getWifiConfiguration().SSID);
-        assertEquals(providerResult.getWifiConfiguration().BSSID,
-                result.getWifiConfiguration().BSSID);
-    }
-
-    @Test
-    public void testRequestRecommendationAsync_noPermission() throws Exception {
-        doThrow(new SecurityException()).when(mContext)
-                .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
-                        anyString());
-        try {
-            mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
-                    mRemoteCallback);
-            fail("REQUEST_NETWORK_SCORES not enforced.");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void testRequestRecommendationAsync_providerNotConnected() throws Exception {
-        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
-                mRemoteCallback);
-        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
-        assertTrue(callbackRan);
-        verifyZeroInteractions(mRecommendationProvider);
-    }
-
-    @Test
-    public void testRequestRecommendationAsync_requestTimesOut() throws Exception {
-        mNetworkScoreService.onUserUnlocked(0);
-        Settings.Global.putLong(mContentResolver,
-                Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, 1L);
-        mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
-        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
-                mRemoteCallback);
-        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
-        assertTrue(callbackRan);
-        verify(mRecommendationProvider).requestRecommendation(eq(mRecommendationRequest),
-                isA(IRemoteCallback.Stub.class), anyInt());
-
-        assertTrue(mOnResultListener.receivedBundle.containsKey(EXTRA_RECOMMENDATION_RESULT));
-        RecommendationResult result =
-                mOnResultListener.receivedBundle.getParcelable(EXTRA_RECOMMENDATION_RESULT);
-        assertTrue(result.hasRecommendation());
-        assertEquals(mRecommendationRequest.getDefaultWifiConfig().SSID,
-                result.getWifiConfiguration().SSID);
-    }
-
-    @Test
-    public void testRequestRecommendationAsync_requestSucceeds() throws Exception {
-        mNetworkScoreService.onUserUnlocked(0);
-        final Bundle bundle = new Bundle();
-        doAnswer(invocation -> {
-            invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
-            return null;
-        }).when(mRecommendationProvider)
-                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
-                        anyInt());
-
-        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
-                mRemoteCallback);
-        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
-        assertTrue(callbackRan);
-        // If it's not the same instance then something else ran the callback.
-        assertSame(bundle, mOnResultListener.receivedBundle);
-    }
-
-    @Test
-    public void testRequestRecommendationAsync_requestThrowsRemoteException() throws Exception {
-        mNetworkScoreService.onUserUnlocked(0);
-        doThrow(new RemoteException()).when(mRecommendationProvider)
-                .requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
-                        anyInt());
-
-        mNetworkScoreService.requestRecommendationAsync(mRecommendationRequest,
-                mRemoteCallback);
-        boolean callbackRan = mOnResultListener.countDownLatch.await(3, TimeUnit.SECONDS);
-        assertTrue(callbackRan);
-    }
-
-    @Test
     public void dispatchingContentObserver_nullUri() throws Exception {
         NetworkScoreService.DispatchingContentObserver observer =
                 new NetworkScoreService.DispatchingContentObserver(mContext, null /*handler*/);
@@ -435,15 +259,6 @@
     }
 
     @Test
-    public void oneTimeCallback_multipleCallbacks() throws Exception {
-        NetworkScoreService.OneTimeCallback callback =
-                new NetworkScoreService.OneTimeCallback(mRemoteCallback);
-        callback.sendResult(null);
-        callback.sendResult(null);
-        assertEquals(1, mOnResultListener.resultCount);
-    }
-
-    @Test
     public void testUpdateScores_notActiveScorer() {
         bindToScorer(false /*callerIsScorer*/);
 
@@ -1088,19 +903,6 @@
         mNetworkScoreService.onUserUnlocked(0);
     }
 
-    private static class OnResultListener implements RemoteCallback.OnResultListener {
-        private final CountDownLatch countDownLatch = new CountDownLatch(1);
-        private int resultCount;
-        private Bundle receivedBundle;
-
-        @Override
-        public void onResult(Bundle result) {
-            countDownLatch.countDown();
-            resultCount++;
-            receivedBundle = result;
-        }
-    }
-
     private static class CountDownHandler extends Handler {
         CountDownLatch latch = new CountDownLatch(1);
         int receivedWhat;
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 20839c5..36e9b3f8 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.nullable;
 import static org.mockito.Mockito.times;
@@ -80,6 +81,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CyclicBarrier;
@@ -2443,7 +2445,6 @@
     @SmallTest
     public void testGetAccountsByFeaturesError() throws Exception {
         unlockSystemUser();
-
         mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
         mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_ERROR, "p12", null);
 
@@ -2511,28 +2512,37 @@
         updateBroadcastCounters(2);
         assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent
         assertEquals(mLoginAccountsChangedBroadcasts, 2);
-        assertEquals(mAccountRemovedBroadcasts, 0);
     }
 
     @SmallTest
     public void testRegisterAccountListenerWithAddingTwoAccounts() throws Exception {
         unlockSystemUser();
+
+        HashMap<String, Integer> visibility = new HashMap<>();
+        visibility.put(AccountManagerServiceTestFixtures.CALLER_PACKAGE,
+            AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+
         mAms.registerAccountListener(
             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
-            "testpackage"); // opPackageName
-        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
+            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
+        mAms.addAccountExplicitlyWithVisibility(
+            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
         mAms.unregisterAccountListener(
             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
-            "testpackage"); // opPackageName
-        mAms.addAccountExplicitly(
-            AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null);
+            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
+
+        addAccountRemovedReceiver(AccountManagerServiceTestFixtures.CALLER_PACKAGE);
+        mAms.addAccountExplicitlyWithVisibility(
+            AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE, "p11", null, visibility);
 
         updateBroadcastCounters(3);
         assertEquals(mVisibleAccountsChangedBroadcasts, 1);
         assertEquals(mLoginAccountsChangedBroadcasts, 2);
+        assertEquals(mAccountRemovedBroadcasts, 0);
 
         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
-        mAms.registerAccountListener( null /* accountTypes */, "testpackage");
+        mAms.registerAccountListener( null /* accountTypes */,
+            AccountManagerServiceTestFixtures.CALLER_PACKAGE);
         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE);
 
         updateBroadcastCounters(8);
@@ -2544,6 +2554,13 @@
     @SmallTest
     public void testRegisterAccountListenerForThreePackages() throws Exception {
         unlockSystemUser();
+
+        addAccountRemovedReceiver("testpackage1");
+        HashMap<String, Integer> visibility = new HashMap<>();
+        visibility.put("testpackage1", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+        visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+        visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+
         mAms.registerAccountListener(
             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
             "testpackage1"); // opPackageName
@@ -2553,7 +2570,8 @@
         mAms.registerAccountListener(
             new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
             "testpackage3"); // opPackageName
-        mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null);
+        mAms.addAccountExplicitlyWithVisibility(
+            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
         updateBroadcastCounters(4);
         assertEquals(mVisibleAccountsChangedBroadcasts, 3);
         assertEquals(mLoginAccountsChangedBroadcasts, 1);
@@ -2572,13 +2590,47 @@
         mAms.addAccountExplicitly(
             AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null);
 
-        updateBroadcastCounters(9);
+        updateBroadcastCounters(8);
         assertEquals(mVisibleAccountsChangedBroadcasts, 5);
         assertEquals(mLoginAccountsChangedBroadcasts, 3);
         assertEquals(mAccountRemovedBroadcasts, 1);
     }
 
     @SmallTest
+    public void testRegisterAccountListenerForAddingAccountWithVisibility() throws Exception {
+        unlockSystemUser();
+
+        HashMap<String, Integer> visibility = new HashMap<>();
+        visibility.put("testpackage1", AccountManager.VISIBILITY_NOT_VISIBLE);
+        visibility.put("testpackage2", AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE);
+        visibility.put("testpackage3", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+
+        addAccountRemovedReceiver("testpackage1");
+        mAms.registerAccountListener(
+            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
+            "testpackage1"); // opPackageName
+        mAms.registerAccountListener(
+            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
+            "testpackage2"); // opPackageName
+        mAms.registerAccountListener(
+            new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
+            "testpackage3"); // opPackageName
+        mAms.addAccountExplicitlyWithVisibility(
+            AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p11", null, visibility);
+
+        updateBroadcastCounters(2);
+        assertEquals(mVisibleAccountsChangedBroadcasts, 1);
+        assertEquals(mLoginAccountsChangedBroadcasts, 1);
+
+        mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
+
+        updateBroadcastCounters(4);
+        assertEquals(mVisibleAccountsChangedBroadcasts, 2);
+        assertEquals(mLoginAccountsChangedBroadcasts, 2);
+        assertEquals(mAccountRemovedBroadcasts, 0); // account was never visible.
+    }
+
+    @SmallTest
     public void testRegisterAccountListenerCredentialsUpdate() throws Exception {
         unlockSystemUser();
         mAms.registerAccountListener(
@@ -2609,21 +2661,31 @@
         mLoginAccountsChangedBroadcasts = 0;
         mAccountRemovedBroadcasts = 0;
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
-        verify(mMockContext, times(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(),
+        verify(mMockContext, atLeast(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(),
             any(UserHandle.class));
         for (Intent intent : captor.getAllValues()) {
             if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED.equals(intent.getAction())) {
                 mVisibleAccountsChangedBroadcasts++;
-            }
-            if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
+            } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
                 mLoginAccountsChangedBroadcasts++;
-            }
-            if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) {
+            } else if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) {
                 mAccountRemovedBroadcasts++;
             }
         }
     }
 
+    private void addAccountRemovedReceiver(String packageName) {
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = new ActivityInfo();
+        resolveInfo.activityInfo.applicationInfo =  new ApplicationInfo();
+        resolveInfo.activityInfo.applicationInfo.packageName = packageName;
+
+        List<ResolveInfo> accountRemovedReceivers = new ArrayList<>();
+        accountRemovedReceivers.add(resolveInfo);
+        when(mMockPackageManager.queryBroadcastReceiversAsUser(any(Intent.class), anyInt(),
+            anyInt())).thenReturn(accountRemovedReceivers);
+    }
+
     @SmallTest
     public void testConcurrencyReadWrite() throws Exception {
         // Test 2 threads calling getAccounts and 1 thread setAuthToken
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 3f6f8ec..bb453a9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -843,18 +843,20 @@
 
                     updateUsbNotification();
                     updateAdbNotification();
+                    if (mBootCompleted) {
+                        Slog.i(TAG, "update state " + mConnected + " " + mConfigured);
+                        updateUsbStateBroadcastIfNeeded(false);
+                    }
                     if (UsbManager.containsFunction(mCurrentFunctions,
                             UsbManager.USB_FUNCTION_ACCESSORY)) {
                         updateCurrentAccessory();
                     }
                     if (mBootCompleted) {
-                        Slog.i(TAG, "update state " + mConnected + " " + mConfigured);
                         if (!mConnected) {
                             // restore defaults when USB is disconnected
                             Slog.i(TAG, "Disconnect, setting usb functions to null");
                             setEnabledFunctions(null, false, false);
                         }
-                        updateUsbStateBroadcastIfNeeded(false);
                         updateUsbFunctions();
                     } else {
                         mPendingBootBroadcast = true;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 85f84ba..b8e24f0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -45,6 +45,7 @@
 import android.service.carrier.CarrierIdentifier;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
+import android.telephony.VisualVoicemailService.VisualVoicemailTask;
 import android.telephony.ims.feature.ImsFeature;
 import android.util.Log;
 
@@ -322,9 +323,6 @@
      * a String.
      *
      * <p class="note">
-     * Requires the READ_PHONE_STATE permission.
-     *
-     * <p class="note">
      * This was a {@link android.content.Context#sendStickyBroadcast sticky}
      * broadcast in version 1.0, but it is no longer sticky.
      * Instead, use {@link #getCallState} to synchronously query the current call state.
@@ -334,6 +332,7 @@
      * @see #getCallState
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public static final String ACTION_PHONE_STATE_CHANGED =
             "android.intent.action.PHONE_STATE";
 
@@ -877,6 +876,30 @@
     public static final String VVM_TYPE_CVVM = "vvm_type_cvvm";
 
     /**
+     * Key in bundle returned by {@link #getVisualVoicemailPackageName()}, indicating whether visual
+     * voicemail was enabled or disabled by the user. If the user never explicitly changed this
+     * setting, this key will not exist.
+     *
+     * @see #getVisualVoicemailSettings()
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL =
+            "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
+
+    /**
+     * Key in bundle returned by {@link #getVisualVoicemailPackageName()}, indicating the voicemail
+     * access PIN scrambled during the auto provisioning process. The user is expected to reset
+     * their PIN if this value is not {@code null}.
+     *
+     * @see #getVisualVoicemailSettings()
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING =
+            "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+
+    /**
      * @hide
      */
     public static final String USSD_RESPONSE = "USSD_RESPONSE";
@@ -914,10 +937,8 @@
      * Returns the software version number for the device, for example,
      * the IMEI/SV for GSM phones. Return null if the software version is
      * not available.
-     *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getDeviceSoftwareVersion() {
         return getDeviceSoftwareVersion(getSlotIndex());
     }
@@ -927,12 +948,10 @@
      * the IMEI/SV for GSM phones. Return null if the software version is
      * not available.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @param slotIndex of which deviceID is returned
      */
     /** {@hide} */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getDeviceSoftwareVersion(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -950,13 +969,11 @@
      * Returns the unique device ID, for example, the IMEI for GSM and the MEID
      * or ESN for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
      * MEID for CDMA.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getDeviceId() {
         try {
             ITelephony telephony = getITelephony();
@@ -974,15 +991,13 @@
      * Returns the unique device ID of a subscription, for example, the IMEI for
      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @param slotIndex of which deviceID is returned
      *
      * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
      * MEID for CDMA.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getDeviceId(int slotIndex) {
         // FIXME this assumes phoneId == slotIndex
         try {
@@ -1000,10 +1015,8 @@
     /**
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
-     *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getImei() {
         return getImei(getSlotIndex());
     }
@@ -1012,11 +1025,9 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @param slotIndex of which IMEI is returned
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getImei(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -1032,10 +1043,8 @@
 
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
-     *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getMeid() {
         return getMeid(getSlotIndex());
     }
@@ -1043,11 +1052,9 @@
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @param slotIndex of which MEID is returned
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getMeid(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -1103,13 +1110,13 @@
      *<p>
      * @return Current location of the device or null if not available.
      *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}.
-     *
      * @deprecated use {@link #getAllCellInfo} instead, which returns a superset of this API.
      */
     @Deprecated
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.ACCESS_COARSE_LOCATION,
+            android.Manifest.permission.ACCESS_FINE_LOCATION
+    })
     public CellLocation getCellLocation() {
         try {
             ITelephony telephony = getITelephony();
@@ -1141,11 +1148,9 @@
      * Enables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
      * PhoneStateListener.onCellLocationChanged} will be called on location updates.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
-     * CONTROL_LOCATION_UPDATES}
-     *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES)
     public void enableLocationUpdates() {
         enableLocationUpdates(getSubId());
     }
@@ -1155,12 +1160,10 @@
      * {@link PhoneStateListener#onCellLocationChanged
      * PhoneStateListener.onCellLocationChanged} will be called on location updates.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
-     * CONTROL_LOCATION_UPDATES}
-     *
      * @param subId for which the location updates are enabled
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES)
     public void enableLocationUpdates(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -1175,11 +1178,9 @@
      * Disables location update notifications.  {@link PhoneStateListener#onCellLocationChanged
      * PhoneStateListener.onCellLocationChanged} will be called on location updates.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES
-     * CONTROL_LOCATION_UPDATES}
-     *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CONTROL_LOCATION_UPDATES)
     public void disableLocationUpdates() {
         disableLocationUpdates(getSubId());
     }
@@ -1198,15 +1199,13 @@
     /**
      * Returns the neighboring cell information of the device.
      *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
-     *
      * @return List of NeighboringCellInfo or null if info unavailable.
      *
      * @deprecated Use {@link #getAllCellInfo} which returns a superset of the information
      *             from NeighboringCellInfo.
      */
     @Deprecated
+    @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
             ITelephony telephony = getITelephony();
@@ -1562,14 +1561,12 @@
      * invalid subscription ID is pinned to the TelephonyManager, the returned config will contain
      * default values.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
-     * READ_PHONE_STATE}
-     *
      * @see CarrierConfigManager#getConfigForSubId(int)
      * @see #createForSubscriptionId(int)
      * @see #createForPhoneAccountHandle(PhoneAccountHandle)
      */
     @WorkerThread
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public PersistableBundle getCarrierConfig() {
         CarrierConfigManager carrierConfigManager = mContext
                 .getSystemService(CarrierConfigManager.class);
@@ -1729,11 +1726,9 @@
      * @see #NETWORK_TYPE_EHRPD
      * @see #NETWORK_TYPE_HSPAP
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public int getNetworkType(int subId) {
        try {
            ITelephony telephony = getITelephony();
@@ -1759,10 +1754,6 @@
      * If this object has been created with {@link #createForSubscriptionId}, applies to the given
      * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @return the network type
      *
      * @see #NETWORK_TYPE_UNKNOWN
@@ -1782,6 +1773,7 @@
      * @see #NETWORK_TYPE_EHRPD
      * @see #NETWORK_TYPE_HSPAP
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getDataNetworkType() {
         return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
     }
@@ -1792,12 +1784,9 @@
      * @return the network type
      *
      * @param subId for which network type is returned
-     *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getDataNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -1818,23 +1807,17 @@
 
     /**
      * Returns the NETWORK_TYPE_xxxx for voice
-     *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getVoiceNetworkType() {
         return getVoiceNetworkType(getSubId());
     }
 
     /**
      * Returns the NETWORK_TYPE_xxxx for voice for a subId
-     *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getVoiceNetworkType(int subId) {
         try{
             ITelephony telephony = getITelephony();
@@ -2236,10 +2219,8 @@
     /**
      * Returns the serial number of the SIM, if applicable. Return null if it is
      * unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getSimSerialNumber() {
          return getSimSerialNumber(getSubId());
     }
@@ -2249,10 +2230,9 @@
      * unavailable.
      * <p>
      * @param subId for which Sim Serial number is returned
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getSimSerialNumber(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2275,12 +2255,9 @@
      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getLteOnCdmaMode() {
         return getLteOnCdmaMode(getSubId());
     }
@@ -2293,12 +2270,9 @@
      * @param subId for which radio is LTE on CDMA is returned
      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
-     *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getLteOnCdmaMode(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -2323,10 +2297,8 @@
     /**
      * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getSubscriberId() {
         return getSubscriberId(getSubId());
     }
@@ -2335,13 +2307,11 @@
      * Returns the unique subscriber ID, for example, the IMSI for a GSM phone
      * for a subscription.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
      * @param subId whose subscriber id is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getSubscriberId(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2359,10 +2329,8 @@
     /**
      * Returns the Group Identifier Level1 for a GSM phone.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getGroupIdLevel1() {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2380,13 +2348,11 @@
     /**
      * Returns the Group Identifier Level1 for a GSM phone for a particular subscription.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
      * @param subId whose subscriber id is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getGroupIdLevel1(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2405,15 +2371,13 @@
      * Returns the phone number string for line 1, for example, the MSISDN
      * for a GSM phone. Return null if it is unavailable.
      * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *   OR
-     *   {@link android.Manifest.permission#READ_SMS}
-     *   OR
-     *   {@link android.Manifest.permission#READ_PHONE_NUMBERS}
-     * <p>
      * The default SMS app can also use this.
      */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PHONE_STATE,
+            android.Manifest.permission.READ_SMS,
+            android.Manifest.permission.READ_PHONE_NUMBERS
+    })
     public String getLine1Number() {
         return getLine1Number(getSubId());
     }
@@ -2422,18 +2386,16 @@
      * Returns the phone number string for line 1, for example, the MSISDN
      * for a GSM phone for a particular subscription. Return null if it is unavailable.
      * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *   OR
-     *   {@link android.Manifest.permission#READ_SMS}
-     *   OR
-     *   {@link android.Manifest.permission#READ_PHONE_NUMBERS}
-     * <p>
      * The default SMS app can also use this.
      *
      * @param subId whose phone number for line 1 is returned
      * @hide
      */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.READ_PHONE_STATE,
+            android.Manifest.permission.READ_SMS,
+            android.Manifest.permission.READ_PHONE_NUMBERS
+    })
     public String getLine1Number(int subId) {
         String number = null;
         try {
@@ -2505,12 +2467,10 @@
     /**
      * Returns the alphabetic identifier associated with the line 1 number.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      * nobody seems to call this.
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getLine1AlphaTag() {
         return getLine1AlphaTag(getSubId());
     }
@@ -2519,13 +2479,11 @@
      * Returns the alphabetic identifier associated with the line 1 number
      * for a subscription.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @param subId whose alphabetic identifier associated with line 1 is returned
      * nobody seems to call this.
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getLine1AlphaTag(int subId) {
         String alphaTag = null;
         try {
@@ -2574,12 +2532,10 @@
     /**
      * Returns the MSISDN string.
      * for a GSM phone. Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getMsisdn() {
         return getMsisdn(getSubId());
     }
@@ -2587,13 +2543,11 @@
     /**
      * Returns the MSISDN string.
      * for a GSM phone. Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
      * @param subId for which msisdn is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getMsisdn(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2610,10 +2564,8 @@
 
     /**
      * Returns the voice mail number. Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getVoiceMailNumber() {
         return getVoiceMailNumber(getSubId());
     }
@@ -2621,12 +2573,10 @@
     /**
      * Returns the voice mail number for a subscription.
      * Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @param subId whose voice mail number is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getVoiceMailNumber(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2643,25 +2593,21 @@
 
     /**
      * Returns the complete voice mail number. Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CALL_PRIVILEGED)
     public String getCompleteVoiceMailNumber() {
         return getCompleteVoiceMailNumber(getSubId());
     }
 
     /**
      * Returns the complete voice mail number. Return null if it is unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
      *
      * @param subId
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.CALL_PRIVILEGED)
     public String getCompleteVoiceMailNumber(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -2732,9 +2678,6 @@
     /**
      * Returns whether the visual voicemail client is enabled.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
      * @param phoneAccountHandle the phone account to check for.
      * @return {@code true} when the visual voicemail client is enabled for this client
      * @hide
@@ -2742,24 +2685,50 @@
      * be implemented instead.
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public boolean isVisualVoicemailEnabled(PhoneAccountHandle phoneAccountHandle){
         return false;
     }
 
+    /**
+     * Returns an opaque bundle of settings formerly used by the visual voicemail client for the
+     * subscription ID pinned to the TelephonyManager, or {@code null} if the subscription ID is
+     * invalid. This method allows the system dialer to migrate settings out of the pre-O visual
+     * voicemail client in telephony.
+     *
+     * <p>Requires the caller to be the system dialer.
+     *
+     * @see #KEY_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL
+     * @see #KEY_VOICEMAIL_SCRAMBLED_PIN_STRING
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public Bundle getVisualVoicemailSettings(){
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony
+                        .getVisualVoicemailSettings(mContext.getOpPackageName(), mSubId);
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return null;
+    }
 
     /**
      * Returns the package responsible of processing visual voicemail for the subscription ID pinned
      * to the TelephonyManager. Returns {@code null} when there is no package responsible for
      * processing visual voicemail for the subscription.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
-     * READ_PHONE_STATE}
-     *
      * @see #createForSubscriptionId(int)
      * @see #createForPhoneAccountHandle(PhoneAccountHandle)
      * @see VisualVoicemailService
      */
     @Nullable
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getVisualVoicemailPackageName() {
         try {
             ITelephony telephony = getITelephony();
@@ -2774,6 +2743,54 @@
     }
 
     /**
+     * Set the visual voicemail SMS filter settings for the subscription ID pinned
+     * to the TelephonyManager.
+     * When the filter is enabled, {@link
+     * VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be
+     * called when a SMS matching the settings is received. The caller should have
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} and implement a
+     * VisualVoicemailService.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *
+     * @param settings The settings for the filter, or {@code null} to disable the filter.
+     */
+    public void setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings settings) {
+        if (settings == null) {
+            disableVisualVoicemailSmsFilter(mSubId);
+        } else {
+            enableVisualVoicemailSmsFilter(mSubId, settings);
+        }
+    }
+
+    /**
+     * Send a visual voicemail SMS. The caller must be the current default dialer.
+     * A {@link VisualVoicemailService} uses this method to send a command via SMS to the carrier's
+     * visual voicemail server.  Some examples for carriers using the OMTP standard include
+     * activating and deactivating visual voicemail, or requesting the current visual voicemail
+     * provisioning status.  See the OMTP Visual Voicemail specification for more information on the
+     * format of these SMS messages.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#SEND_SMS SEND_SMS}
+     *
+     * @param number The destination number.
+     * @param port The destination port for data SMS, or 0 for text SMS.
+     * @param text The message content. For data sms, it will be encoded as a UTF-8 byte stream.
+     * @param sentIntent The sent intent passed to the {@link SmsManager}
+     *
+     * @throws SecurityException if the caller is not the current default dialer
+     *
+     * @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
+     * @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
+     */
+    public void sendVisualVoicemailSms(String number, int port, String text,
+            PendingIntent sentIntent) {
+        sendVisualVoicemailSmsForSubscriber(mSubId, number, port, text, sentIntent);
+    }
+
+    /**
      * Enables the visual voicemail SMS filter for a phone account. When the filter is
      * enabled, Incoming SMS messages matching the OMTP VVM SMS interface will be redirected to the
      * visual voicemail client with
@@ -2871,9 +2888,6 @@
     /**
      * Send a visual voicemail SMS. The IPC caller must be the current default dialer.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#SEND_SMS SEND_SMS}
-     *
      * @param phoneAccountHandle The account to send the SMS with.
      * @param number The destination number.
      * @param port The destination port for data SMS, or 0 for text SMS.
@@ -2885,6 +2899,7 @@
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.SEND_SMS)
     public void sendVisualVoicemailSmsForSubscriber(int subId, String number, int port,
             String text, PendingIntent sentIntent) {
         try {
@@ -2989,9 +3004,6 @@
     /**
      * Returns the voice activation state for the given subscriber.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE}
-     *
      * @param subId The subscription id.
      *
      * @return voiceActivationState for the given subscriber
@@ -3001,6 +3013,7 @@
      * @see #SIM_ACTIVATION_STATE_DEACTIVATED
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getVoiceActivationState(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3015,9 +3028,6 @@
     /**
      * Returns the data activation state for the given subscriber.
      *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE}
-     *
      * @param subId The subscription id.
      *
      * @return dataActivationState for the given subscriber
@@ -3028,6 +3038,7 @@
      * @see #SIM_ACTIVATION_STATE_RESTRICTED
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getDataActivationState(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3042,23 +3053,19 @@
     /**
      * Returns the voice mail count. Return 0 if unavailable, -1 if there are unread voice messages
      * but the count is unknown.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getVoiceMessageCount() {
         return getVoiceMessageCount(getSubId());
     }
 
     /**
      * Returns the voice mail count for a subscription. Return 0 if unavailable.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @param subId whose voice message count is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getVoiceMessageCount(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3076,10 +3083,8 @@
     /**
      * Retrieves the alphabetic identifier associated with the voice
      * mail number.
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getVoiceMailAlphaTag() {
         return getVoiceMailAlphaTag(getSubId());
     }
@@ -3087,13 +3092,11 @@
     /**
      * Retrieves the alphabetic identifier associated with the voice
      * mail number for a subscription.
-     * <p>
-     * Requires Permission:
-     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @param subId whose alphabetic identifier associated with the
      * voice mail number is returned
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getVoiceMailAlphaTag(int subId) {
         try {
             IPhoneSubInfo info = getSubscriberInfo();
@@ -3404,23 +3407,18 @@
 
     /**
      * Returns the CDMA ERI icon index to display
-     *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getCdmaEriIconIndex() {
         return getCdmaEriIconIndex(getSubId());
     }
 
     /**
      * Returns the CDMA ERI icon index to display for a subscription
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getCdmaEriIconIndex(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3440,11 +3438,9 @@
      * 0 - ON
      * 1 - FLASHING
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getCdmaEriIconMode() {
         return getCdmaEriIconMode(getSubId());
     }
@@ -3454,11 +3450,9 @@
      * 0 - ON
      * 1 - FLASHING
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public int getCdmaEriIconMode(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3476,11 +3470,9 @@
     /**
      * Returns the CDMA ERI text,
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getCdmaEriText() {
         return getCdmaEriText(getSubId());
     }
@@ -3488,11 +3480,9 @@
     /**
      * Returns the CDMA ERI text, of a subscription
      *
-     * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String getCdmaEriText(int subId) {
         try {
             ITelephony telephony = getITelephony();
@@ -3575,13 +3565,10 @@
      * android.telephony.TelephonyManager#getCellLocation getCellLocation()}
      * instead.
      *
-     * <p>Requires permission:
-     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
-     *
      * @return List of {@link android.telephony.CellInfo}; null if cell
      * information is unavailable.
-     *
      */
+    @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
     public List<CellInfo> getAllCellInfo() {
         try {
             ITelephony telephony = getITelephony();
@@ -4435,11 +4422,9 @@
      * Returns an array of Forbidden PLMNs from the USIM App
      * Returns null if the query fails.
      *
-     *
-     * <p>Requires that the caller has READ_PHONE_STATE
-     *
      * @return an array of forbidden PLMNs or null if not available
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String[] getForbiddenPlmns() {
       return getForbiddenPlmns(getSubId(), APPTYPE_USIM);
     }
@@ -4448,14 +4433,12 @@
      * Returns an array of Forbidden PLMNs from the specified SIM App
      * Returns null if the query fails.
      *
-     *
-     * <p>Requires that the calling app has READ_PHONE_STATE
-     *
      * @param subId subscription ID used for authentication
      * @param appType the icc application type, like {@link #APPTYPE_USIM}
      * @return fplmns an array of forbidden PLMNs
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public String[] getForbiddenPlmns(int subId, int appType) {
         try {
             ITelephony telephony = getITelephony();
@@ -6143,10 +6126,8 @@
 
     /**
      * Returns the current {@link ServiceState} information.
-     *
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public ServiceState getServiceState() {
         return getServiceStateForSubscriber(getSubId());
     }
diff --git a/telephony/java/android/telephony/VisualVoicemailService.java b/telephony/java/android/telephony/VisualVoicemailService.java
index e211f76..fe30eb7 100644
--- a/telephony/java/android/telephony/VisualVoicemailService.java
+++ b/telephony/java/android/telephony/VisualVoicemailService.java
@@ -18,6 +18,7 @@
 
 import android.annotation.MainThread;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
@@ -199,7 +200,8 @@
 
     /**
      * Called when a SMS matching the {@link VisualVoicemailSmsFilterSettings} set by
-     * {@link #setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)}
+     * {@link TelephonyManager#setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings)
+     * }
      * is received.
      *
      * @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
@@ -240,8 +242,11 @@
      *
      * @param phoneAccountHandle The account to apply the settings to.
      * @param settings The settings for the filter, or {@code null} to disable the filter.
+     *
+     * @hide
      */
-    public final static void setSmsFilterSettings(Context context,
+    @SystemApi
+    public static final void setSmsFilterSettings(Context context,
             PhoneAccountHandle phoneAccountHandle,
             VisualVoicemailSmsFilterSettings settings) {
         TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
@@ -269,8 +274,11 @@
      *
      * @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
      * @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
+     *
+     * @hide
      */
-    public final static void sendVisualVoicemailSms(Context context,
+    @SystemApi
+    public static final void sendVisualVoicemailSms(Context context,
             PhoneAccountHandle phoneAccountHandle, String number,
             short port, String text, PendingIntent sentIntent) {
         TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
index 56a8c62..8ed96a3 100644
--- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
+++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
@@ -38,7 +38,7 @@
  * <p>Use {@link android.telephony.VisualVoicemailSmsFilterSettings.Builder} to construct this
  * class.
  *
- * @see VisualVoicemailService#setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)
+ * @see TelephonyManager#setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings)
  */
 public final class VisualVoicemailSmsFilterSettings implements Parcelable {
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index dd08f67..da333ae 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -498,6 +498,8 @@
       */
     boolean isConcurrentVoiceAndDataAllowed(int subId);
 
+    Bundle getVisualVoicemailSettings(String callingPackage, int subId);
+
     String getVisualVoicemailPackageName(String callingPackage, int subId);
 
     // Not oneway, caller needs to make sure the vaule is set before receiving a SMS
diff --git a/tests/testables/src/android/testing/AndroidTestingRunner.java b/tests/testables/src/android/testing/AndroidTestingRunner.java
index 816ed03..a425f70 100644
--- a/tests/testables/src/android/testing/AndroidTestingRunner.java
+++ b/tests/testables/src/android/testing/AndroidTestingRunner.java
@@ -18,7 +18,7 @@
 import android.support.test.internal.runner.junit4.statement.RunBefores;
 import android.support.test.internal.runner.junit4.statement.UiThreadStatement;
 
-import android.testing.TestableLooper.LooperStatement;
+import android.testing.TestableLooper.LooperFrameworkMethod;
 import android.testing.TestableLooper.RunWithLooper;
 
 import org.junit.After;
@@ -30,6 +30,7 @@
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.Statement;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -49,28 +50,21 @@
 
     @Override
     protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        return shouldRunOnUiThread(method) ? new UiThreadStatement(
-                methodInvokerInt(method, test), true) : methodInvokerInt(method, test);
-    }
-
-    protected Statement methodInvokerInt(FrameworkMethod method, Object test) {
-        RunWithLooper annotation = method.getAnnotation(RunWithLooper.class);
-        if (annotation == null) annotation = mKlass.getAnnotation(RunWithLooper.class);
-        if (annotation != null) {
-            return new LooperStatement(super.methodInvoker(method, test),
-                    annotation.setAsMainLooper(), test);
-        }
-        return super.methodInvoker(method, test);
+        method = looperWrap(method, test, method);
+        final Statement statement = super.methodInvoker(method, test);
+        return shouldRunOnUiThread(method) ? new UiThreadStatement(statement, true) : statement;
     }
 
     protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
-        List befores = this.getTestClass().getAnnotatedMethods(Before.class);
+        List befores = looperWrap(method, target,
+                this.getTestClass().getAnnotatedMethods(Before.class));
         return befores.isEmpty() ? statement : new RunBefores(method, statement,
                 befores, target);
     }
 
     protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) {
-        List afters = this.getTestClass().getAnnotatedMethods(After.class);
+        List afters = looperWrap(method, target,
+                this.getTestClass().getAnnotatedMethods(After.class));
         return afters.isEmpty() ? statement : new RunAfters(method, statement, afters,
                 target);
     }
@@ -88,6 +82,30 @@
         return annotation == null ? 0L : annotation.timeout();
     }
 
+    protected List<FrameworkMethod> looperWrap(FrameworkMethod method, Object test,
+            List<FrameworkMethod> methods) {
+        RunWithLooper annotation = method.getAnnotation(RunWithLooper.class);
+        if (annotation == null) annotation = mKlass.getAnnotation(RunWithLooper.class);
+        if (annotation != null) {
+            methods = new ArrayList<>(methods);
+            for (int i = 0; i < methods.size(); i++) {
+                methods.set(i, LooperFrameworkMethod.get(methods.get(i),
+                        annotation.setAsMainLooper(), test));
+            }
+        }
+        return methods;
+    }
+
+    protected FrameworkMethod looperWrap(FrameworkMethod method, Object test,
+            FrameworkMethod base) {
+        RunWithLooper annotation = method.getAnnotation(RunWithLooper.class);
+        if (annotation == null) annotation = mKlass.getAnnotation(RunWithLooper.class);
+        if (annotation != null) {
+            return LooperFrameworkMethod.get(base, annotation.setAsMainLooper(), test);
+        }
+        return base;
+    }
+
     public boolean shouldRunOnUiThread(FrameworkMethod method) {
         if (mKlass.getAnnotation(UiThreadTest.class) != null) {
             return true;
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index 8a33cf9..9eddc51 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -15,20 +15,21 @@
 package android.testing;
 
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
+import android.os.TestLooperManager;
+import android.support.test.InstrumentationRegistry;
 import android.util.ArrayMap;
 
-import org.junit.runners.model.Statement;
+import org.junit.runners.model.FrameworkMethod;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Map;
 
 /**
@@ -38,65 +39,35 @@
  */
 public class TestableLooper {
 
-    private final Method mNext;
-    private final Method mRecycleUnchecked;
-
     private Looper mLooper;
     private MessageQueue mQueue;
     private boolean mMain;
     private Object mOriginalMain;
     private MessageHandler mMessageHandler;
 
-    private int mParsedCount;
     private Handler mHandler;
-    private Message mEmptyMessage;
+    private Runnable mEmptyMessage;
+    private TestLooperManager mQueueWrapper;
 
-    public TestableLooper() throws Exception {
-        this(true);
+    public TestableLooper(Looper l) throws Exception {
+        this(InstrumentationRegistry.getInstrumentation().acquireLooperManager(l), l);
     }
 
-    public TestableLooper(boolean setMyLooper) throws Exception {
-        setupQueue(setMyLooper);
-        mNext = mQueue.getClass().getDeclaredMethod("next");
-        mNext.setAccessible(true);
-        mRecycleUnchecked = Message.class.getDeclaredMethod("recycleUnchecked");
-        mRecycleUnchecked.setAccessible(true);
+    private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
+        mQueueWrapper = wrapper;
+        setupQueue(l);
+    }
+
+    private TestableLooper(Looper looper, boolean b) throws Exception {
+        setupQueue(looper);
     }
 
     public Looper getLooper() {
         return mLooper;
     }
 
-    private void clearLooper() throws NoSuchFieldException, IllegalAccessException {
-        Field field = Looper.class.getDeclaredField("sThreadLocal");
-        field.setAccessible(true);
-        ThreadLocal<Looper> sThreadLocal = (ThreadLocal<Looper>) field.get(null);
-        sThreadLocal.set(null);
-    }
-
-    private boolean setForCurrentThread() throws NoSuchFieldException, IllegalAccessException {
-        if (Looper.myLooper() != mLooper) {
-            Field field = Looper.class.getDeclaredField("sThreadLocal");
-            field.setAccessible(true);
-            ThreadLocal<Looper> sThreadLocal = (ThreadLocal<Looper>) field.get(null);
-            sThreadLocal.set(mLooper);
-            return true;
-        }
-        return false;
-    }
-
-    private void setupQueue(boolean setMyLooper) throws Exception {
-        if (setMyLooper) {
-            clearLooper();
-            Looper.prepare();
-            mLooper = Looper.myLooper();
-        } else {
-            Constructor<Looper> constructor = Looper.class.getDeclaredConstructor(
-                    boolean.class);
-            constructor.setAccessible(true);
-            mLooper = constructor.newInstance(true);
-        }
-
+    private void setupQueue(Looper l) throws Exception {
+        mLooper = l;
         mQueue = mLooper.getQueue();
         mHandler = new Handler(mLooper);
     }
@@ -121,9 +92,7 @@
      * tests.
      */
     public void destroy() throws NoSuchFieldException, IllegalAccessException {
-        if (Looper.myLooper() == mLooper) {
-            clearLooper();
-        }
+        mQueueWrapper.release();
         if (mMain && mOriginalMain != null) {
             Field field = mLooper.getClass().getDeclaredField("sMainLooper");
             field.setAccessible(true);
@@ -156,34 +125,35 @@
 
     private int processQueuedMessages() {
         int count = 0;
-        mEmptyMessage = mHandler.obtainMessage(1);
-        mHandler.sendMessageDelayed(mEmptyMessage, 1);
+        mEmptyMessage = () -> { };
+        mHandler.post(mEmptyMessage);
+        waitForMessage(mQueueWrapper, mHandler, mEmptyMessage);
         while (parseMessageInt()) count++;
         return count;
     }
 
     private boolean parseMessageInt() {
         try {
-            Message result = (Message) mNext.invoke(mQueue);
+            Message result = mQueueWrapper.next();
             if (result != null) {
                 // This is a break message.
-                if (result == mEmptyMessage) {
-                    mRecycleUnchecked.invoke(result);
+                if (result.getCallback() == mEmptyMessage) {
+                    mQueueWrapper.recycle(result);
                     return false;
                 }
 
                 if (mMessageHandler != null) {
                     if (mMessageHandler.onMessageHandled(result)) {
                         result.getTarget().dispatchMessage(result);
-                        mRecycleUnchecked.invoke(result);
+                        mQueueWrapper.recycle(result);
                     } else {
-                        mRecycleUnchecked.invoke(result);
+                        mQueueWrapper.recycle(result);
                         // Message handler indicated it doesn't want us to continue.
                         return false;
                     }
                 } else {
                     result.getTarget().dispatchMessage(result);
-                    mRecycleUnchecked.invoke(result);
+                    mQueueWrapper.recycle(result);
                 }
             } else {
                 // No messages, don't continue parsing
@@ -199,10 +169,14 @@
      * Runs an executable with myLooper set and processes all messages added.
      */
     public void runWithLooper(RunnableWithException runnable) throws Exception {
-        boolean set = setForCurrentThread();
-        runnable.run();
+        new Handler(getLooper()).post(() -> {
+            try {
+                runnable.run();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
         processAllMessages();
-        if (set) clearLooper();
     }
 
     public interface RunnableWithException {
@@ -215,39 +189,132 @@
         boolean setAsMainLooper() default false;
     }
 
+    private static void waitForMessage(TestLooperManager queueWrapper, Handler handler,
+            Runnable execute) {
+        for (int i = 0; i < 10; i++) {
+            if (!queueWrapper.hasMessages(handler, null, execute)) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        if (!queueWrapper.hasMessages(handler, null, execute)) {
+            throw new RuntimeException("Message didn't queue...");
+        }
+    }
+
     private static final Map<Object, TestableLooper> sLoopers = new ArrayMap<>();
 
     public static TestableLooper get(Object test) {
         return sLoopers.get(test);
     }
 
-    public static class LooperStatement extends Statement {
-        private final boolean mSetAsMain;
-        private final Statement mBase;
-        private final TestableLooper mLooper;
+    public static class LooperFrameworkMethod extends FrameworkMethod {
+        private HandlerThread mHandlerThread;
 
-        public LooperStatement(Statement base, boolean setAsMain, Object test) {
-            mBase = base;
+        private final TestableLooper mTestableLooper;
+        private final Looper mLooper;
+        private final Handler mHandler;
+
+        public LooperFrameworkMethod(FrameworkMethod base, boolean setAsMain, Object test) {
+            super(base.getMethod());
             try {
-                mLooper = new TestableLooper(false);
-                sLoopers.put(test, mLooper);
-                mSetAsMain = setAsMain;
+                mLooper = setAsMain ? Looper.getMainLooper() : createLooper();
+                mTestableLooper = new TestableLooper(mLooper, false);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
+            sLoopers.put(test, mTestableLooper);
+            mHandler = new Handler(mLooper);
+        }
+
+        public LooperFrameworkMethod(TestableLooper other, FrameworkMethod base) {
+            super(base.getMethod());
+            mLooper = other.mLooper;
+            mTestableLooper = other;
+            mHandler = new Handler(mLooper);
+        }
+
+        public static FrameworkMethod get(FrameworkMethod base, boolean setAsMain, Object test) {
+            if (sLoopers.containsKey(test)) {
+                return new LooperFrameworkMethod(sLoopers.get(test), base);
+            }
+            return new LooperFrameworkMethod(base, setAsMain, test);
         }
 
         @Override
-        public void evaluate() throws Throwable {
-            mLooper.setForCurrentThread();
-            if (mSetAsMain) {
-                mLooper.setAsMainLooper();
+        public Object invokeExplosively(Object target, Object... params) throws Throwable {
+            if (Looper.myLooper() == mLooper) {
+                // Already on the right thread from another statement, just execute then.
+                return super.invokeExplosively(target, params);
+            }
+            boolean set = mTestableLooper.mQueueWrapper == null;
+            if (set) {
+                mTestableLooper.mQueueWrapper = InstrumentationRegistry.getInstrumentation()
+                        .acquireLooperManager(mLooper);
+            }
+            try {
+                Object[] ret = new Object[1];
+                // Run the execution on the looper thread.
+                Runnable execute = () -> {
+                    try {
+                        ret[0] = super.invokeExplosively(target, params);
+                    } catch (Throwable throwable) {
+                        throw new LooperException(throwable);
+                    }
+                };
+                Message m = Message.obtain(mHandler, execute);
+
+                // Dispatch our message.
+                try {
+                    mTestableLooper.mQueueWrapper.execute(m);
+                } catch (LooperException e) {
+                    throw e.getSource();
+                } catch (RuntimeException re) {
+                    // If the TestLooperManager has to post, it will wrap what it throws in a
+                    // RuntimeException, make sure we grab the actual source.
+                    if (re.getCause() instanceof LooperException) {
+                        throw ((LooperException) re.getCause()).getSource();
+                    } else {
+                        throw re.getCause();
+                    }
+                } finally {
+                    m.recycle();
+                }
+                return ret[0];
+            } finally {
+                if (set) {
+                    mTestableLooper.mQueueWrapper.release();
+                    mTestableLooper.mQueueWrapper = null;
+                }
+            }
+        }
+
+        private Looper createLooper() {
+            // TODO: Find way to share these.
+            mHandlerThread = new HandlerThread(TestableLooper.class.getSimpleName());
+            mHandlerThread.start();
+            return mHandlerThread.getLooper();
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            super.finalize();
+            if (mHandlerThread != null) {
+                mHandlerThread.quit();
+            }
+        }
+
+        private static class LooperException extends RuntimeException {
+            private final Throwable mSource;
+
+            public LooperException(Throwable t) {
+                mSource = t;
             }
 
-            try {
-                mBase.evaluate();
-            } finally {
-                mLooper.destroy();
+            public Throwable getSource() {
+                return mSource;
             }
         }
     }
diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java
index 18e5fff..12f1d0a 100644
--- a/tests/testables/tests/src/android/testing/TestableLooperTest.java
+++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java
@@ -24,17 +24,16 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.testing.TestableLooper.MessageHandler;
 import android.testing.TestableLooper.RunWithLooper;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 public class TestableLooperTest {
@@ -46,11 +45,6 @@
         mTestableLooper = TestableLooper.get(this);
     }
 
-    @After
-    public void tearDown() throws Exception {
-        mTestableLooper.destroy();
-    }
-
     @Test
     public void testMessageExecuted() throws Exception {
         Handler h = new Handler();
@@ -133,39 +127,23 @@
     @Test
     public void testMainLooper() throws Exception {
         assertNotEquals(Looper.myLooper(), Looper.getMainLooper());
-
-        Looper originalMain = Looper.getMainLooper();
-        mTestableLooper.setAsMainLooper();
-        assertEquals(Looper.myLooper(), Looper.getMainLooper());
-        Runnable r = mock(Runnable.class);
-
-        new Handler(Looper.getMainLooper()).post(r);
-        mTestableLooper.processAllMessages();
-
-        verify(r).run();
-        mTestableLooper.destroy();
-
-        assertEquals(originalMain, Looper.getMainLooper());
-    }
-
-    @Test
-    public void testNotMyLooper() throws Exception {
-        TestableLooper looper = new TestableLooper(false);
-
-        assertEquals(Looper.myLooper(), mTestableLooper.getLooper());
-        assertNotEquals(Looper.myLooper(), looper.getLooper());
-
         Runnable r = mock(Runnable.class);
         Runnable r2 = mock(Runnable.class);
-        new Handler().post(r);
-        new Handler(looper.getLooper()).post(r2);
+        TestableLooper testableLooper = new TestableLooper(Looper.getMainLooper());
 
-        looper.processAllMessages();
-        verify(r2).run();
-        verify(r, never()).run();
+        try {
+            testableLooper.setMessageHandler(m -> {
+                if (m.getCallback() == r) return true;
+                return false;
+            });
+            new Handler(Looper.getMainLooper()).post(r);
+            testableLooper.processAllMessages();
 
-        mTestableLooper.processAllMessages();
-        verify(r).run();
+            verify(r).run();
+            verify(r2, never()).run();
+        } finally {
+            testableLooper.destroy();
+        }
     }
 
     @Test
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 578a8fb..b93c6ec 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -365,6 +365,21 @@
   return true;
 }
 
+static bool IsValidFile(IAaptContext* context, const StringPiece& input_path) {
+  const file::FileType file_type = file::GetFileType(input_path);
+  if (file_type != file::FileType::kRegular && file_type != file::FileType::kSymlink) {
+    if (file_type == file::FileType::kDirectory) {
+      context->GetDiagnostics()->Error(DiagMessage(input_path)
+                                       << "resource file cannot be a directory");
+    } else {
+      context->GetDiagnostics()->Error(DiagMessage(input_path)
+                                       << "not a valid resource file");
+    }
+    return false;
+  }
+  return true;
+}
+
 static bool CompileXml(IAaptContext* context, const CompileOptions& options,
                        const ResourcePathData& path_data, IArchiveWriter* writer,
                        const std::string& output_path) {
@@ -569,7 +584,8 @@
   std::string error_str;
   Maybe<android::FileMap> f = file::MmapPath(path_data.source.path, &error_str);
   if (!f) {
-    context->GetDiagnostics()->Error(DiagMessage(path_data.source) << error_str);
+    context->GetDiagnostics()->Error(DiagMessage(path_data.source) << "failed to mmap file: "
+                                     << error_str);
     return false;
   }
 
@@ -582,6 +598,11 @@
 
 class CompileContext : public IAaptContext {
  public:
+  PackageType GetPackageType() override {
+    // Every compilation unit starts as an app and then gets linked as potentially something else.
+    return PackageType::kApp;
+  }
+
   void SetVerbose(bool val) {
     verbose_ = val;
   }
@@ -692,6 +713,11 @@
       context.GetDiagnostics()->Note(DiagMessage(path_data.source) << "processing");
     }
 
+    if (!IsValidFile(&context, path_data.source.path)) {
+      error = true;
+      continue;
+    }
+
     if (path_data.resource_dir == "values") {
       // Overwrite the extension.
       path_data.extension = "arsc";
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index fdc89b2..1a6f348 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -31,6 +31,11 @@
   DiffContext() : name_mangler_({}), symbol_table_(&name_mangler_) {
   }
 
+  PackageType GetPackageType() override {
+    // Doesn't matter.
+    return PackageType::kApp;
+  }
+
   const std::string& GetCompilationPackage() override {
     return empty_;
   }
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 1bbfb28..57c4574 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -144,6 +144,11 @@
 
 class DumpContext : public IAaptContext {
  public:
+  PackageType GetPackageType() override {
+    // Doesn't matter.
+    return PackageType::kApp;
+  }
+
   IDiagnostics* GetDiagnostics() override {
     return &diagnostics_;
   }
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index b86188f..258516d 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -65,16 +65,7 @@
 
 namespace aapt {
 
-// The type of package to build.
-enum class PackageType {
-  kApp,
-  kSharedLib,
-  kStaticLib,
-};
-
 struct LinkOptions {
-  PackageType package_type = PackageType::kApp;
-
   std::string output_path;
   std::string manifest_path;
   std::vector<std::string> include_paths;
@@ -130,6 +121,14 @@
   LinkContext() : name_mangler_({}), symbols_(&name_mangler_) {
   }
 
+  PackageType GetPackageType() override {
+    return package_type_;
+  }
+
+  void SetPackageType(PackageType type) {
+    package_type_ = type;
+  }
+
   IDiagnostics* GetDiagnostics() override {
     return &diagnostics_;
   }
@@ -181,6 +180,7 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(LinkContext);
 
+  PackageType package_type_ = PackageType::kApp;
   StdErrDiagnostics diagnostics_;
   NameMangler name_mangler_;
   std::string compilation_package_;
@@ -627,7 +627,7 @@
       std::string error_str;
       std::unique_ptr<ResourceTable> include_static = LoadStaticLibrary(path, &error_str);
       if (include_static) {
-        if (options_.package_type != PackageType::kStaticLib) {
+        if (context_->GetPackageType() != PackageType::kStaticLib) {
           // Can't include static libraries when not building a static library (they have no IDs
           // assigned).
           context_->GetDiagnostics()->Error(
@@ -1300,7 +1300,7 @@
    */
   bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
                 ResourceTable* table) {
-    const bool keep_raw_values = options_.package_type == PackageType::kStaticLib;
+    const bool keep_raw_values = context_->GetPackageType() == PackageType::kStaticLib;
     bool result =
         FlattenXml(manifest, "AndroidManifest.xml", {}, keep_raw_values, writer, context_);
     if (!result) {
@@ -1325,7 +1325,7 @@
       return false;
     }
 
-    if (options_.package_type == PackageType::kStaticLib) {
+    if (context_->GetPackageType() == PackageType::kStaticLib) {
       if (!FlattenTableToPb(table, writer)) {
         return false;
       }
@@ -1374,7 +1374,7 @@
       context_->SetPackageId(0x01);
 
       // Verify we're building a regular app.
-      if (options_.package_type != PackageType::kApp) {
+      if (context_->GetPackageType() != PackageType::kApp) {
         context_->GetDiagnostics()->Error(
             DiagMessage() << "package 'android' can only be built as a regular app");
         return 1;
@@ -1414,7 +1414,7 @@
       return 1;
     }
 
-    if (options_.package_type != PackageType::kStaticLib) {
+    if (context_->GetPackageType() != PackageType::kStaticLib) {
       PrivateAttributeMover mover;
       if (!mover.Consume(context_, &final_table_)) {
         context_->GetDiagnostics()->Error(DiagMessage() << "failed moving private attributes");
@@ -1469,7 +1469,7 @@
       return 1;
     }
 
-    if (options_.package_type == PackageType::kStaticLib) {
+    if (context_->GetPackageType() == PackageType::kStaticLib) {
       if (!options_.products.empty()) {
         context_->GetDiagnostics()->Warn(DiagMessage()
                                          << "can't select products when building static library");
@@ -1490,7 +1490,7 @@
       }
     }
 
-    if (options_.package_type != PackageType::kStaticLib && context_->GetMinSdkVersion() > 0) {
+    if (context_->GetPackageType() != PackageType::kStaticLib && context_->GetMinSdkVersion() > 0) {
       if (context_->IsVerbose()) {
         context_->GetDiagnostics()->Note(DiagMessage()
                                          << "collapsing resource versions for minimum SDK "
@@ -1514,7 +1514,7 @@
     proguard::KeepSet proguard_keep_set;
     proguard::KeepSet proguard_main_dex_keep_set;
 
-    if (options_.package_type == PackageType::kStaticLib) {
+    if (context_->GetPackageType() == PackageType::kStaticLib) {
       if (options_.table_splitter_options.config_filter != nullptr ||
           !options_.table_splitter_options.preferred_densities.empty()) {
         context_->GetDiagnostics()->Warn(DiagMessage()
@@ -1641,11 +1641,12 @@
       template_options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
       template_options.javadoc_annotations = options_.javadoc_annotations;
 
-      if (options_.package_type == PackageType::kStaticLib || options_.generate_non_final_ids) {
+      if (context_->GetPackageType() == PackageType::kStaticLib ||
+          options_.generate_non_final_ids) {
         template_options.use_final = false;
       }
 
-      if (options_.package_type == PackageType::kSharedLib) {
+      if (context_->GetPackageType() == PackageType::kSharedLib) {
         template_options.use_final = false;
         template_options.rewrite_callback_options = OnResourcesLoadedCallbackOptions{};
       }
@@ -1922,18 +1923,18 @@
   }
 
   if (shared_lib) {
-    options.package_type = PackageType::kSharedLib;
+    context.SetPackageType(PackageType::kSharedLib);
     context.SetPackageId(0x00);
   } else if (static_lib) {
-    options.package_type = PackageType::kStaticLib;
+    context.SetPackageType(PackageType::kStaticLib);
     context.SetPackageId(kAppPackageId);
   } else {
-    options.package_type = PackageType::kApp;
+    context.SetPackageType(PackageType::kApp);
     context.SetPackageId(kAppPackageId);
   }
 
   if (package_id) {
-    if (options.package_type != PackageType::kApp) {
+    if (context.GetPackageType() != PackageType::kApp) {
       context.GetDiagnostics()->Error(
           DiagMessage() << "can't specify --package-id when not building a regular app");
       return 1;
@@ -2000,7 +2001,7 @@
     }
   }
 
-  if (options.package_type != PackageType::kStaticLib && stable_id_file_path) {
+  if (context.GetPackageType() != PackageType::kStaticLib && stable_id_file_path) {
     if (!LoadStableIdMap(context.GetDiagnostics(), stable_id_file_path.value(),
                          &options.stable_id_map)) {
       return 1;
@@ -2015,7 +2016,7 @@
        ".3gpp2", ".amr",  ".awb",  ".wma", ".wmv",  ".webm", ".mkv"});
 
   // Turn off auto versioning for static-libs.
-  if (options.package_type == PackageType::kStaticLib) {
+  if (context.GetPackageType() == PackageType::kStaticLib) {
     options.no_auto_version = true;
     options.no_version_vectors = true;
     options.no_version_transitions = true;
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index e99ee8a..78ed49b 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -59,6 +59,14 @@
 
 class OptimizeContext : public IAaptContext {
  public:
+  OptimizeContext() = default;
+
+  PackageType GetPackageType() override {
+    // Not important here. Using anything other than kApp adds EXTRA validation, which we want to
+    // avoid.
+    return PackageType::kApp;
+  }
+
   IDiagnostics* GetDiagnostics() override {
     return &diagnostics_;
   }
@@ -99,6 +107,8 @@
   }
 
  private:
+  DISALLOW_COPY_AND_ASSIGN(OptimizeContext);
+
   StdErrDiagnostics diagnostics_;
   bool verbose_ = false;
   int sdk_version_ = 0;
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index 3098458..d44b3e0 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -230,15 +230,18 @@
     ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE);
     pkg_header->id = util::HostToDevice32(package_->id.value());
 
-    if (package_->name.size() >= arraysize(pkg_header->name)) {
+    // AAPT truncated the package name, so do the same.
+    // Shared libraries require full package names, so don't truncate theirs.
+    if (context_->GetPackageType() != PackageType::kApp &&
+        package_->name.size() >= arraysize(pkg_header->name)) {
       diag_->Error(DiagMessage() << "package name '" << package_->name
-                                 << "' is too long");
+                                 << "' is too long. "
+                                    "Shared libraries cannot have truncated package names");
       return false;
     }
 
     // Copy the package name in device endianness.
-    strcpy16_htod(pkg_header->name, arraysize(pkg_header->name),
-                  util::Utf8ToUtf16(package_->name));
+    strcpy16_htod(pkg_header->name, arraysize(pkg_header->name), util::Utf8ToUtf16(package_->name));
 
     // Serialize the types. We do this now so that our type and key strings
     // are populated. We write those first.
diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp
index 4196187..8dff3a2 100644
--- a/tools/aapt2/flatten/TableFlattener_test.cpp
+++ b/tools/aapt2/flatten/TableFlattener_test.cpp
@@ -411,4 +411,40 @@
   EXPECT_EQ(0x03u, entries.valueAt(idx));
 }
 
+TEST_F(TableFlattenerTest, LongPackageNameIsTruncated) {
+  std::string kPackageName(256, 'F');
+
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetCompilationPackage(kPackageName).SetPackageId(0x7f).Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId(kPackageName, 0x7f)
+          .AddSimple(kPackageName + ":id/foo", ResourceId(0x7f010000))
+          .Build();
+
+  ResTable result;
+  ASSERT_TRUE(Flatten(context.get(), {}, table.get(), &result));
+
+  ASSERT_EQ(1u, result.getBasePackageCount());
+  EXPECT_EQ(127u, result.getBasePackageName(0).size());
+}
+
+TEST_F(TableFlattenerTest, LongSharedLibraryPackageNameIsIllegal) {
+  std::string kPackageName(256, 'F');
+
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder()
+                                              .SetCompilationPackage(kPackageName)
+                                              .SetPackageId(0x7f)
+                                              .SetPackageType(PackageType::kSharedLib)
+                                              .Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId(kPackageName, 0x7f)
+          .AddSimple(kPackageName + ":id/foo", ResourceId(0x7f010000))
+          .Build();
+
+  ResTable result;
+  ASSERT_FALSE(Flatten(context.get(), {}, table.get(), &result));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 0c19c7a..27ab22b 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -333,7 +333,7 @@
   // Provider actions.
   application_action["provider"] = component_action;
   application_action["provider"]["grant-uri-permissions"];
-  application_action["provider"]["path-permissions"];
+  application_action["provider"]["path-permission"];
 
   return true;
 }
diff --git a/tools/aapt2/process/IResourceTableConsumer.h b/tools/aapt2/process/IResourceTableConsumer.h
index 4526a79..30dad802 100644
--- a/tools/aapt2/process/IResourceTableConsumer.h
+++ b/tools/aapt2/process/IResourceTableConsumer.h
@@ -32,9 +32,17 @@
 class ResourceTable;
 class SymbolTable;
 
+// The type of package to build.
+enum class PackageType {
+  kApp,
+  kSharedLib,
+  kStaticLib,
+};
+
 struct IAaptContext {
   virtual ~IAaptContext() = default;
 
+  virtual PackageType GetPackageType() = 0;
   virtual SymbolTable* GetExternalSymbols() = 0;
   virtual IDiagnostics* GetDiagnostics() = 0;
   virtual const std::string& GetCompilationPackage() = 0;
diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h
index 557cd1b..29d1838 100644
--- a/tools/aapt2/test/Context.h
+++ b/tools/aapt2/test/Context.h
@@ -35,9 +35,17 @@
  public:
   Context() : name_mangler_({}), symbols_(&name_mangler_), min_sdk_version_(0) {}
 
-  SymbolTable* GetExternalSymbols() override { return &symbols_; }
+  PackageType GetPackageType() override {
+    return package_type_;
+  }
 
-  IDiagnostics* GetDiagnostics() override { return &diagnostics_; }
+  SymbolTable* GetExternalSymbols() override {
+    return &symbols_;
+  }
+
+  IDiagnostics* GetDiagnostics() override {
+    return &diagnostics_;
+  }
 
   const std::string& GetCompilationPackage() override {
     CHECK(bool(compilation_package_)) << "package name not set";
@@ -49,17 +57,24 @@
     return package_id_.value();
   }
 
-  NameMangler* GetNameMangler() override { return &name_mangler_; }
+  NameMangler* GetNameMangler() override {
+    return &name_mangler_;
+  }
 
-  bool IsVerbose() override { return false; }
+  bool IsVerbose() override {
+    return false;
+  }
 
-  int GetMinSdkVersion() override { return min_sdk_version_; }
+  int GetMinSdkVersion() override {
+    return min_sdk_version_;
+  }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Context);
 
   friend class ContextBuilder;
 
+  PackageType package_type_ = PackageType::kApp;
   Maybe<std::string> compilation_package_;
   Maybe<uint8_t> package_id_;
   StdErrDiagnostics diagnostics_;
@@ -70,6 +85,11 @@
 
 class ContextBuilder {
  public:
+  ContextBuilder& SetPackageType(PackageType type) {
+    context_->package_type_ = type;
+    return *this;
+  }
+
   ContextBuilder& SetCompilationPackage(const android::StringPiece& package) {
     context_->compilation_package_ = package.to_string();
     return *this;
@@ -123,15 +143,16 @@
     return *this;
   }
 
-  std::unique_ptr<ISymbolSource> Build() { return std::move(symbol_source_); }
+  std::unique_ptr<ISymbolSource> Build() {
+    return std::move(symbol_source_);
+  }
 
  private:
   class StaticSymbolSource : public ISymbolSource {
    public:
     StaticSymbolSource() = default;
 
-    std::unique_ptr<SymbolTable::Symbol> FindByName(
-        const ResourceName& name) override {
+    std::unique_ptr<SymbolTable::Symbol> FindByName(const ResourceName& name) override {
       auto iter = name_map_.find(name);
       if (iter != name_map_.end()) {
         return CloneSymbol(iter->second);
@@ -153,12 +174,10 @@
 
    private:
     std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) {
-      std::unique_ptr<SymbolTable::Symbol> clone =
-          util::make_unique<SymbolTable::Symbol>();
+      std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>();
       clone->id = sym->id;
       if (sym->attribute) {
-        clone->attribute =
-            std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr));
+        clone->attribute = std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr));
       }
       clone->is_public = sym->is_public;
       return clone;
@@ -167,8 +186,7 @@
     DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource);
   };
 
-  std::unique_ptr<StaticSymbolSource> symbol_source_ =
-      util::make_unique<StaticSymbolSource>();
+  std::unique_ptr<StaticSymbolSource> symbol_source_ = util::make_unique<StaticSymbolSource>();
 };
 
 }  // namespace test
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 20a4531..42786b5 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -22,6 +22,7 @@
 
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "android-base/stringprintf.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/TypeWrappers.h"
 
@@ -37,6 +38,8 @@
 
 using namespace android;
 
+using android::base::StringPrintf;
+
 namespace {
 
 /*
@@ -87,26 +90,35 @@
 bool BinaryResourceParser::Parse() {
   ResChunkPullParser parser(data_, data_len_);
 
-  bool error = false;
-  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
-    if (parser.chunk()->type != android::RES_TABLE_TYPE) {
-      context_->GetDiagnostics()->Warn(DiagMessage(source_)
-                                       << "unknown chunk of type '"
-                                       << (int)parser.chunk()->type << "'");
-      continue;
-    }
-
-    if (!ParseTable(parser.chunk())) {
-      error = true;
-    }
-  }
-
-  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
-    context_->GetDiagnostics()->Error(
-        DiagMessage(source_) << "corrupt resource table: " << parser.error());
+  if (!ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << "corrupt resources.arsc: " << parser.error());
     return false;
   }
-  return !error;
+
+  if (parser.chunk()->type != android::RES_TABLE_TYPE) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                      << StringPrintf("unknown chunk of type 0x%02x",
+                                                      (int)parser.chunk()->type));
+    return false;
+  }
+
+  if (!ParseTable(parser.chunk())) {
+    return false;
+  }
+
+  if (parser.Next() != ResChunkPullParser::Event::kEndDocument) {
+    if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+      context_->GetDiagnostics()->Warn(
+          DiagMessage(source_) << "invalid chunk trailing RES_TABLE_TYPE: " << parser.error());
+    } else {
+      context_->GetDiagnostics()->Warn(
+          DiagMessage(source_) << StringPrintf(
+              "unexpected chunk of type 0x%02x trailing RES_TABLE_TYPE",
+              (int)parser.chunk()->type));
+    }
+  }
+  return true;
 }
 
 /**
diff --git a/tools/aapt2/unflatten/ResChunkPullParser.cpp b/tools/aapt2/unflatten/ResChunkPullParser.cpp
index 5d71ff3..8d92bd9 100644
--- a/tools/aapt2/unflatten/ResChunkPullParser.cpp
+++ b/tools/aapt2/unflatten/ResChunkPullParser.cpp
@@ -16,9 +16,11 @@
 
 #include "unflatten/ResChunkPullParser.h"
 
+#include <inttypes.h>
 #include <cstddef>
 
 #include "android-base/logging.h"
+#include "android-base/stringprintf.h"
 #include "androidfw/ResourceTypes.h"
 
 #include "util/Util.h"
@@ -26,6 +28,13 @@
 namespace aapt {
 
 using android::ResChunk_header;
+using android::base::StringPrintf;
+
+static std::string ChunkHeaderDump(const ResChunk_header* header) {
+  return StringPrintf("(type=%02" PRIx16 " header_size=%" PRIu16 " size=%" PRIu32 ")",
+                      util::DeviceToHost16(header->type), util::DeviceToHost16(header->headerSize),
+                      util::DeviceToHost32(header->size));
+}
 
 ResChunkPullParser::Event ResChunkPullParser::Next() {
   if (!IsGoodEvent(event_)) {
@@ -53,18 +62,17 @@
     return (event_ = Event::kBadDocument);
   }
 
-  if (util::DeviceToHost16(current_chunk_->headerSize) <
-      sizeof(ResChunk_header)) {
+  if (util::DeviceToHost16(current_chunk_->headerSize) < sizeof(ResChunk_header)) {
     error_ = "chunk has too small header";
     current_chunk_ = nullptr;
     return (event_ = Event::kBadDocument);
   } else if (util::DeviceToHost32(current_chunk_->size) <
              util::DeviceToHost16(current_chunk_->headerSize)) {
-    error_ = "chunk's total size is smaller than header";
+    error_ = "chunk's total size is smaller than header " + ChunkHeaderDump(current_chunk_);
     current_chunk_ = nullptr;
     return (event_ = Event::kBadDocument);
   } else if (offset + util::DeviceToHost32(current_chunk_->size) > len_) {
-    error_ = "chunk's data extends past the end of the document";
+    error_ = "chunk's data extends past the end of the document " + ChunkHeaderDump(current_chunk_);
     current_chunk_ = nullptr;
     return (event_ = Event::kBadDocument);
   }
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 3fedea2..53501f9 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -259,14 +259,19 @@
 def verify_constants(clazz):
     """All static final constants must be FOO_NAME style."""
     if re.match("android\.R\.[a-z]+", clazz.fullname): return
+    if clazz.fullname.startswith("android.os.Build"): return
+    if clazz.fullname == "android.system.OsConstants": return
 
+    req = ["java.lang.String","byte","short","int","long","float","double","boolean","char"]
     for f in clazz.fields:
         if "static" in f.split and "final" in f.split:
             if re.match("[A-Z0-9_]+", f.name) is None:
                 error(clazz, f, "C2", "Constant field names must be FOO_NAME")
-            elif f.typ != "java.lang.String":
+            if f.typ != "java.lang.String":
                 if f.name.startswith("MIN_") or f.name.startswith("MAX_"):
                     warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
+            if f.typ in req and f.value is None:
+                error(clazz, f, None, "All constants must be defined at compile time")
 
 
 def verify_enums(clazz):
@@ -352,6 +357,7 @@
         if f.value is None: continue
         if f.name.startswith("EXTRA_"): continue
         if f.name == "SERVICE_INTERFACE" or f.name == "PROVIDER_INTERFACE": continue
+        if "INTERACTION" in f.name: continue
 
         if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
             if "_ACTION" in f.name or "ACTION_" in f.name or ".action." in f.value.lower():
@@ -447,10 +453,14 @@
         "android.app.Notification",
         "android.content.pm.ActivityInfo",
         "android.content.pm.ApplicationInfo",
+        "android.content.pm.ComponentInfo",
+        "android.content.pm.ResolveInfo",
         "android.content.pm.FeatureGroupInfo",
         "android.content.pm.InstrumentationInfo",
         "android.content.pm.PackageInfo",
         "android.content.pm.PackageItemInfo",
+        "android.content.res.Configuration",
+        "android.graphics.BitmapFactory.Options",
         "android.os.Message",
         "android.system.StructPollfd",
     ]
@@ -786,6 +796,10 @@
     for c in clazz.ctors:
         error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")
 
+    for m in clazz.methods:
+        if m.typ == clazz.fullname:
+            error(clazz, m, None, "Managers must always be obtained from Context")
+
 
 def verify_boxed(clazz):
     """Verifies that methods avoid boxed primitives."""
@@ -812,17 +826,19 @@
 def verify_static_utils(clazz):
     """Verifies that helper classes can't be constructed."""
     if clazz.fullname.startswith("android.opengl"): return
-    if re.match("android\.R\.[a-z]+", clazz.fullname): return
+    if clazz.fullname.startswith("android.R"): return
 
-    if len(clazz.fields) > 0: return
-    if len(clazz.methods) == 0: return
+    # Only care about classes with default constructors
+    if len(clazz.ctors) == 1 and len(clazz.ctors[0].args) == 0:
+        test = []
+        test.extend(clazz.fields)
+        test.extend(clazz.methods)
 
-    for m in clazz.methods:
-        if "static" not in m.split:
-            return
+        if len(test) == 0: return
+        for t in test:
+            if "static" not in t.split:
+                return
 
-    # At this point, we have no fields, and all methods are static
-    if len(clazz.ctors) > 0:
         error(clazz, None, None, "Fully-static utility classes must not have constructor")
 
 
@@ -920,6 +936,9 @@
         if len(m.args) > 1 and m.args[0] != "android.content.Context":
             if "android.content.Context" in m.args[1:]:
                 error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
+        if len(m.args) > 1 and m.args[0] != "android.content.ContentResolver":
+            if "android.content.ContentResolver" in m.args[1:]:
+                error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
 
 
 def verify_listener_last(clazz):
@@ -1001,6 +1020,112 @@
             warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
 
 
+def verify_runtime_exceptions(clazz):
+    """Verifies that runtime exceptions aren't listed in throws."""
+
+    banned = [
+        "java.lang.NullPointerException",
+        "java.lang.ClassCastException",
+        "java.lang.IndexOutOfBoundsException",
+        "java.lang.reflect.UndeclaredThrowableException",
+        "java.lang.reflect.MalformedParametersException",
+        "java.lang.reflect.MalformedParameterizedTypeException",
+        "java.lang.invoke.WrongMethodTypeException",
+        "java.lang.EnumConstantNotPresentException",
+        "java.lang.IllegalMonitorStateException",
+        "java.lang.SecurityException",
+        "java.lang.UnsupportedOperationException",
+        "java.lang.annotation.AnnotationTypeMismatchException",
+        "java.lang.annotation.IncompleteAnnotationException",
+        "java.lang.TypeNotPresentException",
+        "java.lang.IllegalStateException",
+        "java.lang.ArithmeticException",
+        "java.lang.IllegalArgumentException",
+        "java.lang.ArrayStoreException",
+        "java.lang.NegativeArraySizeException",
+        "java.util.MissingResourceException",
+        "java.util.EmptyStackException",
+        "java.util.concurrent.CompletionException",
+        "java.util.concurrent.RejectedExecutionException",
+        "java.util.IllformedLocaleException",
+        "java.util.ConcurrentModificationException",
+        "java.util.NoSuchElementException",
+        "java.io.UncheckedIOException",
+        "java.time.DateTimeException",
+        "java.security.ProviderException",
+        "java.nio.BufferUnderflowException",
+        "java.nio.BufferOverflowException",
+    ]
+
+    test = []
+    test.extend(clazz.ctors)
+    test.extend(clazz.methods)
+
+    for t in test:
+        if " throws " not in t.raw: continue
+        throws = t.raw[t.raw.index(" throws "):]
+        for b in banned:
+            if b in throws:
+                error(clazz, t, None, "Methods must not mention RuntimeException subclasses in throws clauses")
+
+
+def verify_error(clazz):
+    """Verifies that we always use Exception instead of Error."""
+    if not clazz.extends: return
+    if clazz.extends.endswith("Error"):
+        error(clazz, None, None, "Trouble must be reported through an Exception, not Error")
+    if clazz.extends.endswith("Exception") and not clazz.name.endswith("Exception"):
+        error(clazz, None, None, "Exceptions must be named FooException")
+
+
+def verify_units(clazz):
+    """Verifies that we use consistent naming for units."""
+
+    # If we find K, recommend replacing with V
+    bad = {
+        "Ns": "Nanos",
+        "Ms": "Millis or Micros",
+        "Sec": "Seconds", "Secs": "Seconds",
+        "Hr": "Hours", "Hrs": "Hours",
+        "Mo": "Months", "Mos": "Months",
+        "Yr": "Years", "Yrs": "Years",
+        "Byte": "Bytes", "Space": "Bytes",
+    }
+
+    for m in clazz.methods:
+        if m.typ not in ["short","int","long"]: continue
+        for k, v in bad.iteritems():
+            if m.name.endswith(k):
+                error(clazz, m, None, "Expected method name units to be " + v)
+        if m.name.endswith("Nanos") or m.name.endswith("Micros"):
+            warn(clazz, m, None, "Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision")
+        if m.name.endswith("Seconds"):
+            error(clazz, m, None, "Returned time values must be in milliseconds")
+
+    for m in clazz.methods:
+        typ = m.typ
+        if typ == "void":
+            if len(m.args) != 1: continue
+            typ = m.args[0]
+
+        if m.name.endswith("Fraction") and typ != "float":
+            error(clazz, m, None, "Fractions must use floats")
+        if m.name.endswith("Percentage") and typ != "int":
+            error(clazz, m, None, "Percentage must use ints")
+
+
+def verify_closable(clazz):
+    """Verifies that classes are AutoClosable."""
+    if "implements java.lang.AutoCloseable" in clazz.raw: return
+    if "implements java.io.Closeable" in clazz.raw: return
+
+    for m in clazz.methods:
+        if len(m.args) > 0: continue
+        if m.name in ["close","release","destroy","finish","finalize","disconnect","shutdown","stop","free","quit"]:
+            warn(clazz, m, None, "Classes that release resources should implement AutoClosable and CloseGuard")
+            return
+
+
 def examine_clazz(clazz):
     """Find all style issues in the given class."""
     if clazz.pkg.name.startswith("java"): return
@@ -1048,6 +1173,10 @@
     verify_files(clazz)
     verify_manager_list(clazz)
     verify_abstract_inner(clazz)
+    verify_runtime_exceptions(clazz)
+    verify_error(clazz)
+    verify_units(clazz)
+    verify_closable(clazz)
 
 
 def examine_stream(stream):
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index f5b9042..c0475ee 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -428,7 +428,8 @@
     _text_variation_sequences, _emoji_variation_sequences = sequences
     _emoji_sequences = parse_unicode_datafile(
         path.join(ucd_path, 'emoji-sequences.txt'))
-
+    _emoji_sequences.update(parse_unicode_datafile(
+        path.join(ucd_path, 'additions', 'emoji-sequences.txt')))
     _emoji_zwj_sequences = parse_unicode_datafile(
         path.join(ucd_path, 'emoji-zwj-sequences.txt'))
     _emoji_zwj_sequences.update(parse_unicode_datafile(
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index bf5c42b..c7e1fc7 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -38,10 +38,10 @@
  *     {@link #createNetworkSpecifierOpen(PeerHandle)} or
  *     {@link #createNetworkSpecifierPassphrase(PeerHandle, String)}.
  * </ul>
- * The {@link #destroy()} method must be called to destroy discovery sessions once they are
+ * The {@link #close()} method must be called to destroy discovery sessions once they are
  * no longer needed.
  */
-public class DiscoverySession {
+public class DiscoverySession implements AutoCloseable {
     private static final String TAG = "DiscoverySession";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
@@ -96,7 +96,8 @@
      *     exception is a session for which we received a termination callback,
      *     {@link DiscoverySessionCallback#onSessionTerminated()}.
      */
-    public void destroy() {
+    @Override
+    public void close() {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.w(TAG, "destroy: called post GC on WifiAwareManager");
@@ -131,7 +132,7 @@
         try {
             if (!mTerminated) {
                 mCloseGuard.warnIfOpen();
-                destroy();
+                close();
             }
         } finally {
             super.finalize();
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
index 334205b..d8667e6 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySessionCallback.java
@@ -84,7 +84,7 @@
 
     /**
      * Called when a discovery session (publish or subscribe) terminates. Termination may be due
-     * to user-request (either directly through {@link DiscoverySession#destroy()} or
+     * to user-request (either directly through {@link DiscoverySession#close()} or
      * application-specified expiration, e.g. {@link PublishConfig.Builder#setTtlSec(int)}
      * or {@link SubscribeConfig.Builder#setTtlSec(int)}).
      */
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index 1ce12f3..0f1e992 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -314,7 +314,7 @@
          * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link DiscoverySession#destroy()} is
+         *     Session will be terminated when {@link DiscoverySession#close()} is
          *     called.
          *
          * @param ttlSec Lifetime of a publish session in seconds.
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 97a6a3f..31e7e8e 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -61,27 +61,6 @@
     public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
 
     /** @hide */
-    @IntDef({
-            MATCH_STYLE_FIRST_ONLY, MATCH_STYLE_ALL })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MatchStyles {
-    }
-
-    /**
-     * Specifies that only the first match of a set of identical matches (same
-     * publish) will be reported to the subscriber. Configuration is done using
-     * {@link SubscribeConfig.Builder#setMatchStyle(int)}.
-     */
-    public static final int MATCH_STYLE_FIRST_ONLY = 0;
-
-    /**
-     * Specifies that all matches of a set of identical matches (same publish)
-     * will be reported to the subscriber. Configuration is done using
-     * {@link SubscribeConfig.Builder#setMatchStyle(int)}.
-     */
-    public static final int MATCH_STYLE_ALL = 1;
-
-    /** @hide */
     public final byte[] mServiceName;
 
     /** @hide */
@@ -97,21 +76,17 @@
     public final int mTtlSec;
 
     /** @hide */
-    public final int mMatchStyle;
-
-    /** @hide */
     public final boolean mEnableTerminateNotification;
 
     /** @hide */
     public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
-            int subscribeType, int ttlSec, int matchStyle,
+            int subscribeType, int ttlSec,
             boolean enableTerminateNotification) {
         mServiceName = serviceName;
         mServiceSpecificInfo = serviceSpecificInfo;
         mMatchFilter = matchFilter;
         mSubscribeType = subscribeType;
         mTtlSec = ttlSec;
-        mMatchStyle = matchStyle;
         mEnableTerminateNotification = enableTerminateNotification;
     }
 
@@ -121,8 +96,8 @@
                 (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
                 + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
                 mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
-                + ", mTtlSec=" + mTtlSec + ", mMatchType="
-                + mMatchStyle + ", mEnableTerminateNotification=" + mEnableTerminateNotification
+                + ", mTtlSec=" + mTtlSec
+                + ", mEnableTerminateNotification=" + mEnableTerminateNotification
                 + "]";
     }
 
@@ -138,7 +113,6 @@
         dest.writeByteArray(mMatchFilter);
         dest.writeInt(mSubscribeType);
         dest.writeInt(mTtlSec);
-        dest.writeInt(mMatchStyle);
         dest.writeInt(mEnableTerminateNotification ? 1 : 0);
     }
 
@@ -155,11 +129,10 @@
             byte[] matchFilter = in.createByteArray();
             int subscribeType = in.readInt();
             int ttlSec = in.readInt();
-            int matchStyle = in.readInt();
             boolean enableTerminateNotification = in.readInt() != 0;
 
             return new SubscribeConfig(serviceName, ssi, matchFilter, subscribeType,
-                    ttlSec, matchStyle, enableTerminateNotification);
+                    ttlSec, enableTerminateNotification);
         }
     };
 
@@ -178,7 +151,7 @@
         return Arrays.equals(mServiceName, lhs.mServiceName) && Arrays.equals(mServiceSpecificInfo,
                 lhs.mServiceSpecificInfo) && Arrays.equals(mMatchFilter, lhs.mMatchFilter)
                 && mSubscribeType == lhs.mSubscribeType
-                && mTtlSec == lhs.mTtlSec && mMatchStyle == lhs.mMatchStyle
+                && mTtlSec == lhs.mTtlSec
                 && mEnableTerminateNotification == lhs.mEnableTerminateNotification;
     }
 
@@ -191,7 +164,6 @@
         result = 31 * result + Arrays.hashCode(mMatchFilter);
         result = 31 * result + mSubscribeType;
         result = 31 * result + mTtlSec;
-        result = 31 * result + mMatchStyle;
         result = 31 * result + (mEnableTerminateNotification ? 1 : 0);
 
         return result;
@@ -217,10 +189,6 @@
         if (mTtlSec < 0) {
             throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
         }
-        if (mMatchStyle != MATCH_STYLE_FIRST_ONLY && mMatchStyle != MATCH_STYLE_ALL) {
-            throw new IllegalArgumentException(
-                    "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
-        }
 
         if (characteristics != null) {
             int maxServiceNameLength = characteristics.getMaxServiceNameLength();
@@ -252,7 +220,6 @@
         private byte[] mMatchFilter;
         private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE;
         private int mTtlSec = 0;
-        private int mMatchStyle = MATCH_STYLE_ALL;
         private boolean mEnableTerminateNotification = true;
 
         /**
@@ -346,7 +313,7 @@
          * {@link DiscoverySessionCallback#onSessionTerminated()}.
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link DiscoverySession#destroy()} is
+         *     Session will be terminated when {@link DiscoverySession#close()} is
          *     called.
          *
          * @param ttlSec Lifetime of a subscribe session in seconds.
@@ -363,28 +330,6 @@
         }
 
         /**
-         * Sets the match style of the subscription - how are matches from a
-         * single match session (corresponding to the same publish action on the
-         * peer) reported to the host (using the
-         * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[],
-         * java.util.List)}). The options are: only report the first match and ignore the rest
-         * {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single
-         * match {@link SubscribeConfig#MATCH_STYLE_ALL} (the default).
-         *
-         * @param matchStyle The reporting style for the discovery match.
-         * @return The builder to facilitate chaining
-         *         {@code builder.setXXX(..).setXXX(..)}.
-         */
-        public Builder setMatchStyle(@MatchStyles int matchStyle) {
-            if (matchStyle != MATCH_STYLE_FIRST_ONLY && matchStyle != MATCH_STYLE_ALL) {
-                throw new IllegalArgumentException(
-                        "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
-            }
-            mMatchStyle = matchStyle;
-            return this;
-        }
-
-        /**
          * Configure whether a subscribe terminate notification
          * {@link DiscoverySessionCallback#onSessionTerminated()} is reported
          * back to the callback.
@@ -406,7 +351,7 @@
          */
         public SubscribeConfig build() {
             return new SubscribeConfig(mServiceName, mServiceSpecificInfo, mMatchFilter,
-                    mSubscribeType, mTtlSec, mMatchStyle,
+                    mSubscribeType, mTtlSec,
                     mEnableTerminateNotification);
         }
     }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 3fcbd4b..d3ed792 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -82,7 +82,7 @@
  *     discovery or connection setup only after receiving confirmation that Aware attach
  *     succeeded - {@link AttachCallback#onAttached(WifiAwareSession)}. When an
  *     application is finished using Aware it <b>must</b> use the
- *     {@link WifiAwareSession#destroy()} API to indicate to the Aware service that the device
+ *     {@link WifiAwareSession#close()} API to indicate to the Aware service that the device
  *     may detach from the Aware cluster. The device will actually disable Aware once the last
  *     application detaches.
  * <p>
@@ -104,7 +104,7 @@
  *     also be used to send messages using the
  *     {@link DiscoverySession#sendMessage(PeerHandle, int, byte[])} APIs. When an
  *     application is finished with a discovery session it <b>must</b> terminate it using the
- *     {@link DiscoverySession#destroy()} API.
+ *     {@link DiscoverySession#close()} API.
  * <p>
  *    Creating connections between Aware devices is managed by the standard
  *    {@link ConnectivityManager#requestNetwork(NetworkRequest,
@@ -215,7 +215,7 @@
      * create connections to peers. The device will attach to an existing cluster if it can find
      * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
      * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiAwareSession#destroy()} when done with the
+     * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
      * Wi-Fi Aware object.
      * <p>
      * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
@@ -237,7 +237,7 @@
      * create connections to peers. The device will attach to an existing cluster if it can find
      * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
      * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiAwareSession#destroy()} when done with the
+     * An application <b>must</b> call {@link WifiAwareSession#close()} when done with the
      * Wi-Fi Aware object.
      * <p>
      * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index ac3a6bb..4e060d5 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -33,7 +33,7 @@
  * This class represents a Wi-Fi Aware session - an attachment to the Wi-Fi Aware service through
  * which the app can execute discovery operations.
  */
-public class WifiAwareSession {
+public class WifiAwareSession implements AutoCloseable {
     private static final String TAG = "WifiAwareSession";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
@@ -67,7 +67,7 @@
      * An application may re-attach after a destroy using
      * {@link WifiAwareManager#attach(AttachCallback, Handler)} .
      */
-    public void destroy() {
+    public void close() {
         WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
             Log.w(TAG, "destroy: called post GC on WifiAwareManager");
@@ -85,7 +85,7 @@
         try {
             if (!mTerminated) {
                 mCloseGuard.warnIfOpen();
-                destroy();
+                close();
             }
         } finally {
             super.finalize();
@@ -110,7 +110,7 @@
      * on the {@code callback} object. The resulting publish session can be modified using
      * {@link PublishDiscoverySession#updatePublish(PublishConfig)}.
      * <p>
-     *      An application must use the {@link DiscoverySession#destroy()} to
+     *      An application must use the {@link DiscoverySession#close()} to
      *      terminate the publish discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -156,7 +156,7 @@
      * on the {@code callback} object. The resulting subscribe session can be modified using
      * {@link SubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
      * <p>
-     *      An application must use the {@link DiscoverySession#destroy()} to
+     *      An application must use the {@link DiscoverySession#close()} to
      *      terminate the subscribe discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 72a6a7a..694b911 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -150,7 +150,7 @@
         inOrder.verify(mockAwareService).publish(eq(clientId), eq(publishConfig), any());
 
         // (3) disconnect
-        session.destroy();
+        session.close();
         inOrder.verify(mockAwareService).disconnect(eq(clientId), eq(binder.getValue()));
 
         // (4) try publishing again - fails silently
@@ -329,7 +329,7 @@
         inOrder.verify(mockSessionCallback).onSessionConfigFailed();
 
         // (5) terminate
-        publishSession.getValue().destroy();
+        publishSession.getValue().close();
         mMockLooper.dispatchAll();
         inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
 
@@ -466,7 +466,7 @@
         inOrder.verify(mockSessionCallback).onSessionConfigFailed();
 
         // (5) terminate
-        subscribeSession.getValue().destroy();
+        subscribeSession.getValue().close();
         mMockLooper.dispatchAll();
         inOrder.verify(mockAwareService).terminateSession(clientId, sessionId);
 
@@ -687,8 +687,6 @@
         collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
                 equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
         collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
-        collector.checkThat("mMatchStyle", subscribeConfig.mMatchStyle,
-                equalTo(SubscribeConfig.MATCH_STYLE_ALL));
         collector.checkThat("mEnableTerminateNotification",
                 subscribeConfig.mEnableTerminateNotification, equalTo(true));
     }
@@ -701,14 +699,13 @@
         final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
         final int subscribeCount = 10;
         final int subscribeTtl = 15;
-        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
         final boolean enableTerminateNotification = false;
 
         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
                 .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
                         new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
                 .setSubscribeType(subscribeType)
-                .setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+                .setTtlSec(subscribeTtl)
                 .setTerminateNotificationEnabled(enableTerminateNotification).build();
 
         collector.checkThat("mServiceName", serviceName.getBytes(),
@@ -719,7 +716,6 @@
         collector.checkThat("mSubscribeType", subscribeType,
                 equalTo(subscribeConfig.mSubscribeType));
         collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
-        collector.checkThat("mMatchStyle", matchStyle, equalTo(subscribeConfig.mMatchStyle));
         collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
                 equalTo(subscribeConfig.mEnableTerminateNotification));
     }
@@ -730,16 +726,14 @@
         final String serviceSpecificInfo = "long arbitrary string with some info";
         final byte[] matchFilter = { 1, 16, 1, 22 };
         final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
-        final int subscribeCount = 10;
         final int subscribeTtl = 15;
-        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
         final boolean enableTerminateNotification = true;
 
         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
                 .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
                         new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
                 .setSubscribeType(subscribeType)
-                .setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+                .setTtlSec(subscribeTtl)
                 .setTerminateNotificationEnabled(enableTerminateNotification).build();
 
         Parcel parcelW = Parcel.obtain();
@@ -765,14 +759,6 @@
         new SubscribeConfig.Builder().setTtlSec(-100);
     }
 
-    /**
-     * Validate that a bad match style configuration throws an exception.
-     */
-    @Test(expected = IllegalArgumentException.class)
-    public void testSubscribeConfigBuilderBadMatchStyle() {
-        new SubscribeConfig.Builder().setMatchStyle(10);
-    }
-
     /*
      * PublishConfig Tests
      */