Merge "Only show progress log every 10%" into oc-dev
diff --git a/Android.mk b/Android.mk
index 991d185..e58f306 100644
--- a/Android.mk
+++ b/Android.mk
@@ -143,7 +143,6 @@
 	core/java/android/bluetooth/IBluetoothGatt.aidl \
 	core/java/android/bluetooth/IBluetoothGattCallback.aidl \
 	core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
-	core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
 	core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl \
 	core/java/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \
 	core/java/android/bluetooth/le/IScannerCallback.aidl \
@@ -908,7 +907,6 @@
 	ext \
 	icu4j \
 	framework \
-	telephony-common \
 	voip-common
 
 framework_docs_LOCAL_JAVA_LIBRARIES := \
@@ -923,6 +921,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 +951,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 35726f1..0e9f27e 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
@@ -766,6 +766,7 @@
     field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
     field public static final int itemPadding = 16843565; // 0x101032d
     field public static final int itemTextAppearance = 16843052; // 0x101012c
+    field public static final int justificationMode = 16844138; // 0x101056a
     field public static final int keepScreenOn = 16843286; // 0x1010216
     field public static final int key = 16843240; // 0x10101e8
     field public static final int keyBackground = 16843315; // 0x1010233
@@ -2836,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
@@ -2854,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
@@ -3634,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();
@@ -3759,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);
@@ -5124,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();
@@ -5199,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
@@ -5345,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);
@@ -6659,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();
@@ -6892,15 +6896,15 @@
   public abstract class JobServiceEngine {
     ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
-    method public final void jobFinished(android.app.job.JobParameters, boolean);
+    method public void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
     method public abstract boolean onStopJob(android.app.job.JobParameters);
   }
 
   public final class JobWorkItem implements android.os.Parcelable {
     ctor public JobWorkItem(android.content.Intent);
-    ctor public JobWorkItem(android.os.Parcel);
     method public int describeContents();
+    method public int getDeliveryCount();
     method public android.content.Intent getIntent();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
@@ -6925,6 +6929,7 @@
 
   public final class ExternalStorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getAudioBytes();
     method public long getImageBytes();
     method public long getTotalBytes();
@@ -7595,6 +7600,7 @@
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+    method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
     method public boolean createBond();
     method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -8932,7 +8938,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
@@ -8946,7 +8952,6 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
-    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -13777,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);
@@ -13812,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();
   }
@@ -14752,16 +14745,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
@@ -22779,7 +22772,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
@@ -23644,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();
@@ -23670,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);
   }
 
@@ -24785,7 +24778,6 @@
   }
 
   public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
-    ctor public TvContract.WatchNextPrograms();
     field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
     field public static final int ASPECT_RATIO_1_1 = 3; // 0x3
     field public static final int ASPECT_RATIO_2_3 = 4; // 0x4
@@ -25501,66 +25493,6 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
-  public final class IpSecAlgorithm implements android.os.Parcelable {
-    ctor public IpSecAlgorithm(java.lang.String, byte[]);
-    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
-    method public int describeContents();
-    method public byte[] getKey();
-    method public java.lang.String getName();
-    method public int getTruncationLengthBits();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
-    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
-    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
-    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
-    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
-    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
-    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
-  }
-
-  public final class IpSecManager {
-    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
-  }
-
-  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
-  }
-
-  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
-    method public void close();
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
-    method public void close() throws java.io.IOException;
-    method public int getPort();
-    method public java.io.FileDescriptor getSocket();
-  }
-
-  public final class IpSecTransform implements java.lang.AutoCloseable {
-    method public void close();
-    field public static final int DIRECTION_IN = 0; // 0x0
-    field public static final int DIRECTION_OUT = 1; // 0x1
-  }
-
-  public static class IpSecTransform.Builder {
-    ctor public IpSecTransform.Builder(android.content.Context);
-    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
-    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
-  }
-
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -26738,10 +26670,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[]);
   }
 
@@ -26793,8 +26725,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
   }
@@ -26803,7 +26733,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);
@@ -26825,10 +26754,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);
   }
@@ -34498,7 +34427,7 @@
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
     method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
+    method public static void requestFonts(android.content.Context, android.graphics.fonts.FontRequest, android.os.Handler, android.os.CancellationSignal, android.provider.FontsContract.FontRequestCallback);
   }
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -34929,7 +34858,7 @@
     field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
-    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.action.MANAGE_UNKNOWN_APP_SOURCES";
+    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.MANAGE_UNKNOWN_APP_SOURCES";
     field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
@@ -34943,6 +34872,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";
@@ -37034,15 +36964,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";
   }
@@ -37096,9 +37023,9 @@
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
+    method public java.util.ArrayList<android.service.autofill.FillContext> getFillContexts();
     method public int getFlags();
     method public int getId();
-    method public android.app.assist.AssistStructure getStructure();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
@@ -37116,7 +37043,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);
   }
@@ -37131,6 +37057,8 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
+    field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
+    field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -37144,7 +37072,7 @@
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
-    method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
+    method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
   }
 
@@ -39088,7 +39016,6 @@
   }
 
   public static final class Connection.RttModifyStatus {
-    ctor public Connection.RttModifyStatus();
     field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
     field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
     field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
@@ -40238,10 +40165,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);
@@ -40315,7 +40244,6 @@
     field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
     field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
     field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
-    field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
     field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
@@ -40333,8 +40261,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";
   }
 
@@ -42733,7 +42659,7 @@
     method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
     field public static final int ALL = 15; // 0xf
     field public static final int EMAIL_ADDRESSES = 2; // 0x2
-    field public static final deprecated int MAP_ADDRESSES = 8; // 0x8
+    field public static final int MAP_ADDRESSES = 8; // 0x8
     field public static final int PHONE_NUMBERS = 4; // 0x4
     field public static final int WEB_URLS = 1; // 0x1
     field public static final android.text.util.Linkify.MatchFilter sPhoneNumberMatchFilter;
@@ -45426,6 +45352,7 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public java.lang.String[] getAutofillHints();
+    method public final android.view.autofill.AutofillId getAutofillId();
     method public int getAutofillType();
     method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
@@ -46548,6 +46475,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
+    method public abstract android.view.autofill.AutofillId getAutofillId();
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46561,7 +46489,8 @@
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHints(java.lang.String[]);
-    method public abstract void setAutofillId(android.view.ViewStructure, int);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId, int);
     method public abstract void setAutofillOptions(java.lang.CharSequence[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
@@ -46591,8 +46520,8 @@
     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 void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -47155,7 +47084,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();
@@ -47836,6 +47767,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);
@@ -47850,7 +47783,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 {
@@ -48284,12 +48216,7 @@
 
 package android.view.textclassifier {
 
-  public abstract interface LinksInfo {
-    method public abstract boolean apply(java.lang.CharSequence);
-  }
-
   public final class TextClassificationManager {
-    method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
     method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
@@ -48317,7 +48244,6 @@
   }
 
   public abstract interface TextClassifier {
-    method public abstract android.view.textclassifier.LinksInfo getLinks(java.lang.CharSequence, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextClassificationResult getTextClassificationResult(java.lang.CharSequence, int, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int, android.os.LocaleList);
     field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -48328,20 +48254,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public final class TextLanguage {
-    method public float getConfidenceScore(java.util.Locale);
-    method public int getEndIndex();
-    method public java.util.Locale getLanguage(int);
-    method public int getLanguageCount();
-    method public int getStartIndex();
-  }
-
-  public static final class TextLanguage.Builder {
-    ctor public TextLanguage.Builder(int, int);
-    method public android.view.textclassifier.TextLanguage build();
-    method public android.view.textclassifier.TextLanguage.Builder setLanguage(java.util.Locale, float);
-  }
-
   public final class TextSelection {
     method public float getConfidenceScore(java.lang.String);
     method public java.lang.String getEntity(int);
@@ -48993,7 +48905,7 @@
     method public void documentHasImages(android.os.Message);
     method public static void enableSlowWholeDocumentDraw();
     method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
-    method public static deprecated java.lang.String findAddress(java.lang.String);
+    method public static java.lang.String findAddress(java.lang.String);
     method public deprecated int findAll(java.lang.String);
     method public void findAllAsync(java.lang.String);
     method public void findNext(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 189536d..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);
   }
 
@@ -126,6 +125,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
@@ -346,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 b9125bf..ade3592 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
@@ -884,6 +885,7 @@
     field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
     field public static final int itemPadding = 16843565; // 0x101032d
     field public static final int itemTextAppearance = 16843052; // 0x101012c
+    field public static final int justificationMode = 16844138; // 0x101056a
     field public static final int keepScreenOn = 16843286; // 0x1010216
     field public static final int key = 16843240; // 0x10101e8
     field public static final int keyBackground = 16843315; // 0x1010233
@@ -2963,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
@@ -2981,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
@@ -3765,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();
@@ -3892,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);
@@ -5303,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();
@@ -5382,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
@@ -5528,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);
@@ -6904,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();
@@ -7328,15 +7333,15 @@
   public abstract class JobServiceEngine {
     ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
-    method public final void jobFinished(android.app.job.JobParameters, boolean);
+    method public void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
     method public abstract boolean onStopJob(android.app.job.JobParameters);
   }
 
   public final class JobWorkItem implements android.os.Parcelable {
     ctor public JobWorkItem(android.content.Intent);
-    ctor public JobWorkItem(android.os.Parcel);
     method public int describeContents();
+    method public int getDeliveryCount();
     method public android.content.Intent getIntent();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
@@ -7390,6 +7395,7 @@
 
   public final class ExternalStorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getAudioBytes();
     method public long getImageBytes();
     method public long getTotalBytes();
@@ -8067,6 +8073,7 @@
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+    method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
     method public boolean createBond();
     method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -9436,7 +9443,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";
@@ -9452,7 +9459,6 @@
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
-    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -14551,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);
@@ -14586,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();
   }
@@ -15526,16 +15520,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
@@ -24615,7 +24609,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
@@ -25491,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();
@@ -25517,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);
   }
 
@@ -26782,7 +26776,6 @@
   }
 
   public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
-    ctor public TvContract.WatchNextPrograms();
     field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
     field public static final int ASPECT_RATIO_1_1 = 3; // 0x3
     field public static final int ASPECT_RATIO_2_3 = 4; // 0x4
@@ -27690,68 +27683,6 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
-  public final class IpSecAlgorithm implements android.os.Parcelable {
-    ctor public IpSecAlgorithm(java.lang.String, byte[]);
-    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
-    method public int describeContents();
-    method public byte[] getKey();
-    method public java.lang.String getName();
-    method public int getTruncationLengthBits();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
-    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
-    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
-    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
-    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
-    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
-    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
-  }
-
-  public final class IpSecManager {
-    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
-  }
-
-  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
-  }
-
-  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
-    method public void close();
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
-    method public void close() throws java.io.IOException;
-    method public int getPort();
-    method public java.io.FileDescriptor getSocket();
-  }
-
-  public final class IpSecTransform implements java.lang.AutoCloseable {
-    method public void close();
-    field public static final int DIRECTION_IN = 0; // 0x0
-    field public static final int DIRECTION_OUT = 1; // 0x1
-  }
-
-  public static class IpSecTransform.Builder {
-    ctor public IpSecTransform.Builder(android.content.Context);
-    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
-    method public android.net.IpSecTransform.Builder setNattKeepalive(int);
-    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
-    method public android.net.IpSecTransform.Builder setUnderlyingNetwork(android.net.Network);
-  }
-
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -27965,13 +27896,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);
   }
 
@@ -28038,7 +27969,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();
@@ -28053,7 +27984,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[]);
@@ -28063,7 +27994,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();
@@ -29481,11 +29412,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[]);
   }
 
@@ -29537,8 +29468,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
   }
@@ -29547,7 +29476,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);
@@ -29569,11 +29497,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);
   }
@@ -37487,7 +37415,7 @@
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
     method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
+    method public static void requestFonts(android.content.Context, android.graphics.fonts.FontRequest, android.os.Handler, android.os.CancellationSignal, android.provider.FontsContract.FontRequestCallback);
   }
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -38021,7 +37949,7 @@
     field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
-    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.action.MANAGE_UNKNOWN_APP_SOURCES";
+    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.MANAGE_UNKNOWN_APP_SOURCES";
     field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
@@ -38035,6 +37963,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";
@@ -38095,7 +38024,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";
@@ -40149,15 +40077,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";
   }
@@ -40211,9 +40136,9 @@
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
+    method public java.util.ArrayList<android.service.autofill.FillContext> getFillContexts();
     method public int getFlags();
     method public int getId();
-    method public android.app.assist.AssistStructure getStructure();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
@@ -40231,7 +40156,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);
   }
@@ -40246,6 +40170,8 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
+    field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
+    field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -40259,7 +40185,7 @@
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
-    method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
+    method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
   }
 
@@ -40767,6 +40693,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";
   }
 
@@ -42377,7 +42304,6 @@
   }
 
   public static final class Connection.RttModifyStatus {
-    ctor public Connection.RttModifyStatus();
     field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
     field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
     field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
@@ -43731,6 +43657,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();
@@ -43766,6 +43693,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);
@@ -43775,6 +43703,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);
@@ -43822,7 +43751,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
@@ -43859,7 +43790,6 @@
     field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
     field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
     field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
-    field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
     field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
@@ -46310,7 +46240,7 @@
     method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
     field public static final int ALL = 15; // 0xf
     field public static final int EMAIL_ADDRESSES = 2; // 0x2
-    field public static final deprecated int MAP_ADDRESSES = 8; // 0x8
+    field public static final int MAP_ADDRESSES = 8; // 0x8
     field public static final int PHONE_NUMBERS = 4; // 0x4
     field public static final int WEB_URLS = 1; // 0x1
     field public static final android.text.util.Linkify.MatchFilter sPhoneNumberMatchFilter;
@@ -49004,6 +48934,7 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public java.lang.String[] getAutofillHints();
+    method public final android.view.autofill.AutofillId getAutofillId();
     method public int getAutofillType();
     method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
@@ -50126,6 +50057,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
+    method public abstract android.view.autofill.AutofillId getAutofillId();
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -50139,7 +50071,8 @@
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHints(java.lang.String[]);
-    method public abstract void setAutofillId(android.view.ViewStructure, int);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId, int);
     method public abstract void setAutofillOptions(java.lang.CharSequence[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
@@ -50169,8 +50102,8 @@
     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 void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -50736,7 +50669,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();
@@ -51417,6 +51352,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);
@@ -51431,7 +51368,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 {
@@ -51865,12 +51801,7 @@
 
 package android.view.textclassifier {
 
-  public abstract interface LinksInfo {
-    method public abstract boolean apply(java.lang.CharSequence);
-  }
-
   public final class TextClassificationManager {
-    method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
     method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
@@ -51898,7 +51829,6 @@
   }
 
   public abstract interface TextClassifier {
-    method public abstract android.view.textclassifier.LinksInfo getLinks(java.lang.CharSequence, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextClassificationResult getTextClassificationResult(java.lang.CharSequence, int, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int, android.os.LocaleList);
     field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -51909,20 +51839,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public final class TextLanguage {
-    method public float getConfidenceScore(java.util.Locale);
-    method public int getEndIndex();
-    method public java.util.Locale getLanguage(int);
-    method public int getLanguageCount();
-    method public int getStartIndex();
-  }
-
-  public static final class TextLanguage.Builder {
-    ctor public TextLanguage.Builder(int, int);
-    method public android.view.textclassifier.TextLanguage build();
-    method public android.view.textclassifier.TextLanguage.Builder setLanguage(java.util.Locale, float);
-  }
-
   public final class TextSelection {
     method public float getConfidenceScore(java.lang.String);
     method public java.lang.String getEntity(int);
@@ -52667,7 +52583,7 @@
     method public void documentHasImages(android.os.Message);
     method public static void enableSlowWholeDocumentDraw();
     method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
-    method public static deprecated java.lang.String findAddress(java.lang.String);
+    method public static java.lang.String findAddress(java.lang.String);
     method public deprecated int findAll(java.lang.String);
     method public void findAllAsync(java.lang.String);
     method public void findNext(boolean);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 559ce12..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);
   }
 
@@ -124,6 +123,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
@@ -340,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 3675bd8..109a75e 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
@@ -766,6 +766,7 @@
     field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131
     field public static final int itemPadding = 16843565; // 0x101032d
     field public static final int itemTextAppearance = 16843052; // 0x101012c
+    field public static final int justificationMode = 16844138; // 0x101056a
     field public static final int keepScreenOn = 16843286; // 0x1010216
     field public static final int key = 16843240; // 0x10101e8
     field public static final int keyBackground = 16843315; // 0x1010233
@@ -2836,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
@@ -2854,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
@@ -3636,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();
@@ -3761,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);
@@ -5137,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();
@@ -5212,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
@@ -5358,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);
@@ -6689,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();
@@ -6922,15 +6926,15 @@
   public abstract class JobServiceEngine {
     ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
-    method public final void jobFinished(android.app.job.JobParameters, boolean);
+    method public void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
     method public abstract boolean onStopJob(android.app.job.JobParameters);
   }
 
   public final class JobWorkItem implements android.os.Parcelable {
     ctor public JobWorkItem(android.content.Intent);
-    ctor public JobWorkItem(android.os.Parcel);
     method public int describeContents();
+    method public int getDeliveryCount();
     method public android.content.Intent getIntent();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
@@ -6955,6 +6959,7 @@
 
   public final class ExternalStorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getAudioBytes();
     method public long getImageBytes();
     method public long getTotalBytes();
@@ -7626,6 +7631,7 @@
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
     method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+    method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
     method public boolean createBond();
     method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
     method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -8965,7 +8971,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
@@ -8979,7 +8985,6 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
-    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -13819,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);
@@ -13854,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();
   }
@@ -13997,6 +13990,7 @@
     method public void draw(android.graphics.Canvas);
     method public int getColor();
     method public int getOpacity();
+    method public android.graphics.Xfermode getXfermode();
     method public void setAlpha(int);
     method public void setColor(int);
     method public void setColorFilter(android.graphics.ColorFilter);
@@ -14797,16 +14791,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
@@ -22886,7 +22880,7 @@
     method public void releaseDrm() throws android.media.MediaPlayer.NoDrmSchemeException;
     method public void reset();
     method public void restoreKeys(byte[]) throws android.media.MediaPlayer.NoDrmSchemeException;
-    method public void seekTo(int, int) throws java.lang.IllegalStateException;
+    method public void seekTo(long, int);
     method public void seekTo(int) throws java.lang.IllegalStateException;
     method public void selectTrack(int) throws java.lang.IllegalStateException;
     method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
@@ -23751,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();
@@ -23777,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);
   }
 
@@ -24892,7 +24886,6 @@
   }
 
   public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
-    ctor public TvContract.WatchNextPrograms();
     field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
     field public static final int ASPECT_RATIO_1_1 = 3; // 0x3
     field public static final int ASPECT_RATIO_2_3 = 4; // 0x4
@@ -25608,66 +25601,6 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
-  public final class IpSecAlgorithm implements android.os.Parcelable {
-    ctor public IpSecAlgorithm(java.lang.String, byte[]);
-    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
-    method public int describeContents();
-    method public byte[] getKey();
-    method public java.lang.String getName();
-    method public int getTruncationLengthBits();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
-    field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
-    field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
-    field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
-    field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
-    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
-    field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
-  }
-
-  public final class IpSecManager {
-    method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
-    method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
-    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
-  }
-
-  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
-  }
-
-  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
-    method public void close();
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
-    method public int getSpi();
-  }
-
-  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
-    method public void close() throws java.io.IOException;
-    method public int getPort();
-    method public java.io.FileDescriptor getSocket();
-  }
-
-  public final class IpSecTransform implements java.lang.AutoCloseable {
-    method public void close();
-    field public static final int DIRECTION_IN = 0; // 0x0
-    field public static final int DIRECTION_OUT = 1; // 0x1
-  }
-
-  public static class IpSecTransform.Builder {
-    ctor public IpSecTransform.Builder(android.content.Context);
-    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
-    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
-    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
-    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
-  }
-
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -26845,10 +26778,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[]);
   }
 
@@ -26900,8 +26833,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
   }
@@ -26910,7 +26841,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);
@@ -26932,10 +26862,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);
   }
@@ -34633,7 +34563,7 @@
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String);
     method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]);
     method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler);
+    method public static void requestFonts(android.content.Context, android.graphics.fonts.FontRequest, android.os.Handler, android.os.CancellationSignal, android.provider.FontsContract.FontRequestCallback);
   }
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
@@ -35065,7 +34995,7 @@
     field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
     field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
-    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.action.MANAGE_UNKNOWN_APP_SOURCES";
+    field public static final java.lang.String ACTION_MANAGE_UNKNOWN_APP_SOURCES = "android.settings.MANAGE_UNKNOWN_APP_SOURCES";
     field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
@@ -35079,6 +35009,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";
@@ -37187,15 +37118,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";
   }
@@ -37249,9 +37177,9 @@
   public final class FillRequest implements android.os.Parcelable {
     method public int describeContents();
     method public android.os.Bundle getClientState();
+    method public java.util.ArrayList<android.service.autofill.FillContext> getFillContexts();
     method public int getFlags();
     method public int getId();
-    method public android.app.assist.AssistStructure getStructure();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR;
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
@@ -37269,7 +37197,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);
   }
@@ -37284,6 +37211,8 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1
+    field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0
+    field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
     field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
     field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
@@ -37297,7 +37226,7 @@
     method public android.service.autofill.SaveInfo build();
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setFlags(int);
-    method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
+    method public android.service.autofill.SaveInfo.Builder setNegativeAction(int, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
   }
 
@@ -39282,7 +39211,6 @@
   }
 
   public static final class Connection.RttModifyStatus {
-    ctor public Connection.RttModifyStatus();
     field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
     field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
     field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
@@ -40432,10 +40360,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);
@@ -40509,7 +40439,6 @@
     field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
     field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
     field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
-    field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
     field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
@@ -40527,8 +40456,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";
   }
 
@@ -42931,7 +42858,7 @@
     method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
     field public static final int ALL = 15; // 0xf
     field public static final int EMAIL_ADDRESSES = 2; // 0x2
-    field public static final deprecated int MAP_ADDRESSES = 8; // 0x8
+    field public static final int MAP_ADDRESSES = 8; // 0x8
     field public static final int PHONE_NUMBERS = 4; // 0x4
     field public static final int WEB_URLS = 1; // 0x1
     field public static final android.text.util.Linkify.MatchFilter sPhoneNumberMatchFilter;
@@ -45792,6 +45719,7 @@
     method public android.view.animation.Animation getAnimation();
     method public android.os.IBinder getApplicationWindowToken();
     method public java.lang.String[] getAutofillHints();
+    method public final android.view.autofill.AutofillId getAutofillId();
     method public int getAutofillType();
     method public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
@@ -46922,6 +46850,7 @@
     method public abstract int addChildCount(int);
     method public abstract void asyncCommit();
     method public abstract android.view.ViewStructure asyncNewChild(int);
+    method public abstract android.view.autofill.AutofillId getAutofillId();
     method public abstract int getChildCount();
     method public abstract android.os.Bundle getExtras();
     method public abstract java.lang.CharSequence getHint();
@@ -46935,7 +46864,8 @@
     method public abstract void setActivated(boolean);
     method public abstract void setAlpha(float);
     method public abstract void setAutofillHints(java.lang.String[]);
-    method public abstract void setAutofillId(android.view.ViewStructure, int);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId);
+    method public abstract void setAutofillId(android.view.autofill.AutofillId, int);
     method public abstract void setAutofillOptions(java.lang.CharSequence[]);
     method public abstract void setAutofillType(int);
     method public abstract void setAutofillValue(android.view.autofill.AutofillValue);
@@ -46965,8 +46895,8 @@
     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 void setVisibility(int);
+    method public abstract void setWebDomain(java.lang.String);
   }
 
   public static abstract class ViewStructure.HtmlInfo {
@@ -47531,7 +47461,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();
@@ -48214,6 +48146,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);
@@ -48228,7 +48162,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 {
@@ -48662,12 +48595,7 @@
 
 package android.view.textclassifier {
 
-  public abstract interface LinksInfo {
-    method public abstract boolean apply(java.lang.CharSequence);
-  }
-
   public final class TextClassificationManager {
-    method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
     method public android.view.textclassifier.TextClassifier getTextClassifier();
     method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
@@ -48695,7 +48623,6 @@
   }
 
   public abstract interface TextClassifier {
-    method public abstract android.view.textclassifier.LinksInfo getLinks(java.lang.CharSequence, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextClassificationResult getTextClassificationResult(java.lang.CharSequence, int, int, android.os.LocaleList);
     method public abstract android.view.textclassifier.TextSelection suggestSelection(java.lang.CharSequence, int, int, android.os.LocaleList);
     field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -48706,20 +48633,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public final class TextLanguage {
-    method public float getConfidenceScore(java.util.Locale);
-    method public int getEndIndex();
-    method public java.util.Locale getLanguage(int);
-    method public int getLanguageCount();
-    method public int getStartIndex();
-  }
-
-  public static final class TextLanguage.Builder {
-    ctor public TextLanguage.Builder(int, int);
-    method public android.view.textclassifier.TextLanguage build();
-    method public android.view.textclassifier.TextLanguage.Builder setLanguage(java.util.Locale, float);
-  }
-
   public final class TextSelection {
     method public float getConfidenceScore(java.lang.String);
     method public java.lang.String getEntity(int);
@@ -49371,7 +49284,7 @@
     method public void documentHasImages(android.os.Message);
     method public static void enableSlowWholeDocumentDraw();
     method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
-    method public static deprecated java.lang.String findAddress(java.lang.String);
+    method public static java.lang.String findAddress(java.lang.String);
     method public deprecated int findAll(java.lang.String);
     method public void findAllAsync(java.lang.String);
     method public void findNext(boolean);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 189536d..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);
   }
 
@@ -126,6 +125,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
@@ -346,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/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index fe496e3..cdeca13 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1092,6 +1092,14 @@
                 AnimationEvent event = mEvents.get(i);
                 Node node = event.mNode;
                 if (event.mEvent == AnimationEvent.ANIMATION_END) {
+                    if (node.mAnimation.isStarted()) {
+                        // If the animation has already been started before its due time (i.e.
+                        // the child animator is being manipulated outside of the AnimatorSet), we
+                        // need to cancel the animation to reset the internal state (e.g. frame
+                        // time tracking) and remove the self pulsing callbacks
+                        node.mAnimation.cancel();
+                    }
+                    node.mEnded = false;
                     mPlayingSet.add(event.mNode);
                     node.mAnimation.startWithoutPulsing(true);
                     pulseFrame(node, 0);
@@ -1106,6 +1114,14 @@
                 Node node = event.mNode;
                 if (event.mEvent == AnimationEvent.ANIMATION_START) {
                     mPlayingSet.add(event.mNode);
+                    if (node.mAnimation.isStarted()) {
+                        // If the animation has already been started before its due time (i.e.
+                        // the child animator is being manipulated outside of the AnimatorSet), we
+                        // need to cancel the animation to reset the internal state (e.g. frame
+                        // time tracking) and remove the self pulsing callbacks
+                        node.mAnimation.cancel();
+                    }
+                    node.mEnded = false;
                     node.mAnimation.startWithoutPulsing(false);
                     pulseFrame(node, 0);
                 } else if (event.mEvent == AnimationEvent.ANIMATION_END && !node.mEnded) {
diff --git a/core/java/android/annotation/AnyThread.java b/core/java/android/annotation/AnyThread.java
index c101548c..e173bd1 100644
--- a/core/java/android/annotation/AnyThread.java
+++ b/core/java/android/annotation/AnyThread.java
@@ -15,30 +15,34 @@
  */
 package android.annotation;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
 import static java.lang.annotation.ElementType.CONSTRUCTOR;
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 /**
- * Denotes that the annotated method can be called from any thread (e.g. it is "thread safe".)
- * If the annotated element is a class, then all methods in the class can be called
- * from any thread.
+ * Denotes that the annotated method can be called from any thread (e.g. it is
+ * "thread safe".) If the annotated element is a class, then all methods in the
+ * class can be called from any thread.
  * <p>
- * The main purpose of this method is to indicate that you believe a method can be called
- * from any thread; static tools can then check that nothing you call from within this method
- * or class have more strict threading requirements.
+ * The main purpose of this method is to indicate that you believe a method can
+ * be called from any thread; static tools can then check that nothing you call
+ * from within this method or class have more strict threading requirements.
  * <p>
  * Example:
- * <pre><code>
+ *
+ * <pre>
+ * <code>
  *  &#64;AnyThread
  *  public void deliverResult(D data) { ... }
- * </code></pre>
+ * </code>
+ * </pre>
  *
- * {@hide}
+ * @memberDoc This method is safe to call from any thread.
+ * @hide
  */
 @Retention(SOURCE)
 @Target({METHOD,CONSTRUCTOR,TYPE})
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/annotation/CallSuper.java b/core/java/android/annotation/CallSuper.java
index b10a28a..c16b511 100644
--- a/core/java/android/annotation/CallSuper.java
+++ b/core/java/android/annotation/CallSuper.java
@@ -15,24 +15,29 @@
  */
 package android.annotation;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 /**
  * Denotes that any overriding methods should invoke this method as well.
  * <p>
  * Example:
- * <pre><code>
+ *
+ * <pre>
+ * <code>
  *  &#64;CallSuper
  *  public abstract void onFocusLost();
- * </code></pre>
+ * </code>
+ * </pre>
  *
+ * @memberDoc If you override this method you <em>must</em> call through to the
+ *            superclass implementation.
  * @hide
  */
 @Retention(SOURCE)
 @Target({METHOD})
 public @interface CallSuper {
-}
\ No newline at end of file
+}
diff --git a/core/java/android/annotation/MainThread.java b/core/java/android/annotation/MainThread.java
index c6ac30c..d15cfcd 100644
--- a/core/java/android/annotation/MainThread.java
+++ b/core/java/android/annotation/MainThread.java
@@ -15,9 +15,6 @@
  */
 package android.annotation;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
 import static java.lang.annotation.ElementType.CONSTRUCTOR;
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.ElementType.TYPE;
@@ -25,6 +22,9 @@
 
 import android.os.Looper;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 /**
  * Denotes that the annotated method should only be called on the main thread.
  * If the annotated element is a class, then all methods in the class should be
diff --git a/core/java/android/annotation/SuppressAutoDoc.java b/core/java/android/annotation/SuppressAutoDoc.java
index 0f8fa6c..e34e03b 100644
--- a/core/java/android/annotation/SuppressAutoDoc.java
+++ b/core/java/android/annotation/SuppressAutoDoc.java
@@ -16,14 +16,17 @@
 
 package android.annotation;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
 import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 /**
  * Denotes that any automatically generated documentation should be suppressed
  * for the annotated method, parameter, or field.
@@ -31,6 +34,6 @@
  * @hide
  */
 @Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
 public @interface SuppressAutoDoc {
 }
diff --git a/core/java/android/annotation/UiThread.java b/core/java/android/annotation/UiThread.java
index 53121e7..b277896 100644
--- a/core/java/android/annotation/UiThread.java
+++ b/core/java/android/annotation/UiThread.java
@@ -15,28 +15,36 @@
  */
 package android.annotation;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
 import static java.lang.annotation.ElementType.CONSTRUCTOR;
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.os.Looper;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 /**
- * Denotes that the annotated method or constructor should only be called on the UI thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the UI thread.
+ * Denotes that the annotated method or constructor should only be called on the
+ * UI thread. If the annotated element is a class, then all methods in the class
+ * should be called on the UI thread.
  * <p>
  * Example:
- * <pre><code>
+ *
+ * <pre>
+ * <code>
  *  &#64;UiThread
  *  public abstract void setText(@NonNull String text) { ... }
- * </code></pre>
+ * </code>
+ * </pre>
  *
- * {@hide}
+ * @memberDoc This method must be called on the thread that originally created
+ *            this UI element. This is typically the
+ *            {@linkplain Looper#getMainLooper() main thread} of your app.
+ * @hide
  */
 @Retention(SOURCE)
 @Target({METHOD,CONSTRUCTOR,TYPE})
 public @interface UiThread {
-}
\ No newline at end of file
+}
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 44c275f..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) {
@@ -3081,6 +3087,21 @@
          */
         public int lastTrimLevel;
 
+        /** @hide */
+        @IntDef(prefix = { "IMPORTANCE_" }, value = {
+                IMPORTANCE_FOREGROUND,
+                IMPORTANCE_FOREGROUND_SERVICE,
+                IMPORTANCE_TOP_SLEEPING,
+                IMPORTANCE_VISIBLE,
+                IMPORTANCE_PERCEPTIBLE,
+                IMPORTANCE_CANT_SAVE_STATE,
+                IMPORTANCE_SERVICE,
+                IMPORTANCE_CACHED,
+                IMPORTANCE_GONE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Importance {}
+
         /**
          * Constant for {@link #importance}: This process is running the
          * foreground UI; that is, it is the thing currently at the top of the screen
@@ -3190,7 +3211,7 @@
          * will be passed to a client, use {@link #procStateToImportanceForClient}.
          * @hide
          */
-        public static int procStateToImportance(int procState) {
+        public static @Importance int procStateToImportance(int procState) {
             if (procState == PROCESS_STATE_NONEXISTENT) {
                 return IMPORTANCE_GONE;
             } else if (procState >= PROCESS_STATE_HOME) {
@@ -3219,7 +3240,8 @@
          * client's target SDK < {@link VERSION_CODES#O}.
          * @hide
          */
-        public static int procStateToImportanceForClient(int procState, Context clientContext) {
+        public static @Importance int procStateToImportanceForClient(int procState,
+                Context clientContext) {
             final int importance = procStateToImportance(procState);
 
             // For pre O apps, convert to the old, wrong values.
@@ -3235,7 +3257,7 @@
         }
 
         /** @hide */
-        public static int importanceToProcState(int importance) {
+        public static int importanceToProcState(@Importance int importance) {
             if (importance == IMPORTANCE_GONE) {
                 return PROCESS_STATE_NONEXISTENT;
             } else if (importance >= IMPORTANCE_CACHED) {
@@ -3258,14 +3280,11 @@
         }
 
         /**
-         * The relative importance level that the system places on this
-         * process.  May be one of {@link #IMPORTANCE_FOREGROUND},
-         * {@link #IMPORTANCE_VISIBLE}, {@link #IMPORTANCE_SERVICE}, or
-         * {@link #IMPORTANCE_CACHED}.  These
-         * constants are numbered so that "more important" values are always
-         * smaller than "less important" values.
+         * The relative importance level that the system places on this process.
+         * These constants are numbered so that "more important" values are
+         * always smaller than "less important" values.
          */
-        public int importance;
+        public @Importance int importance;
 
         /**
          * An additional ordering within a particular {@link #importance}
@@ -3459,7 +3478,7 @@
      */
     @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
-    public int getPackageImportance(String packageName) {
+    public @RunningAppProcessInfo.Importance int getPackageImportance(String packageName) {
         try {
             int procState = getService().getPackageProcessState(packageName,
                     mContext.getOpPackageName());
@@ -3479,7 +3498,7 @@
      */
     @SystemApi @TestApi
     @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
-    public int getUidImportance(int uid) {
+    public @RunningAppProcessInfo.Importance int getUidImportance(int uid) {
         try {
             int procState = getService().getUidProcessState(uid,
                     mContext.getOpPackageName());
@@ -3505,7 +3524,7 @@
          * @param uid The uid whose importance has changed.
          * @param importance The new importance value as per {@link RunningAppProcessInfo}.
          */
-        void onUidImportance(int uid, int importance);
+        void onUidImportance(int uid, @RunningAppProcessInfo.Importance int importance);
     }
 
     /**
@@ -3527,7 +3546,7 @@
      */
     @SystemApi @TestApi
     public void addOnUidImportanceListener(OnUidImportanceListener listener,
-            int importanceCutpoint) {
+            @RunningAppProcessInfo.Importance int importanceCutpoint) {
         synchronized (this) {
             if (mImportanceListeners.containsKey(listener)) {
                 throw new IllegalArgumentException("Listener already registered: " + listener);
@@ -3624,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,
@@ -4002,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);
     }
@@ -4263,8 +4279,7 @@
 
     /**
      * Enable more aggressive scheduling for latency-sensitive low-runtime VR threads that persist
-     * beyond a single process. It requires holding the
-     * {@link android.Manifest.permission#RESTRICTED_VR_ACCESS} permission. Only one thread can be a
+     * beyond a single process. Only one thread can be a
      * persistent VR thread at a time, and that thread may be subject to restrictions on the amount
      * of time it can run. Calling this method will disable aggressive scheduling for non-persistent
      * VR threads set via {@link #setVrThread}. If persistent VR mode is disabled then the
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/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index cd9c095..cc7e0fd 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -46,7 +46,7 @@
     void enqueueToast(String pkg, ITransientNotification callback, int duration);
     void cancelToast(String pkg, ITransientNotification callback);
     void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
-            in Notification notification, inout int[] idReceived, int userId);
+            in Notification notification, int userId);
     void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
 
     void setShowBadge(String pkg, int uid, boolean showBadge);
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 47817a7..f369955 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -21,6 +21,11 @@
 
 /** @hide */
 oneway interface ITaskStackListener {
+    /** Activity was resized to be displayed in split-screen. */
+    const int FORCED_RESIZEABLE_REASON_SPLIT_SCREEN = 1;
+    /** Activity was resized to be displayed on a secondary display. */
+    const int FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY = 2;
+
     /** Called whenever there are changes to the state of tasks in a stack. */
     void onTaskStackChanged();
 
@@ -49,15 +54,26 @@
 
     /**
      * Called when we launched an activity that we forced to be resizable.
+     *
+     * @param packageName Package name of the top activity in the task.
+     * @param taskId Id of the task.
+     * @param reason {@link #FORCED_RESIZEABLE_REASON_SPLIT_SCREEN} or
+      *              {@link #FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY}.
      */
-    void onActivityForcedResizable(String packageName, int taskId);
+    void onActivityForcedResizable(String packageName, int taskId, int reason);
 
     /**
-     * Callen when we launched an activity that is dismissed the docked stack.
+     * Called when we launched an activity that dismissed the docked stack.
      */
     void onActivityDismissingDockedStack();
 
     /**
+     * Called when an activity was requested to be launched on a secondary display but was not
+     * allowed there.
+     */
+    void onActivityLaunchOnSecondaryDisplayFailed();
+
+    /**
      * Called when a task is added.
      *
      * @param taskId id of the task.
diff --git a/core/java/android/app/InstantAppResolverService.java b/core/java/android/app/InstantAppResolverService.java
index 88399e5..c5dc86c 100644
--- a/core/java/android/app/InstantAppResolverService.java
+++ b/core/java/android/app/InstantAppResolverService.java
@@ -91,6 +91,9 @@
             @Override
             public void getInstantAppResolveInfoList(
                     int digestPrefix[], String token, int sequence, IRemoteCallback callback) {
+                if (DEBUG_EPHEMERAL) {
+                    Slog.v(TAG, "[" + token + "] Phase1 called; posting");
+                }
                 final SomeArgs args = SomeArgs.obtain();
                 args.arg1 = callback;
                 args.arg2 = digestPrefix;
@@ -103,6 +106,9 @@
             @Override
             public void getInstantAppIntentFilterList(
                     int digestPrefix[], String token, String hostName, IRemoteCallback callback) {
+                if (DEBUG_EPHEMERAL) {
+                    Slog.v(TAG, "[" + token + "] Phase2 called; posting");
+                }
                 final SomeArgs args = SomeArgs.obtain();
                 args.arg1 = callback;
                 args.arg2 = digestPrefix;
@@ -140,7 +146,7 @@
     void _onGetInstantAppResolveInfo(int[] digestPrefix, String token,
             InstantAppResolutionCallback callback) {
         if (DEBUG_EPHEMERAL) {
-            Slog.d(TAG, "Instant resolver; getInstantAppResolveInfo;"
+            Slog.d(TAG, "[" + token + "] Phase1 request;"
                     + " prefix: " + Arrays.toString(digestPrefix));
         }
         onGetInstantAppResolveInfo(digestPrefix, token, callback);
@@ -149,7 +155,7 @@
     void _onGetInstantAppIntentFilter(int digestPrefix[], String token, String hostName,
             InstantAppResolutionCallback callback) {
         if (DEBUG_EPHEMERAL) {
-            Slog.d(TAG, "Instant resolver; getInstantAppIntentFilter;"
+            Slog.d(TAG, "[" + token + "] Phase2 request;"
                     + " prefix: " + Arrays.toString(digestPrefix));
         }
         onGetInstantAppIntentFilter(digestPrefix, token, callback);
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index c0bf0c4..b8a5f57 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -169,9 +169,6 @@
          * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
          * is enabled that requires a password.
          *
-         * <p>This method requires the caller to hold the permission
-         * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
-         *
          * @see #reenableKeyguard()
          */
         @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
@@ -191,9 +188,6 @@
          * Note: This call has no effect while any {@link android.app.admin.DevicePolicyManager}
          * is enabled that requires a password.
          *
-         * <p>This method requires the caller to hold the permission
-         * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
-         *
          * @see #disableKeyguard()
          */
         @RequiresPermission(Manifest.permission.DISABLE_KEYGUARD)
@@ -431,9 +425,6 @@
      * This will, if the keyguard is secure, bring up the unlock screen of
      * the keyguard.
      *
-     * <p>This method requires the caller to hold the permission
-     * {@link android.Manifest.permission#DISABLE_KEYGUARD}.
-     *
      * @param callback Let's you know whether the operation was succesful and
      *   it is safe to launch anything that would normally be considered safe
      *   once the user has gotten past the keyguard.
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/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 58ed587..7c361b9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -298,7 +298,6 @@
      */
     public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
     {
-        int[] idOut = new int[1];
         INotificationManager service = getService();
         String pkg = mContext.getPackageName();
         // Fix the notification as best we can.
@@ -320,10 +319,7 @@
         final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
         try {
             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
-                    copy, idOut, user.getIdentifier());
-            if (localLOGV && id != idOut[0]) {
-                Log.v(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
-            }
+                    copy, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 57fc874..307fc91 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -51,7 +51,8 @@
     }
 
     @Override
-    public void onActivityForcedResizable(String packageName, int taskId) throws RemoteException {
+    public void onActivityForcedResizable(String packageName, int taskId, int reason)
+            throws RemoteException {
     }
 
     @Override
@@ -59,6 +60,10 @@
     }
 
     @Override
+    public void onActivityLaunchOnSecondaryDisplayFailed() throws RemoteException {
+    }
+
+    @Override
     public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
     }
 
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..7855b92 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1518,7 +1518,8 @@
      * Service action: Action for a service that device owner and profile owner can optionally
      * own.  If a device owner or a profile owner has such a service, the system tries to keep
      * a bound connection to it, in order to keep their process always running.
-     * The service must not be exported.
+     * The service must be protected with the {@link android.Manifest.permission#BIND_DEVICE_ADMIN}
+     * permission.
      */
     @SdkConstant(SdkConstantType.SERVICE_ACTION)
     public static final String ACTION_DEVICE_ADMIN_SERVICE
@@ -2972,9 +2973,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 +3005,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 +7682,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 9e5c9e7..d6b89a1 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;
@@ -34,8 +35,18 @@
 import java.util.Arrays;
 
 /**
- * Assist data automatically created by the platform's implementation
- * of {@link android.app.Activity#onProvideAssistData}.
+ * Assist data automatically created by the platform's implementation of Assist and Autofill.
+ *
+ * <p>The structure is used for Assist purposes when created by
+ * {@link android.app.Activity#onProvideAssistData}, {@link View#onProvideStructure(ViewStructure)},
+ * or {@link View#onProvideVirtualStructure(ViewStructure)}.
+ *
+ * <p>The structure is used for Autofill purposes when created by
+ * {@link View#onProvideAutofillStructure(ViewStructure, int)},
+ * or {@link View#onProvideAutofillVirtualStructure(ViewStructure, int)}.
+ *
+ * <p>For performance reasons, some properties of the Assist data might be available just for Assist
+ * or Autofill purposes; in those case, the property availability will be document in its javadoc.
  */
 public class AssistStructure implements Parcelable {
     static final String TAG = "AssistStructure";
@@ -589,10 +600,10 @@
         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.AutofillType int mAutofillType = View.AUTOFILL_TYPE_NONE;
         @Nullable String[] mAutofillHints;
         AutofillValue mAutofillValue;
         CharSequence[] mAutofillOptions;
@@ -628,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...
@@ -656,7 +667,7 @@
 
         ViewNodeText mText;
         int mInputType;
-        String mUrl;
+        String mWebDomain;
         Bundle mExtras;
         LocaleList mLocaleList;
 
@@ -733,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);
@@ -795,7 +806,7 @@
             if (mInputType != 0) {
                 flags |= FLAGS_HAS_INPUT_TYPE;
             }
-            if (mUrl != null) {
+            if (mWebDomain != null) {
                 flags |= FLAGS_HAS_URL;
             }
             if (mLocaleList != null) {
@@ -890,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);
@@ -938,18 +949,22 @@
         /**
          * Gets the id that can be used to autofill the view contents.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.
+         * <p>It's relevant set when the {@link AssistStructure} is used for Autofill purposes.
+         *
+         * @return id that can be used to autofill the view contents, or {@code null} if the
+         * structure was created for Assist purposes.
          */
-        public AutofillId getAutofillId() {
+        @Nullable public AutofillId getAutofillId() {
             return mAutofillId;
         }
 
         /**
          * Gets the the type of value that can be used to autofill the view contents.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.
+         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes.
+         *
+         * @return autofill type as defined by {@link View#getAutofillType()},
+         * or {@link View#AUTOFILL_TYPE_NONE} if the structure was created for Assist purposes.
          */
         public @View.AutofillType int getAutofillType() {
             return mAutofillType;
@@ -959,32 +974,26 @@
          * Describes the content of a view so that a autofill service can fill in the appropriate
          * data.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.</p>
+         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
+         * not for Assist - see {@link View#getAutofillHints()} for more info.
          *
-         * @return The hints for this view
+         * @return The autofill hints for this view, or {@code null} if the structure was created
+         * for Assist purposes.
          */
         @Nullable public String[] getAutofillHints() {
             return mAutofillHints;
         }
 
         /**
-         * @hide
-         * @deprecated use getAutofillHints() instead.
-         */
-        // TODO(b/33197203): remove once clients don't use it anymore...
-        @Deprecated
-        @Nullable public String[] getAutoFillHints() {
-            return mAutofillHints;
-        }
-
-        /**
          * Gets the the value of this view.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.
+         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
+         * not for Assist purposes.
+         *
+         * @return the autofill value of this view, or {@code null} if the structure was created
+         * for Assist purposes.
          */
-        public AutofillValue getAutofillValue() {
+        @Nullable public AutofillValue getAutofillValue() {
             return mAutofillValue;
         }
 
@@ -994,15 +1003,18 @@
         }
 
         /**
-         * Gets the options that can be used to autofill this structure.
+         * Gets the options that can be used to autofill this view.
          *
          * <p>Typically used by nodes whose {@link View#getAutofillType()} is a list to indicate
          * the meaning of each possible value in the list.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.
+         * <p>It's relevant when the {@link AssistStructure} is used for Autofill purposes, not
+         * for Assist purposes.
+         *
+         * @return the options that can be used to autofill this view, or {@code null} if the
+         * structure was created for Assist purposes.
          */
-        public CharSequence[] getAutofillOptions() {
+        @Nullable public CharSequence[] getAutofillOptions() {
             return mAutofillOptions;
         }
 
@@ -1031,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();
             }
@@ -1226,33 +1236,39 @@
         }
 
         /**
-         * Returns the URL represented by this node.
+         * Returns the domain of the HTML document represented by this view.
          *
-         * <p>Typically used when the view associated with the node is a container for an HTML
+         * <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}.
          */
-        public String getUrl() {
-            return mUrl;
+        @Nullable public String getWebDomain() {
+            return mWebDomain;
         }
 
         /**
-         * Returns the HTML properties associated with this node.
+         * Returns the HTML properties associated with this view.
          *
-         * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
-         * for assist.
+         * <p>It's only relevant when the {@link AssistStructure} is used for Autofill purposes,
+         * not for Assist purposes.
+         *
+         * @return the HTML properties associated with this view, or {@code null} if the
+         * structure was created for Assist purposes.
          */
-        public HtmlInfo getHtmlInfo() {
+        @Nullable public HtmlInfo getHtmlInfo() {
             return mHtmlInfo;
         }
 
         /**
-         * Returns the the list of locales associated with this node.
+         * Returns the the list of locales associated with this view.
          */
-        public LocaleList getLocaleList() {
+        @Nullable public LocaleList getLocaleList() {
             return mLocaleList;
         }
 
@@ -1628,7 +1644,7 @@
 
         @Override
         public void setAutofillId(@NonNull ViewStructure parent, int virtualId) {
-            mNode.mAutofillId = new AutofillId(parent.getAutofillId(), virtualId);
+            setAutofillId(parent.getAutofillId(), virtualId);
         }
 
         @Override
@@ -1669,8 +1685,13 @@
         }
 
         @Override
-        public void setAutofillId(int viewId) {
-            mNode.mAutofillId = new AutofillId(viewId);
+        public void setAutofillId(@NonNull AutofillId id) {
+            mNode.mAutofillId = id;
+        }
+
+        @Override
+        public void setAutofillId(@NonNull AutofillId parentId, int virtualId) {
+            mNode.mAutofillId = new AutofillId(parentId, virtualId);
         }
 
         @Override
@@ -1710,7 +1731,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
@@ -1932,9 +1964,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) {
@@ -1965,7 +1997,7 @@
                     + ", type=" + node.getAutofillType()
                     + ", options=" + Arrays.toString(node.getAutofillOptions())
                     + ", inputType=" + node.getInputType()
-                    + ", hints=" + Arrays.toString(node.getAutoFillHints())
+                    + ", hints=" + Arrays.toString(node.getAutofillHints())
                     + ", value=" + node.getAutofillValue()
                     + ", sanitized=" + node.isSanitized());
         }
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 23baa17..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)}
@@ -244,7 +268,7 @@
     /**
      * Bundle of extras which are returned to your application at execution time.
      */
-    public PersistableBundle getExtras() {
+    public @NonNull PersistableBundle getExtras() {
         return extras;
     }
 
@@ -252,7 +276,7 @@
      * Bundle of transient extras which are returned to your application at execution time,
      * but not persisted by the system.
      */
-    public Bundle getTransientExtras() {
+    public @NonNull Bundle getTransientExtras() {
         return transientExtras;
     }
 
@@ -260,7 +284,7 @@
      * ClipData of information that is returned to your application at execution time,
      * but not persisted by the system.
      */
-    public ClipData getClipData() {
+    public @Nullable ClipData getClipData() {
         return clipData;
     }
 
@@ -274,7 +298,7 @@
     /**
      * Name of the service endpoint that will be called back into by the JobScheduler.
      */
-    public ComponentName getService() {
+    public @NonNull ComponentName getService() {
         return service;
     }
 
@@ -327,8 +351,7 @@
      * Which content: URIs must change for the job to be scheduled.  Returns null
      * if there are none required.
      */
-    @Nullable
-    public TriggerContentUri[] getTriggerContentUris() {
+    public @Nullable TriggerContentUri[] getTriggerContentUris() {
         return triggerContentUris;
     }
 
@@ -350,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;
     }
 
@@ -422,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;
     }
 
@@ -693,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
@@ -703,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;
         }
@@ -721,7 +742,7 @@
         /**
          * Return the flags supplied for the trigger.
          */
-        public int getFlags() {
+        public @Flags int getFlags() {
             return mFlags;
         }
 
@@ -811,7 +832,7 @@
          * @param jobService The endpoint that you implement that will receive the callback from the
          * JobScheduler.
          */
-        public Builder(int jobId, ComponentName jobService) {
+        public Builder(int jobId, @NonNull ComponentName jobService) {
             mJobService = jobService;
             mJobId = jobId;
         }
@@ -832,17 +853,21 @@
          * Set optional extras. This is persisted, so we only allow primitive types.
          * @param extras Bundle containing extras you want the scheduler to hold on to for you.
          */
-        public Builder setExtras(PersistableBundle extras) {
+        public Builder setExtras(@NonNull PersistableBundle extras) {
             mExtras = extras;
             return this;
         }
 
         /**
-         * Set optional transient extras. This is incompatible with jobs that are also
-         * persisted with {@link #setPersisted(boolean)}; mixing the two is not allowed.
+         * Set optional transient extras.
+         *
+         * <p>Because setting this property is not compatible with persisted
+         * jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
+         * {@link android.app.job.JobInfo.Builder#build()} is called.</p>
+         *
          * @param extras Bundle containing extras you want the scheduler to hold on to for you.
          */
-        public Builder setTransientExtras(Bundle extras) {
+        public Builder setTransientExtras(@NonNull Bundle extras) {
             mTransientExtras = extras;
             return this;
         }
@@ -869,7 +894,7 @@
          * {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, and
          * {@link android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}.
          */
-        public Builder setClipData(ClipData clip, int grantFlags) {
+        public Builder setClipData(@Nullable ClipData clip, int grantFlags) {
             mClipData = clip;
             mClipGrantFlags = grantFlags;
             return this;
@@ -883,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;
         }
@@ -1064,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;
@@ -1075,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/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 673d1b8..98bdde8 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -16,6 +16,8 @@
 
 package android.app.job;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.job.IJobCallback;
 import android.content.ClipData;
 import android.net.Uri;
@@ -91,7 +93,7 @@
      * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
      * never be null. If you did not set any extras this will be an empty bundle.
      */
-    public PersistableBundle getExtras() {
+    public @NonNull PersistableBundle getExtras() {
         return extras;
     }
 
@@ -100,7 +102,7 @@
      * {@link android.app.job.JobInfo.Builder#setTransientExtras(android.os.Bundle)}. This will
      * never be null. If you did not set any extras this will be an empty bundle.
      */
-    public Bundle getTransientExtras() {
+    public @NonNull Bundle getTransientExtras() {
         return transientExtras;
     }
 
@@ -109,7 +111,7 @@
      * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be null
      * if it was not set.
      */
-    public ClipData getClipData() {
+    public @Nullable ClipData getClipData() {
         return clipData;
     }
 
@@ -140,7 +142,7 @@
      * always use {@link #getTriggeredContentAuthorities()} to determine whether the job was
      * triggered due to any content changes and the authorities they are associated with.
      */
-    public Uri[] getTriggeredContentUris() {
+    public @Nullable Uri[] getTriggeredContentUris() {
         return mTriggeredContentUris;
     }
 
@@ -152,7 +154,7 @@
      * to retrieve the details of which URIs changed (as long as that has not exceeded the maximum
      * number it can reported).
      */
-    public String[] getTriggeredContentAuthorities() {
+    public @Nullable String[] getTriggeredContentAuthorities() {
         return mTriggeredContentAuthorities;
     }
 
@@ -178,12 +180,18 @@
      * doing so any pending as well as remaining uncompleted work will be re-queued
      * for the next time the job runs.</p>
      *
+     * <p>This example shows how to construct a JobService that will serially dequeue and
+     * process work that is available for it:</p>
+     *
+     * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/JobWorkService.java
+     *      service}
+     *
      * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
      * If null is returned, the system will also stop the job if all work has also been completed.
      * (This means that for correct operation, you must always call dequeueWork() after you have
      * completed other work, to check either for more work or allow the system to stop the job.)
      */
-    public JobWorkItem dequeueWork() {
+    public @Nullable JobWorkItem dequeueWork() {
         try {
             return getCallback().dequeueWork(getJobId());
         } catch (RemoteException e) {
@@ -207,7 +215,7 @@
      * @param work The work you have completed processing, as previously returned by
      * {@link #dequeueWork()}
      */
-    public void completeWork(JobWorkItem work) {
+    public void completeWork(@NonNull JobWorkItem work) {
         try {
             if (!getCallback().completeWork(getJobId(), work.getWorkId())) {
                 throw new IllegalArgumentException("Given work is not active: " + work);
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
index e0afe03..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,26 +81,27 @@
      * @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(JobInfo job);
+    public abstract @Result int schedule(@NonNull JobInfo job);
 
     /**
-     * Similar to {@link #schedule}, but allows you to enqueue work for an existing job.  If a job
-     * with the same ID is already scheduled, it will be replaced with the new {@link JobInfo}, but
-     * any previously enqueued work will remain and be dispatched the next time it runs.  If a job
-     * with the same ID is already running, the new work will be enqueued for it.
+     * Similar to {@link #schedule}, but allows you to enqueue work for a new <em>or existing</em>
+     * job.  If a job with the same ID is already scheduled, it will be replaced with the
+     * new {@link JobInfo}, but any previously enqueued work will remain and be dispatched the
+     * next time it runs.  If a job with the same ID is already running, the new work will be
+     * enqueued for it.
      *
      * <p>The work you enqueue is later retrieved through
-     * {@link JobParameters#dequeueWork() JobParameters.dequeueWork()}.  Be sure to see there
+     * {@link JobParameters#dequeueWork() JobParameters.dequeueWork}.  Be sure to see there
      * about how to process work; the act of enqueueing work changes how you should handle the
      * overall lifecycle of an executing job.</p>
      *
      * <p>It is strongly encouraged that you use the same {@link JobInfo} for all work you
-     * enqueue.  This will allow the system to optimal schedule work along with any pending
+     * enqueue.  This will allow the system to optimally schedule work along with any pending
      * and/or currently running work.  If the JobInfo changes from the last time the job was
      * enqueued, the system will need to update the associated JobInfo, which can cause a disruption
-     * in exection.  In particular, this can result in any currently running job that is processing
+     * in execution.  In particular, this can result in any currently running job that is processing
      * previous work to be stopped and restarted with the new JobInfo.</p>
      *
      * <p>It is recommended that you avoid using
@@ -100,15 +112,15 @@
      * (That said, you should be relatively safe with a simple set of consistent data in these
      * fields.)  You should never use {@link JobInfo.Builder#setClipData(ClipData, int)} with
      * work you are enqueue, since currently this will always be treated as a different JobInfo,
-     * even if the ClipData contents is exactly the same.</p>
+     * even if the ClipData contents are exactly the same.</p>
      *
      * @param job The job you wish to enqueue work for. See
      * {@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(JobInfo job, JobWorkItem work);
+    public abstract @Result int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work);
 
     /**
      *
@@ -117,11 +129,11 @@
      *                    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(JobInfo job, String packageName, int userId, String tag);
+    public abstract @Result int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName,
+            int userId, String tag);
 
     /**
      * Cancel a job that is pending in the JobScheduler.
diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java
index a628619..b7d759b 100644
--- a/core/java/android/app/job/JobServiceEngine.java
+++ b/core/java/android/app/job/JobServiceEngine.java
@@ -32,7 +32,11 @@
 
 /**
  * Helper for implementing a {@link android.app.Service} that interacts with
- * {@link JobScheduler}.
+ * {@link JobScheduler}.  This is not intended for use by regular applications, but
+ * allows frameworks built on top of the platform to create their own
+ * {@link android.app.Service} that interact with {@link JobScheduler} as well as
+ * add in additional functionality.  If you just want to execute jobs normally, you
+ * should instead be looking at {@link JobService}.
  */
 public abstract class JobServiceEngine {
     private static final String TAG = "JobServiceEngine";
@@ -215,7 +219,7 @@
      * {@link JobService#jobFinished(JobParameters, boolean)}  JobService.jobFinished} for more
      * information.
      */
-    public final void jobFinished(JobParameters params, boolean needsReschedule) {
+    public void jobFinished(JobParameters params, boolean needsReschedule) {
         Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
         m.arg2 = needsReschedule ? 1 : 0;
         m.sendToTarget();
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
index 05687ee..0eb0450 100644
--- a/core/java/android/app/job/JobWorkItem.java
+++ b/core/java/android/app/job/JobWorkItem.java
@@ -22,15 +22,19 @@
 
 /**
  * A unit of work that can be enqueued for a job using
- * {@link JobScheduler#enqueue JobScheduler.enqueue}.
+ * {@link JobScheduler#enqueue JobScheduler.enqueue}.  See
+ * {@link JobParameters#dequeueWork() JobParameters.dequeueWork} for more details.
  */
 final public class JobWorkItem implements Parcelable {
     final Intent mIntent;
+    int mDeliveryCount;
     int mWorkId;
     Object mGrants;
 
     /**
-     * Create a new piece of work.
+     * Create a new piece of work, which can be submitted to
+     * {@link JobScheduler#enqueue JobScheduler.enqueue}.
+     *
      * @param intent The general Intent describing this work.
      */
     public JobWorkItem(Intent intent) {
@@ -45,6 +49,23 @@
     }
 
     /**
+     * Return the count of the number of times this work item has been delivered
+     * to the job.  The value will be > 1 if it has been redelivered because the job
+     * was stopped or crashed while it had previously been delivered but before the
+     * job had called {@link JobParameters#completeWork JobParameters.completeWork} for it.
+     */
+    public int getDeliveryCount() {
+        return mDeliveryCount;
+    }
+
+    /**
+     * @hide
+     */
+    public void bumpDeliveryCount() {
+        mDeliveryCount++;
+    }
+
+    /**
      * @hide
      */
     public void setWorkId(int id) {
@@ -73,7 +94,17 @@
     }
 
     public String toString() {
-        return "JobWorkItem{id=" + mWorkId + " intent=" + mIntent + "}";
+        StringBuilder sb = new StringBuilder(64);
+        sb.append("JobWorkItem{id=");
+        sb.append(mWorkId);
+        sb.append(" intent=");
+        sb.append(mIntent);
+        if (mDeliveryCount != 0) {
+            sb.append(" dcount=");
+            sb.append(mDeliveryCount);
+        }
+        sb.append("}");
+        return sb.toString();
     }
 
     public int describeContents() {
@@ -87,6 +118,7 @@
         } else {
             out.writeInt(0);
         }
+        out.writeInt(mDeliveryCount);
         out.writeInt(mWorkId);
     }
 
@@ -101,12 +133,13 @@
         }
     };
 
-    public JobWorkItem(Parcel in) {
+    JobWorkItem(Parcel in) {
         if (in.readInt() != 0) {
             mIntent = Intent.CREATOR.createFromParcel(in);
         } else {
             mIntent = null;
         }
+        mDeliveryCount = in.readInt();
         mWorkId = in.readInt();
     }
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index a64a023..06b0aac 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -51,8 +51,6 @@
      * Changes the lock status for the given user. This is only applicable to Managed Profiles,
      * other users should be handled by Keyguard.
      *
-     * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
-     *
      * @param userId The id for the user to be locked/unlocked.
      * @param locked The value for that user's locked state.
      */
diff --git a/core/java/android/app/usage/ExternalStorageStats.java b/core/java/android/app/usage/ExternalStorageStats.java
index 1166df0..10c9b5f 100644
--- a/core/java/android/app/usage/ExternalStorageStats.java
+++ b/core/java/android/app/usage/ExternalStorageStats.java
@@ -31,6 +31,7 @@
     /** {@hide} */ public long audioBytes;
     /** {@hide} */ public long videoBytes;
     /** {@hide} */ public long imageBytes;
+    /** {@hide} */ public long appBytes;
 
     /**
      * Return the total bytes used by all files in the shared/external storage
@@ -64,6 +65,17 @@
         return imageBytes;
     }
 
+    /**
+     * Return the total bytes used by app files in the shared/external storage
+     * hosted on this volume.
+     * <p>
+     * This data is already accounted against individual apps as returned
+     * through {@link StorageStats}.
+     */
+    public long getAppBytes() {
+        return appBytes;
+    }
+
     /** {@hide} */
     public ExternalStorageStats() {
     }
@@ -74,6 +86,7 @@
         this.audioBytes = in.readLong();
         this.videoBytes = in.readLong();
         this.imageBytes = in.readLong();
+        this.appBytes = in.readLong();
     }
 
     @Override
@@ -87,6 +100,7 @@
         dest.writeLong(audioBytes);
         dest.writeLong(videoBytes);
         dest.writeLong(imageBytes);
+        dest.writeLong(appBytes);
     }
 
     public static final Creator<ExternalStorageStats> CREATOR = new Creator<ExternalStorageStats>() {
diff --git a/core/java/android/app/usage/StorageStats.java b/core/java/android/app/usage/StorageStats.java
index b3104f6..26c702c0 100644
--- a/core/java/android/app/usage/StorageStats.java
+++ b/core/java/android/app/usage/StorageStats.java
@@ -22,12 +22,8 @@
 import android.os.UserHandle;
 
 /**
- * Storage statistics for a UID or {@link UserHandle} on a single storage
- * volume.
- * <p class="note">
- * Note: multiple packages using the same {@code sharedUserId} in their manifest
- * will be merged into a single UID.
- * </p>
+ * Storage statistics for a UID, package, or {@link UserHandle} on a single
+ * storage volume.
  *
  * @see StorageStatsManager
  */
@@ -40,6 +36,9 @@
      * Return the size of all code. This includes {@code APK} files and
      * optimized compiler output.
      * <p>
+     * If the primary external/shared storage is hosted on this storage device,
+     * then this includes files stored under {@link Context#getObbDir()}.
+     * <p>
      * Code is shared between all users on a multiuser device.
      */
     public long getCodeBytes() {
@@ -51,6 +50,12 @@
      * {@link Context#getDataDir()}, {@link Context#getCacheDir()},
      * {@link Context#getCodeCacheDir()}.
      * <p>
+     * If the primary external/shared storage is hosted on this storage device,
+     * then this includes files stored under
+     * {@link Context#getExternalFilesDir(String)},
+     * {@link Context#getExternalCacheDir()}, and
+     * {@link Context#getExternalMediaDirs()}.
+     * <p>
      * Data is isolated for each user on a multiuser device.
      */
     public long getDataBytes() {
@@ -61,6 +66,10 @@
      * Return the size of all cached data. This includes files stored under
      * {@link Context#getCacheDir()} and {@link Context#getCodeCacheDir()}.
      * <p>
+     * If the primary external/shared storage is hosted on this storage device,
+     * then this includes files stored under
+     * {@link Context#getExternalCacheDir()}.
+     * <p>
      * Cached data is isolated for each user on a multiuser device.
      */
     public long getCacheBytes() {
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index 4b6479a..5497d57 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -73,7 +73,8 @@
     }
 
     /**
-     * Return the total size of the media hosting this storage volume.
+     * Return the total size of the underlying media that is hosting this
+     * storage volume.
      * <p>
      * To reduce end user confusion, this value matches the total storage size
      * advertised in a retail environment, which is typically larger than the
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/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 1ca2be5..d1ad8de 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -422,8 +422,6 @@
      * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
      * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param device Bluetooth device
      * @return priority of the device
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 845a47d..d60d4db 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -466,6 +466,30 @@
         "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
 
     /**
+     * Intent used to broadcast the change in the Bluetooth address
+     * of the local Bluetooth adapter.
+     * <p>Always contains the extra field {@link
+     * #EXTRA_BLUETOOTH_ADDRESS} containing the Bluetooth address.
+     *
+     * Note: only system level processes are allowed to send this
+     * defined broadcast.
+     *
+     * @hide
+     */
+    public static final String ACTION_BLUETOOTH_ADDRESS_CHANGED =
+        "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED";
+
+    /**
+     * Used as a String extra field in {@link
+     * #ACTION_BLUETOOTH_ADDRESS_CHANGED} intent to store the local
+     * Bluetooth address.
+     *
+     * @hide
+     */
+    public static final String EXTRA_BLUETOOTH_ADDRESS =
+          "android.bluetooth.adapter.extra.BLUETOOTH_ADDRESS";
+
+    /**
      * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
      * by BLE Always on enabled application to know the ACL_CONNECTED event
      * when Bluetooth state in STATE_BLE_ON. This denotes GATT connection
@@ -673,7 +697,6 @@
      * Return true if Bluetooth is currently enabled and ready for use.
      * <p>Equivalent to:
      * <code>getBluetoothState() == STATE_ON</code>
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return true if the local adapter is turned on
      */
@@ -811,7 +834,6 @@
      * {@link #STATE_TURNING_ON},
      * {@link #STATE_ON},
      * {@link #STATE_TURNING_OFF}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return current state of Bluetooth adapter
      */
@@ -854,7 +876,6 @@
      * {@link #STATE_ON},
      * {@link #STATE_TURNING_OFF},
      * {@link #STATE_BLE_TURNING_OFF}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return current state of Bluetooth adapter
      * @hide
@@ -910,8 +931,6 @@
      * #STATE_ON}. If this call returns false then there was an
      * immediate problem that will prevent the adapter from being turned on -
      * such as Airplane mode, or the adapter is already turned on.
-     * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission
      *
      * @return true to indicate adapter startup has begun, or false on
      *         immediate error
@@ -946,8 +965,6 @@
      * #STATE_ON}. If this call returns false then there was an
      * immediate problem that will prevent the adapter from being turned off -
      * such as the adapter already being turned off.
-     * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission
      *
      * @return true to indicate adapter shutdown has begun, or false on
      *         immediate error
@@ -981,7 +998,6 @@
     /**
      * Returns the hardware address of the local Bluetooth adapter.
      * <p>For example, "00:11:22:AA:BB:CC".
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return Bluetooth hardware address as string
      */
@@ -1085,7 +1101,6 @@
      * will return false. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
      *
      * @param name a valid Bluetooth name
      * @return     true if the name was set, false otherwise
@@ -1116,7 +1131,6 @@
      * will return {@link #SCAN_MODE_NONE}. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return scan mode
      */
@@ -1255,7 +1269,6 @@
      * will return false. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
      * @return true on success, false on error
      */
@@ -1275,7 +1288,6 @@
 
     /**
      * Cancel the current device discovery process.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      * <p>Because discovery is a heavyweight procedure for the Bluetooth
      * adapter, this method should always be called before attempting to connect
      * to a remote device with {@link
@@ -1319,7 +1331,6 @@
      * will return false. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
      * @return true if discovering
      */
@@ -1484,8 +1495,8 @@
     }
 
     /**
-     * Return the maximum LE advertising data length,
-     * if LE Extended Advertising feature is supported.
+     * Return the maximum LE advertising data length in bytes,
+     * if LE Extended Advertising feature is supported, 0 otherwise.
      *
      * @return the maximum LE advertising data length.
      */
@@ -1586,7 +1597,6 @@
      * will return an empty set. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
      * @return unmodifiable set of {@link BluetoothDevice}, or null on error
      */
@@ -1671,8 +1681,6 @@
      * Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET},
      * {@link BluetoothProfile#A2DP}.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
-     *
      * <p> Return value can be one of
      * {@link BluetoothProfile#STATE_DISCONNECTED},
      * {@link BluetoothProfile#STATE_CONNECTING},
@@ -1762,7 +1770,6 @@
      * closed, or if this application closes unexpectedly.
      * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
      * connect to this socket from another device using the same {@link UUID}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
      * @return a listening RFCOMM BluetoothServerSocket
@@ -1794,7 +1801,6 @@
      * closed, or if this application closes unexpectedly.
      * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
      * connect to this socket from another device using the same {@link UUID}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
      * @return a listening RFCOMM BluetoothServerSocket
@@ -2386,8 +2392,6 @@
      * <p>Results of the scan are reported using the
      * {@link LeScanCallback#onLeScan} callback.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
      * @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
@@ -2406,8 +2410,6 @@
      * <p>Devices which advertise all specified services are reported using the
      * {@link LeScanCallback#onLeScan} callback.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
      * @param serviceUuids Array of services to look for
      * @param callback the callback LE scan results are delivered
      * @return true, if the scan was started successfully
@@ -2495,8 +2497,6 @@
     /**
      * Stops an ongoing Bluetooth LE device scan.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
-     *
      * @param callback used to identify which scan to stop
      *        must be the same handle used to start the scan
      * @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index e6cebc0..c427268 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -22,6 +22,8 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelUuid;
@@ -593,32 +595,38 @@
     public static final int TRANSPORT_LE = 2;
 
     /**
-     * Bluetooth LE 1M PHY.
+     * Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
+     * connection.
      */
     public static final int PHY_LE_1M = 1;
 
     /**
-     * Bluetooth LE 2M PHY.
+     * Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
+     * connection.
      */
     public static final int PHY_LE_2M = 2;
 
     /**
-     * Bluetooth LE Coded PHY.
+     * Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
+     * or connection.
      */
     public static final int PHY_LE_CODED = 3;
 
     /**
-     * Bluetooth LE 1M PHY mask.
+     * Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
+     * options in a bitmask.
      */
     public static final int PHY_LE_1M_MASK = 1;
 
     /**
-     * Bluetooth LE 2M PHY mask.
+     * Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
+     * options in a bitmask.
      */
     public static final int PHY_LE_2M_MASK = 2;
 
     /**
-     * Bluetooth LE Coded PHY mask.
+     * Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
+     * available options in a bitmask.
      */
     public static final int PHY_LE_CODED_MASK = 4;
 
@@ -762,7 +770,6 @@
      * <p>The local adapter will automatically retrieve remote names when
      * performing a device scan, and will cache them. This method just returns
      * the name for this device from the cache.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @return the Bluetooth name, or null if there was a problem.
      */
@@ -781,8 +788,6 @@
     /**
      * Get the Bluetooth device type of the remote device.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
-     *
      * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE}
      *                         {@link #DEVICE_TYPE_DUAL}.
      *         {@link #DEVICE_TYPE_UNKNOWN} if it's not available
@@ -862,7 +867,6 @@
      * the bonding process completes, and its result.
      * <p>Android system services will handle the necessary user interactions
      * to confirm and complete the bonding process.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
      * @return false on immediate error, true if bonding will begin
      */
@@ -1022,7 +1026,6 @@
      * {@link #BOND_NONE},
      * {@link #BOND_BONDING},
      * {@link #BOND_BONDED}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
      * @return the bond state
      */
@@ -1089,7 +1092,6 @@
 
     /**
      * Get the Bluetooth class of the remote device.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
      * @return Bluetooth class object, or null on error
      */
@@ -1114,7 +1116,6 @@
      * from the remote device. Instead, the local cached copy of the service
      * UUIDs are returned.
      * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
      * @return the supported features (UUIDs) of the remote device,
      *         or null on error
@@ -1140,7 +1141,6 @@
       * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
       * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
       * if service discovery is not to be performed.
-      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
       *
       * @return False if the sanity check fails, True if the process
       *               of initiating an ACL connection to the remote device
@@ -1221,7 +1221,6 @@
 
     /**
      * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
      *
      * @return true confirmation has been sent out
      *         false for error
@@ -1502,7 +1501,6 @@
      * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
      * However if you are connecting to an Android peer then please generate
      * your own unique UUID.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @param uuid service record uuid to lookup RFCOMM channel
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
@@ -1541,7 +1539,6 @@
      * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
      * However if you are connecting to an Android peer then please generate
      * your own unique UUID.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @param uuid service record uuid to lookup RFCOMM channel
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
@@ -1679,12 +1676,45 @@
      *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
      * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
      *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
-     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if
-     *             {@code autoConnect} is set to true.
-     * @throws IllegalArgumentException if callback is null
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
+     *             if {@code autoConnect} is set to true.
+     * @throws NullPointerException if callback is null
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                      BluetoothGattCallback callback, int transport, int phy) {
+        return connectGatt(context, autoConnect,callback, TRANSPORT_AUTO, PHY_LE_1M_MASK, null);
+    }
+
+    /**
+     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+     * The callback is used to deliver results to Caller, such as connection status as well
+     * as any further GATT client operations.
+     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+     * GATT client operations.
+     * @param callback GATT callback handler that will receive asynchronous callbacks.
+     * @param autoConnect Whether to directly connect to the remote device (false)
+     *                    or to automatically connect as soon as the remote
+     *                    device becomes available (true).
+     * @param transport preferred transport for GATT connections to remote dual-mode devices
+     *             {@link BluetoothDevice#TRANSPORT_AUTO} or
+     *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
+     *             if {@code autoConnect} is set to true.
+     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
+     *             on the service's main thread.
+     * @throws NullPointerException if callback is null
+     */
+    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+                                     BluetoothGattCallback callback, int transport, int phy,
+                                     Handler handler) {
+        if (callback == null)
+            throw new NullPointerException("callback is null");
+
+        if (handler == null)
+            handler = new Handler(Looper.getMainLooper());
+
         // TODO(Bluetooth) check whether platform support BLE
         //     Do the check here or in GattServer?
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1696,7 +1726,7 @@
                 return null;
             }
             BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, phy);
-            gatt.connect(autoConnect, callback);
+            gatt.connect(autoConnect, callback, handler);
             return gatt;
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 4aaf6bd..713dbf4 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.content.Context;
+import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Log;
@@ -43,6 +44,7 @@
 
     private IBluetoothGatt mService;
     private BluetoothGattCallback mCallback;
+    private Handler mHandler;
     private int mClientIf;
     private BluetoothDevice mDevice;
     private boolean mAutoConnect;
@@ -154,8 +156,14 @@
                 }
                 mClientIf = clientIf;
                 if (status != GATT_SUCCESS) {
-                    mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
-                                                      BluetoothProfile.STATE_DISCONNECTED);
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
+                                              BluetoothProfile.STATE_DISCONNECTED);
+                        }
+                    });
+
                     synchronized(mStateLock) {
                         mConnState = CONN_STATE_IDLE;
                     }
@@ -181,11 +189,12 @@
                     return;
                 }
 
-                try {
-                    mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
+                    }
+                });
             }
 
             /**
@@ -200,11 +209,12 @@
                     return;
                 }
 
-                try {
-                    mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
+                    }
+                });
             }
 
             /**
@@ -221,11 +231,13 @@
                 }
                 int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
                                                BluetoothProfile.STATE_DISCONNECTED;
-                try {
-                    mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
+                    }
+                });
 
                 synchronized(mStateLock) {
                     if (connected) {
@@ -279,11 +291,12 @@
                     }
                 }
 
-                try {
-                    mCallback.onServicesDiscovered(BluetoothGatt.this, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onServicesDiscovered(BluetoothGatt.this, status);
+                    }
+                });
             }
 
             /**
@@ -328,11 +341,12 @@
 
                 if (status == 0) characteristic.setValue(value);
 
-                try {
-                    mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
+                    }
+                });
             }
 
             /**
@@ -373,11 +387,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
+                    }
+                });
             }
 
             /**
@@ -398,11 +413,12 @@
 
                 characteristic.setValue(value);
 
-                try {
-                    mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
+                    }
+                });
             }
 
             /**
@@ -442,11 +458,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
+                    }
+                });
             }
 
             /**
@@ -485,11 +502,12 @@
 
                 mAuthRetryState = AUTH_RETRY_STATE_IDLE;
 
-                try {
-                    mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
+                    }
+                });
             }
 
             /**
@@ -508,11 +526,12 @@
                     mDeviceBusy = false;
                 }
 
-                try {
-                    mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
+                    }
+                });
             }
 
             /**
@@ -526,11 +545,12 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
+                    }
+                });
             }
 
             /**
@@ -544,11 +564,13 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
+                    }
+                });
             }
 
             /**
@@ -564,12 +586,14 @@
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
-                try {
-                    mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
-                                                  timeout, status);
-                } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception in callback", ex);
-                }
+
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
+                                                      timeout, status);
+                    }
+                });
             }
         };
 
@@ -659,11 +683,12 @@
      * @return If true, the callback will be called to notify success or failure,
      *         false on immediate error
      */
-    private boolean registerApp(BluetoothGattCallback callback) {
+    private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
         if (DBG) Log.d(TAG, "registerApp()");
         if (mService == null) return false;
 
         mCallback = callback;
+        mHandler = handler;
         UUID uuid = UUID.randomUUID();
         if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
 
@@ -716,7 +741,8 @@
      *                    device becomes available (true).
      * @return true, if the connection attempt was initiated successfully
      */
-    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
+    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
+                                Handler handler) {
         if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
         synchronized(mStateLock) {
             if (mConnState != CONN_STATE_IDLE) {
@@ -727,7 +753,7 @@
 
         mAutoConnect = autoConnect;
 
-        if (!registerApp(callback)) {
+        if (!registerApp(callback, handler)) {
             synchronized(mStateLock) {
                 mConnState = CONN_STATE_IDLE;
             }
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 11a15c6..c6f82ff 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -30,7 +30,8 @@
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
      * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status status of the operation
+     * @param status Status of the PHY update operation.
+     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
      */
     public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
     }
@@ -43,7 +44,8 @@
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
      * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
-     * @param status status of the operation
+     * @param status Status of the PHY read operation.
+     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
      */
     public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
     }
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index 3b8f962..02307bd 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -167,7 +167,8 @@
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
      * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status status of the operation
+     * @param status Status of the PHY update operation.
+     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
      */
     public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
     }
@@ -180,7 +181,8 @@
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
      * @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
      *             {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
-     * @param status status of the operation
+     * @param status Status of the PHY read operation.
+     *                  {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
      */
     public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
     }
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index 29283e7..c7191ba 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -85,8 +85,6 @@
      * This can be used by applications like status bar which would just like
      * to know the state of Bluetooth.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param device Remote bluetooth device.
      * @param profile GATT or GATT_SERVER
      * @return State of the profile connection. One of
@@ -118,8 +116,6 @@
      * This can be used by applications like status bar which would just like
      * to know the state of Bluetooth.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param profile GATT or GATT_SERVER
      * @return List of devices. The list will be empty on error.
      */
@@ -159,8 +155,6 @@
      * This can be used by applications like status bar which would just like
      * to know the state of the local adapter.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param profile GATT or GATT_SERVER
      * @param states Array of states. States can be one of
      *        {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 2f64c71..c5b58e9 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -187,8 +187,6 @@
      *
      * <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @return List of devices. The list will be empty on error.
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
@@ -201,8 +199,6 @@
      * <p> If none of the devices match any of the given states,
      * an empty list will be returned.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param states Array of states. States can be one of
      *              {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
      *              {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
@@ -214,8 +210,6 @@
     /**
      * Get the current connection state of the profile
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
-     *
      * @param device Remote bluetooth device.
      * @return State of the profile connection. One of
      *               {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 582709c..12e9baa 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -32,7 +32,6 @@
 
 import android.bluetooth.IBluetoothGattCallback;
 import android.bluetooth.IBluetoothGattServerCallback;
-import android.bluetooth.le.IAdvertiserCallback;
 import android.bluetooth.le.IAdvertisingSetCallback;
 import android.bluetooth.le.IPeriodicAdvertisingCallback;
 import android.bluetooth.le.IScannerCallback;
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index ea3031b..0c7958d 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -22,7 +22,6 @@
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
-import android.bluetooth.le.IAdvertiserCallback;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelUuid;
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index b65a7ad..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";
@@ -100,7 +100,6 @@
      * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
      * delivered through {@code callback}.
      * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
      * An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
@@ -117,7 +116,6 @@
     /**
      * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
      * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
      * An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
@@ -243,8 +241,6 @@
 
     /**
      * Stops an ongoing Bluetooth LE scan.
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
      *
      * @param callback
      */
@@ -263,8 +259,6 @@
 
     /**
      * Stops an ongoing Bluetooth LE scan started using a PendingIntent.
-     * <p>
-     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
      *
      * @param callbackIntent The PendingIntent that was used to start the scan.
      * @see #startScan(List, ScanSettings, PendingIntent)
diff --git a/core/java/android/bluetooth/le/IAdvertiserCallback.aidl b/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
deleted file mode 100644
index c58b1df..0000000
--- a/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
+++ /dev/null
@@ -1,29 +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.bluetooth.le;
-
-import android.bluetooth.le.AdvertiseSettings;
-
-/**
- * Callback definitions for interacting with Advertiser
- * @hide
- */
-oneway interface IAdvertiserCallback {
-    void onAdvertiserRegistered(in int status, in int advertiserId);
-
-    void onMultiAdvertiseCallback(in int status, boolean isStart,
-                                  in AdvertiseSettings advertiseSettings);
-}
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/ClipDescription.java b/core/java/android/content/ClipDescription.java
index d8ff222..8e30fd6 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -148,7 +148,7 @@
      * Used for setting the timestamp at which the associated {@link ClipData} is copied to
      * global clipboard.
      *
-     * @param timeStamp at which the associated {@link ClipData} is copeid to clipboard in
+     * @param timeStamp at which the associated {@link ClipData} is copied to clipboard in
      *                  {@link System#currentTimeMillis()} time base.
      * @hide
      */
diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java
index b78548b..6576c0f 100644
--- a/core/java/android/content/ComponentCallbacks2.java
+++ b/core/java/android/content/ComponentCallbacks2.java
@@ -16,6 +16,11 @@
 
 package android.content;
 
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Extended {@link ComponentCallbacks} interface with a new callback for
  * finer-grained memory management. This interface is available in all application components
@@ -83,6 +88,19 @@
  */
 public interface ComponentCallbacks2 extends ComponentCallbacks {
 
+    /** @hide */
+    @IntDef(prefix = { "TRIM_MEMORY_" }, value = {
+            TRIM_MEMORY_COMPLETE,
+            TRIM_MEMORY_MODERATE,
+            TRIM_MEMORY_BACKGROUND,
+            TRIM_MEMORY_UI_HIDDEN,
+            TRIM_MEMORY_RUNNING_CRITICAL,
+            TRIM_MEMORY_RUNNING_LOW,
+            TRIM_MEMORY_RUNNING_MODERATE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TrimMemoryLevel {}
+
     /**
      * Level for {@link #onTrimMemory(int)}: the process is nearing the end
      * of the background LRU list, and if more memory isn't found soon it will
@@ -132,7 +150,6 @@
      */
     static final int TRIM_MEMORY_RUNNING_LOW = 10;
 
-
     /**
      * Level for {@link #onTrimMemory(int)}: the process is not an expendable
      * background process, but the device is running moderately low on memory.
@@ -155,11 +172,7 @@
      * ActivityManager.getMyMemoryState(RunningAppProcessInfo)}.
      *
      * @param level The context of the trim, giving a hint of the amount of
-     * trimming the application may like to perform.  May be
-     * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE},
-     * {@link #TRIM_MEMORY_BACKGROUND}, {@link #TRIM_MEMORY_UI_HIDDEN},
-     * {@link #TRIM_MEMORY_RUNNING_CRITICAL}, {@link #TRIM_MEMORY_RUNNING_LOW},
-     * or {@link #TRIM_MEMORY_RUNNING_MODERATE}.
+     * trimming the application may like to perform.
      */
-    void onTrimMemory(int level);
+    void onTrimMemory(@TrimMemoryLevel int level);
 }
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..2e2d444 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);
 
     /**
@@ -2954,9 +2967,6 @@
      *  <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
      *  <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
      *  handling management of network connections.
-     *  <dt> {@link #IPSEC_SERVICE} ("ipsec")
-     *  <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
-     *  sockets and networks.
      *  <dt> {@link #WIFI_SERVICE} ("wifi")
      *  <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
      *  connectivity.  On releases before NYC, it should only be obtained from an application
@@ -3048,7 +3058,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 +3088,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 +3102,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
@@ -3301,6 +3311,7 @@
      * {@link android.net.IpSecManager} for encrypting Sockets or Networks with
      * IPSec.
      *
+     * @hide
      * @see #getSystemService
      */
     public static final String IPSEC_SERVICE = "ipsec";
@@ -3756,7 +3767,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 +4192,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 +4221,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 +4240,7 @@
      * @see #checkCallingUriPermission
      */
     @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)")
+    @PackageManager.PermissionResult
     public abstract int checkCallingOrSelfUriPermission(Uri uri,
             @Intent.AccessUriMode int modeFlags);
 
@@ -4250,6 +4265,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 +4352,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 +4431,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 +4450,7 @@
      * @hide
      */
     public abstract Context createPackageContextAsUser(
-            String packageName, int flags, UserHandle user)
+            String packageName, @CreatePackageOptions int flags, UserHandle user)
             throws PackageManager.NameNotFoundException;
 
     /**
@@ -4438,7 +4459,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 13d7362..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";
 
     /**
@@ -4307,34 +4313,34 @@
      * learned in advance, e.g., when creating or saving content, to avoid increasing latency to
      * start {@link #ACTION_CHOOSER}. Performance on customized annotations can suffer, if they are
      * rarely used for {@link #ACTION_CHOOSER} in the past 14 days. Therefore, it is recommended to
-     * use the following annotations when applicable:</p>
+     * use the following annotations when applicable.</p>
      * <ul>
-     *     <li>"product": represents that the topic of the content is mainly about products, e.g.,
+     *     <li>"product" represents that the topic of the content is mainly about products, e.g.,
      *     health & beauty, and office supplies.</li>
-     *     <li>"emotion": represents that the topic of the content is mainly about emotions, e.g.,
+     *     <li>"emotion" represents that the topic of the content is mainly about emotions, e.g.,
      *     happy, and sad.</li>
-     *     <li>"person": represents that the topic of the content is mainly about persons, e.g.,
+     *     <li>"person" represents that the topic of the content is mainly about persons, e.g.,
      *     face, finger, standing, and walking.</li>
-     *     <li>"child": represents that the topic of the content is mainly about children, e.g.,
+     *     <li>"child" represents that the topic of the content is mainly about children, e.g.,
      *     child, and baby.</li>
-     *     <li>"selfie": represents that the topic of the content is mainly about selfies.</li>
-     *     <li>"crowd": represents that the topic of the content is mainly about crowds.</li>
-     *     <li>"party": represents that the topic of the content is mainly about parties.</li>
-     *     <li>"animal": represent that the topic of the content is mainly about animals.</li>
-     *     <li>"plant": represents that the topic of the content is mainly about plants, e.g.,
+     *     <li>"selfie" represents that the topic of the content is mainly about selfies.</li>
+     *     <li>"crowd" represents that the topic of the content is mainly about crowds.</li>
+     *     <li>"party" represents that the topic of the content is mainly about parties.</li>
+     *     <li>"animal" represent that the topic of the content is mainly about animals.</li>
+     *     <li>"plant" represents that the topic of the content is mainly about plants, e.g.,
      *     flowers.</li>
-     *     <li>"vacation": represents that the topic of the content is mainly about vacations.</li>
-     *     <li>"fashion": represents that the topic of the content is mainly about fashion, e.g.
+     *     <li>"vacation" represents that the topic of the content is mainly about vacations.</li>
+     *     <li>"fashion" represents that the topic of the content is mainly about fashion, e.g.
      *     sunglasses, jewelry, handbags and clothing.</li>
-     *     <li>"material": represents that the topic of the content is mainly about materials, e.g.,
+     *     <li>"material" represents that the topic of the content is mainly about materials, e.g.,
      *     paper, and silk.</li>
-     *     <li>"vehicle": represents that the topic of the content is mainly about vehicles, like
+     *     <li>"vehicle" represents that the topic of the content is mainly about vehicles, like
      *     cars, and boats.</li>
-     *     <li>"document": represents that the topic of the content is mainly about documents, e.g.
+     *     <li>"document" represents that the topic of the content is mainly about documents, e.g.
      *     posters.</li>
-     *     <li>"design": represents that the topic of the content is mainly about design, e.g. arts
+     *     <li>"design" represents that the topic of the content is mainly about design, e.g. arts
      *     and designs of houses.</li>
-     *     <li>"holiday": represents that the topic of the content is mainly about holidays, e.g.,
+     *     <li>"holiday" represents that the topic of the content is mainly about holidays, e.g.,
      *     Christmas and Thanksgiving.</li>
      * </ul>
      */
@@ -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/IntentFilter.java b/core/java/android/content/IntentFilter.java
index d64f018..c9bce53 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.net.Uri;
 import android.os.Parcel;
@@ -33,6 +34,8 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Set;
@@ -283,9 +286,22 @@
     private static final int STATE_VERIFIED            = 0x00001000;
 
     private int mVerifyState;
-
+    /** @hide */
+    public static final int VISIBILITY_NONE = 0;
+    /** @hide */
+    public static final int VISIBILITY_EXPLICIT = 1;
+    /** @hide */
+    public static final int VISIBILITY_IMPLICIT = 2;
+    /** @hide */
+    @IntDef(prefix = { "VISIBILITY_" }, value = {
+            VISIBILITY_NONE,
+            VISIBILITY_EXPLICIT,
+            VISIBILITY_IMPLICIT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InstantAppVisibility {}
     /** Whether or not the intent filter is visible to instant apps. */
-    private boolean mVisibleToInstantApp;
+    private @InstantAppVisibility int mInstantAppVisibility;
     // These functions are the start of more optimized code for managing
     // the string sets...  not yet implemented.
 
@@ -452,7 +468,7 @@
         }
         mHasPartialTypes = o.mHasPartialTypes;
         mVerifyState = o.mVerifyState;
-        mVisibleToInstantApp = o.mVisibleToInstantApp;
+        mInstantAppVisibility = o.mInstantAppVisibility;
     }
 
     /**
@@ -655,12 +671,24 @@
     }
 
     /** @hide */
-    public void setVisibleToInstantApp(boolean visibleToInstantApp) {
-        mVisibleToInstantApp = visibleToInstantApp;
+    public void setVisibilityToInstantApp(@InstantAppVisibility int visibility) {
+        mInstantAppVisibility = visibility;
+    }
+    /** @hide */
+    public @InstantAppVisibility int getVisibilityToInstantApp() {
+        return mInstantAppVisibility;
     }
     /** @hide */
     public boolean isVisibleToInstantApp() {
-        return mVisibleToInstantApp;
+        return mInstantAppVisibility != VISIBILITY_NONE;
+    }
+    /** @hide */
+    public boolean isExplicitlyVisibleToInstantApp() {
+        return mInstantAppVisibility == VISIBILITY_EXPLICIT;
+    }
+    /** @hide */
+    public boolean isImplicitlyVisibleToInstantApp() {
+        return mInstantAppVisibility == VISIBILITY_IMPLICIT;
     }
 
     /**
@@ -1859,7 +1887,7 @@
         dest.writeInt(mPriority);
         dest.writeInt(mHasPartialTypes ? 1 : 0);
         dest.writeInt(getAutoVerify() ? 1 : 0);
-        dest.writeInt(isVisibleToInstantApp() ? 1 : 0);
+        dest.writeInt(mInstantAppVisibility);
     }
 
     /**
@@ -1928,7 +1956,7 @@
         mPriority = source.readInt();
         mHasPartialTypes = source.readInt() > 0;
         setAutoVerify(source.readInt() > 0);
-        setVisibleToInstantApp(source.readInt() > 0);
+        setVisibilityToInstantApp(source.readInt());
     }
 
     private final boolean findMimeType(String type) {
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b01e6a1..0be0885 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.annotation.IntDef;
+import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Configuration.NativeConfig;
 import android.os.Parcel;
@@ -412,17 +413,33 @@
     public static final int FLAG_ALWAYS_FOCUSABLE = 0x40000;
 
     /**
-     * Bit in {@link #flags} indicating if the activity is visible to ephemeral applications.
+     * Bit in {@link #flags} indicating if the activity is visible to instant
+     * applications. The activity is visible if it's either implicitly or
+     * explicitly exposed.
      * @hide
      */
-    public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+    public static final int FLAG_VISIBLE_TO_INSTANT_APP = 0x100000;
+
+    /**
+     * Bit in {@link #flags} indicating if the activity is implicitly visible
+     * to instant applications. Implicitly visible activities are those that
+     * implement certain intent-filters:
+     * <ul>
+     * <li>action {@link Intent#CATEGORY_BROWSABLE}</li>
+     * <li>action {@link Intent#ACTION_SEND}</li>
+     * <li>action {@link Intent#ACTION_SENDTO}</li>
+     * <li>action {@link Intent#ACTION_SEND_MULTIPLE}</li>
+     * </ul>
+     * @hide
+     */
+    public static final int FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP = 0x200000;
 
     /**
      * Bit in {@link #flags} indicating if the activity supports picture-in-picture mode.
      * See {@link android.R.attr#supportsPictureInPicture}.
      * @hide
      */
-    public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x200000;
+    public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000;
 
     /**
      * @hide Bit in {@link #flags}: If set, this component will only be seen
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index b0f8aa7..6c5d26a 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -891,7 +891,7 @@
     public @Category int category = CATEGORY_UNDEFINED;
 
     /** {@hide} */
-    @IntDef({
+    @IntDef(prefix = { "CATEGORY_" }, value = {
             CATEGORY_UNDEFINED,
             CATEGORY_GAME,
             CATEGORY_AUDIO,
diff --git a/core/java/android/content/pm/ChangedPackages.java b/core/java/android/content/pm/ChangedPackages.java
index 78c057d..b78c71d 100644
--- a/core/java/android/content/pm/ChangedPackages.java
+++ b/core/java/android/content/pm/ChangedPackages.java
@@ -35,7 +35,6 @@
     /** The names of the packages that have changed */
     private final List<String> mPackageNames;
 
-    @TestApi
     public ChangedPackages(int sequenceNumber, @NonNull List<String> packageNames) {
         this.mSequenceNumber = sequenceNumber;
         this.mPackageNames = packageNames;
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index bc7a612..c7dd1fa 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -474,15 +474,6 @@
     void notifyDexLoad(String loadingPackageName, in List<String> dexPaths, String loaderIsa);
 
     /**
-     * Ask the package manager to perform dex-opt (if needed) on the given
-     * package if it already hasn't done so.
-     *
-     * In most cases, apps are dexopted in advance and this function will
-     * be a no-op.
-     */
-    boolean performDexOptIfNeeded(String packageName);
-
-    /**
      * Ask the package manager to perform a dex-opt for the given reason. The package
      * manager will map the reason to a compiler filter according to the current system
      * configuration.
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 9e4a86d..aaaff0c 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1084,8 +1084,6 @@
 
         /**
          * Sets which runtime permissions to be granted to the package at installation.
-         * Using this API requires holding {@link android.Manifest.permission
-         * #INSTALL_GRANT_RUNTIME_PERMISSIONS}
          *
          * @param permissions The permissions to grant or null to grant all runtime
          *     permissions.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b8c87e6..d2468d9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -119,7 +119,7 @@
      */
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_ACTIVITIES,
             GET_CONFIGURATIONS,
             GET_GIDS,
@@ -148,7 +148,7 @@
     public @interface PackageInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
             GET_SHARED_LIBRARY_FILES,
             MATCH_UNINSTALLED_PACKAGES,
@@ -164,7 +164,7 @@
     public @interface ApplicationInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
             GET_SHARED_LIBRARY_FILES,
             MATCH_ALL,
@@ -185,7 +185,7 @@
     public @interface ComponentInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
             GET_RESOLVED_FILTER,
             GET_SHARED_LIBRARY_FILES,
@@ -207,21 +207,21 @@
     public @interface ResolveInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionGroupInfoFlags {}
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "GET_", "MATCH_" }, value = {
             GET_META_DATA,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -461,12 +461,20 @@
 
     /**
      * Internal {@link PackageInfo} flag: include only components that are exposed to
-     * ephemeral apps.
+     * instant apps. Matched components may have been either explicitly or implicitly
+     * exposed.
      * @hide
      */
     public static final int MATCH_VISIBLE_TO_INSTANT_APP_ONLY = 0x01000000;
 
     /**
+     * Internal {@link PackageInfo} flag: include only components that have been
+     * explicitly exposed to instant apps.
+     * @hide
+     */
+    public static final int MATCH_EXPLICITLY_VISIBLE_ONLY = 0x02000000;
+
+    /**
      * Internal flag used to indicate that a system component has done their
      * homework and verified that they correctly handle packages and components
      * that come and go over time. In particular:
@@ -503,7 +511,10 @@
     public static final int ONLY_IF_NO_MATCH_FOUND = 0x00000004;
 
     /** @hide */
-    @IntDef({PERMISSION_GRANTED, PERMISSION_DENIED})
+    @IntDef(prefix = { "PERMISSION_" }, value = {
+            PERMISSION_GRANTED,
+            PERMISSION_DENIED
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionResult {}
 
@@ -519,6 +530,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.
@@ -555,11 +578,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;
 
@@ -603,7 +640,7 @@
     public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "INSTALL_" }, value = {
             INSTALL_FORWARD_LOCK,
             INSTALL_REPLACE_EXISTING,
             INSTALL_ALLOW_TEST,
@@ -761,6 +798,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
@@ -770,8 +814,13 @@
     public static final int DONT_KILL_APP = 0x00000001;
 
     /** @hide */
-    @IntDef({INSTALL_REASON_UNKNOWN, INSTALL_REASON_POLICY, INSTALL_REASON_DEVICE_RESTORE,
-            INSTALL_REASON_DEVICE_SETUP, INSTALL_REASON_USER})
+    @IntDef(prefix = { "INSTALL_REASON_" }, value = {
+            INSTALL_REASON_UNKNOWN,
+            INSTALL_REASON_POLICY,
+            INSTALL_REASON_DEVICE_RESTORE,
+            INSTALL_REASON_DEVICE_SETUP,
+            INSTALL_REASON_USER
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InstallReason {}
 
@@ -1247,7 +1296,7 @@
     public static final int INSTALL_FAILED_INSTANT_APP_INVALID = -116;
 
     /** @hide */
-    @IntDef(flag = true, value = {
+    @IntDef(flag = true, prefix = { "DELETE_" }, value = {
             DELETE_KEEP_DATA,
             DELETE_ALL_USERS,
             DELETE_SYSTEM_APP,
@@ -2768,44 +2817,17 @@
      * installed on the system.
      *
      * @param packageName The full name (i.e. com.google.apps.contacts) of the
-     *         desired package.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
-     * @return A PackageInfo object containing information about the
-     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the
-     *         package is not found in the list of installed applications, the
-     *         package information is retrieved from the list of uninstalled
+     *            desired package.
+     * @param flags Additional option flags to modify the data returned.
+     * @return A PackageInfo object containing information about the package. If
+     *         flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the package
+     *         is not found in the list of installed applications, the package
+     *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags)
             throws NameNotFoundException;
@@ -2813,51 +2835,24 @@
     /**
      * Retrieve overall information about an application package that is
      * installed on the system. This method can be used for retrieving
-     * information about packages for which multiple versions can be
-     * installed at the time. Currently only packages hosting static shared
-     * libraries can have multiple installed versions. The method can also
-     * be used to get info for a package that has a single version installed
-     * by passing {@link #VERSION_CODE_HIGHEST} in the {@link VersionedPackage}
+     * information about packages for which multiple versions can be installed
+     * at the time. Currently only packages hosting static shared libraries can
+     * have multiple installed versions. The method can also be used to get info
+     * for a package that has a single version installed by passing
+     * {@link #VERSION_CODE_HIGHEST} in the {@link VersionedPackage}
      * constructor.
      *
      * @param versionedPackage The versioned package for which to query.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
-     * @return A PackageInfo object containing information about the
-     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the
-     *         package is not found in the list of installed applications, the
-     *         package information is retrieved from the list of uninstalled
+     * @param flags Additional option flags to modify the data returned.
+     * @return A PackageInfo object containing information about the package. If
+     *         flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the package
+     *         is not found in the list of installed applications, the package
+     *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract PackageInfo getPackageInfo(VersionedPackage versionedPackage,
             @PackageInfoFlags int flags) throws NameNotFoundException;
@@ -2867,46 +2862,18 @@
      * installed on the system.
      *
      * @param packageName The full name (i.e. com.google.apps.contacts) of the
-     *         desired package.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
+     *            desired package.
+     * @param flags Additional option flags to modify the data returned.
      * @param userId The user id.
-     *
-     * @return A PackageInfo object containing information about the
-     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the
-     *         package is not found in the list of installed applications, the
-     *         package information is retrieved from the list of uninstalled
+     * @return A PackageInfo object containing information about the package. If
+     *         flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the package
+     *         is not found in the list of installed applications, the package
+     *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
-     *
      * @hide
      */
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
@@ -2945,7 +2912,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
@@ -2959,7 +2926,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
@@ -2975,7 +2942,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;
 
     /**
@@ -3048,16 +3015,12 @@
      * Retrieve all of the information we know about a particular permission.
      *
      * @param name The fully qualified name (i.e. com.google.permission.LOGIN)
-     *         of the permission you are interested in.
-     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
-     *         retrieve any meta-data associated with the permission.
-     *
+     *            of the permission you are interested in.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a {@link PermissionInfo} containing information about the
      *         permission.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     *
-     * @see #GET_META_DATA
      */
     public abstract PermissionInfo getPermissionInfo(String name, @PermissionInfoFlags int flags)
             throws NameNotFoundException;
@@ -3066,17 +3029,13 @@
      * Query for all of the permissions associated with a particular group.
      *
      * @param group The fully qualified name (i.e. com.google.permission.LOGIN)
-     *         of the permission group you are interested in.  Use null to
-     *         find all of the permissions not associated with a group.
-     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
-     *         retrieve any meta-data associated with the permissions.
-     *
+     *            of the permission group you are interested in. Use null to
+     *            find all of the permissions not associated with a group.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a list of {@link PermissionInfo} containing information
-     *             about all of the permissions in the given group.
+     *         about all of the permissions in the given group.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     *
-     * @see #GET_META_DATA
      */
     public abstract List<PermissionInfo> queryPermissionsByGroup(String group,
             @PermissionInfoFlags int flags) throws NameNotFoundException;
@@ -3093,17 +3052,14 @@
      * Retrieve all of the information we know about a particular group of
      * permissions.
      *
-     * @param name The fully qualified name (i.e. com.google.permission_group.APPS)
-     *         of the permission you are interested in.
-     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
-     *         retrieve any meta-data associated with the permission group.
-     *
+     * @param name The fully qualified name (i.e.
+     *            com.google.permission_group.APPS) of the permission you are
+     *            interested in.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a {@link PermissionGroupInfo} containing information
      *         about the permission.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     *
-     * @see #GET_META_DATA
      */
     public abstract PermissionGroupInfo getPermissionGroupInfo(String name,
             @PermissionGroupInfoFlags int flags) throws NameNotFoundException;
@@ -3111,13 +3067,9 @@
     /**
      * Retrieve all of the known permission groups in the system.
      *
-     * @param flags Additional option flags.  Use {@link #GET_META_DATA} to
-     *         retrieve any meta-data associated with the permission group.
-     *
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a list of {@link PermissionGroupInfo} containing
      *         information about all of the known permission groups.
-     *
-     * @see #GET_META_DATA
      */
     public abstract List<PermissionGroupInfo> getAllPermissionGroups(
             @PermissionGroupInfoFlags int flags);
@@ -3127,27 +3079,17 @@
      * package/application.
      *
      * @param packageName The full name (i.e. com.google.apps.contacts) of an
-     *         application.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *         {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
+     *            application.
+     * @param flags Additional option flags to modify the data returned.
      * @return An {@link ApplicationInfo} containing information about the
-     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if the
-     *         package is not found in the list of installed applications, the
-     *         application information is retrieved from the list of uninstalled
-     *         applications (which includes installed applications as well as
-     *         applications with data directory i.e. applications which had been
-     *         deleted with {@code DONT_DELETE_DATA} flag set).
+     *         package. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set and if
+     *         the package is not found in the list of installed applications,
+     *         the application information is retrieved from the list of
+     *         uninstalled applications (which includes installed applications
+     *         as well as applications with data directory i.e. applications
+     *         which had been deleted with {@code DONT_DELETE_DATA} flag set).
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     *
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ApplicationInfo getApplicationInfo(String packageName,
             @ApplicationInfoFlags int flags) throws NameNotFoundException;
@@ -3163,30 +3105,11 @@
      * @param component The full component name (i.e.
      *            com.google.apps.contacts/com.google.apps.contacts.
      *            ContactsList) of an Activity class.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return An {@link ActivityInfo} containing information about the
      *         activity.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ActivityInfo getActivityInfo(ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
@@ -3198,30 +3121,11 @@
      * @param component The full component name (i.e.
      *            com.google.apps.calendar/com.google.apps.calendar.
      *            CalendarAlarm) of a Receiver class.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return An {@link ActivityInfo} containing information about the
      *         receiver.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ActivityInfo getReceiverInfo(ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
@@ -3232,30 +3136,11 @@
      * @param component The full component name (i.e.
      *            com.google.apps.media/com.google.apps.media.
      *            BackgroundPlayback) of a Service class.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return A {@link ServiceInfo} object containing information about the
      *         service.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ServiceInfo getServiceInfo(ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
@@ -3267,168 +3152,63 @@
      * @param component The full component name (i.e.
      *            com.google.providers.media/com.google.providers.media.
      *            MediaProvider) of a ContentProvider class.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return A {@link ProviderInfo} object containing information about the
      *         provider.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ProviderInfo getProviderInfo(ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
 
     /**
-     * Return a List of all packages that are installed
-     * on the device.
+     * Return a List of all packages that are installed on the device.
      *
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
+     * @param flags Additional option flags to modify the data returned.
      * @return A List of PackageInfo objects, one for each installed package,
-     *         containing information about the package.  In the unlikely case
+     *         containing information about the package. In the unlikely case
      *         there are no installed packages, an empty list is returned. If
      *         flag {@code MATCH_UNINSTALLED_PACKAGES} is set, the package
      *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
-     *
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<PackageInfo> getInstalledPackages(@PackageInfoFlags int flags);
 
     /**
-     * Return a List of all installed packages that are currently
-     * holding any of the given permissions.
+     * Return a List of all installed packages that are currently holding any of
+     * the given permissions.
      *
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
+     * @param flags Additional option flags to modify the data returned.
      * @return A List of PackageInfo objects, one for each installed package
      *         that holds any of the permissions that were provided, containing
      *         information about the package. If no installed packages hold any
      *         of the permissions, an empty list is returned. If flag
-     *         {@code MATCH_UNINSTALLED_PACKAGES} is set, the package information
-     *         is retrieved from the list of uninstalled applications (which
-     *         includes installed applications as well as applications with data
-     *         directory i.e. applications which had been deleted with
-     *         {@code DONT_DELETE_DATA} flag set).
-     *
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
+     *         {@code MATCH_UNINSTALLED_PACKAGES} is set, the package
+     *         information is retrieved from the list of uninstalled
+     *         applications (which includes installed applications as well as
+     *         applications with data directory i.e. applications which had been
+     *         deleted with {@code DONT_DELETE_DATA} flag set).
      */
     public abstract List<PackageInfo> getPackagesHoldingPermissions(
             String[] permissions, @PackageInfoFlags int flags);
 
     /**
-     * Return a List of all packages that are installed on the device, for a specific user.
-     * Requesting a list of installed packages for another user
+     * Return a List of all packages that are installed on the device, for a
+     * specific user. Requesting a list of installed packages for another user
      * will require the permission INTERACT_ACROSS_USERS_FULL.
      *
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
+     * @param flags Additional option flags to modify the data returned.
      * @param userId The user for whom the installed packages are to be listed
-     *
      * @return A List of PackageInfo objects, one for each installed package,
-     *         containing information about the package.  In the unlikely case
+     *         containing information about the package. In the unlikely case
      *         there are no installed packages, an empty list is returned. If
      *         flag {@code MATCH_UNINSTALLED_PACKAGES} is set, the package
      *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
-     *
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
-     *
      * @hide
      */
     @SystemApi
@@ -3450,7 +3230,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
@@ -3541,12 +3321,14 @@
      * @hide
      */
     @SystemApi
-    @IntDef({FLAG_PERMISSION_USER_SET,
+    @IntDef(prefix = { "FLAG_PERMISSION_" }, value = {
+            FLAG_PERMISSION_USER_SET,
             FLAG_PERMISSION_USER_FIXED,
             FLAG_PERMISSION_POLICY_FIXED,
             FLAG_PERMISSION_REVOKE_ON_UPGRADE,
             FLAG_PERMISSION_SYSTEM_FIXED,
-            FLAG_PERMISSION_GRANTED_BY_DEFAULT})
+            FLAG_PERMISSION_GRANTED_BY_DEFAULT
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PermissionFlags {}
 
@@ -3627,7 +3409,7 @@
      */
     @SystemApi
     public abstract void updatePermissionFlags(String permissionName,
-            String packageName, @PermissionFlags int flagMask, int flagValues,
+            String packageName, @PermissionFlags int flagMask, @PermissionFlags int flagValues,
             @NonNull UserHandle user);
 
     /**
@@ -3678,12 +3460,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
@@ -3701,12 +3480,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
@@ -3755,67 +3531,46 @@
     /**
      * Return a List of all application packages that are installed on the
      * device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
-     * applications including those deleted with {@code DONT_DELETE_DATA} (partially
-     * installed apps with data directory) will be returned.
+     * applications including those deleted with {@code DONT_DELETE_DATA}
+     * (partially installed apps with data directory) will be returned.
      *
-     * @param flags Additional option flags. Use any combination of
-     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS}
-     * {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
-     * to modify the data returned.
-     *
-     * @return A List of ApplicationInfo objects, one for each installed application.
-     *         In the unlikely case there are no installed packages, an empty list
-     *         is returned. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set, the
-     *         application information is retrieved from the list of uninstalled
+     * @param flags Additional option flags to modify the data returned.
+     * @return A List of ApplicationInfo objects, one for each installed
+     *         application. In the unlikely case there are no installed
+     *         packages, an empty list is returned. If flag
+     *         {@code MATCH_UNINSTALLED_PACKAGES} is set, the application
+     *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
-     *
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ApplicationInfo> getInstalledApplications(@ApplicationInfoFlags int flags);
 
     /**
-     * Return a List of all application packages that are installed on the device, for a specific
-     * user. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all applications including
-     * those deleted with {@code DONT_DELETE_DATA} (partially installed apps with data directory)
+     * Return a List of all application packages that are installed on the
+     * device, for a specific user. If flag GET_UNINSTALLED_PACKAGES has been
+     * set, a list of all applications including those deleted with
+     * {@code DONT_DELETE_DATA} (partially installed apps with data directory)
      * will be returned.
      *
-     * @param flags Additional option flags. Use any combination of
-     * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     * {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS}
-     * {@link #MATCH_SYSTEM_ONLY}, {@link #MATCH_UNINSTALLED_PACKAGES}
-     * to modify the data returned.
-     * @param userId The user for whom the installed applications are to be listed
-     *
-     * @return A List of ApplicationInfo objects, one for each installed application.
-     *         In the unlikely case there are no installed packages, an empty list
-     *         is returned. If flag {@code MATCH_UNINSTALLED_PACKAGES} is set, the
-     *         application information is retrieved from the list of uninstalled
+     * @param flags Additional option flags to modify the data returned.
+     * @param userId The user for whom the installed applications are to be
+     *            listed
+     * @return A List of ApplicationInfo objects, one for each installed
+     *         application. In the unlikely case there are no installed
+     *         packages, an empty list is returned. If flag
+     *         {@code MATCH_UNINSTALLED_PACKAGES} is set, the application
+     *         information is retrieved from the list of uninstalled
      *         applications (which includes installed applications as well as
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @hide
-     *
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ApplicationInfo> getInstalledApplicationsAsUser(
             @ApplicationInfoFlags int flags, @UserIdInt int userId);
 
     /**
-     * Gets the instant applications the user recently used. Requires
-     * holding "android.permission.ACCESS_INSTANT_APPS".
+     * Gets the instant applications the user recently used.
      *
      * @return The instant app list.
      *
@@ -4055,33 +3810,15 @@
      *
      * @param intent An intent containing all of the desired specification
      *            (action, data, type, category, and/or component).
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned. The most important is {@link #MATCH_DEFAULT_ONLY},
-     *            to limit the resolution to only those activities that support
-     *            the {@link android.content.Intent#CATEGORY_DEFAULT}.
+     * @param flags Additional option flags to modify the data returned. The
+     *            most important is {@link #MATCH_DEFAULT_ONLY}, to limit the
+     *            resolution to only those activities that support the
+     *            {@link android.content.Intent#CATEGORY_DEFAULT}.
      * @return Returns a ResolveInfo object containing the final activity intent
      *         that was determined to be the best action. Returns null if no
      *         matching activity was found. If multiple matching activities are
      *         found and there is no default set, returns a ResolveInfo object
      *         containing something else, such as the activity resolver.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ResolveInfo resolveActivity(Intent intent, @ResolveInfoFlags int flags);
 
@@ -4101,34 +3838,16 @@
      *
      * @param intent An intent containing all of the desired specification
      *            (action, data, type, category, and/or component).
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned. The most important is {@link #MATCH_DEFAULT_ONLY},
-     *            to limit the resolution to only those activities that support
-     *            the {@link android.content.Intent#CATEGORY_DEFAULT}.
+     * @param flags Additional option flags to modify the data returned. The
+     *            most important is {@link #MATCH_DEFAULT_ONLY}, to limit the
+     *            resolution to only those activities that support the
+     *            {@link android.content.Intent#CATEGORY_DEFAULT}.
      * @param userId The user id.
      * @return Returns a ResolveInfo object containing the final activity intent
      *         that was determined to be the best action. Returns null if no
      *         matching activity was found. If multiple matching activities are
      *         found and there is no default set, returns a ResolveInfo object
      *         containing something else, such as the activity resolver.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     public abstract ResolveInfo resolveActivityAsUser(Intent intent, @ResolveInfoFlags int flags,
@@ -4138,34 +3857,16 @@
      * Retrieve all activities that can be performed for the given intent.
      *
      * @param intent The desired intent as per resolveActivity().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned. The most important is {@link #MATCH_DEFAULT_ONLY},
-     *            to limit the resolution to only those activities that support
-     *            the {@link android.content.Intent#CATEGORY_DEFAULT}. Or, set
+     * @param flags Additional option flags to modify the data returned. The
+     *            most important is {@link #MATCH_DEFAULT_ONLY}, to limit the
+     *            resolution to only those activities that support the
+     *            {@link android.content.Intent#CATEGORY_DEFAULT}. Or, set
      *            {@link #MATCH_ALL} to prevent any filtering of the results.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching activity, ordered from best to worst. In other
      *         words, the first item is what would be returned by
      *         {@link #resolveActivity}. If there are no matching activities, an
      *         empty list is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
             @ResolveInfoFlags int flags);
@@ -4175,34 +3876,16 @@
      * specific user.
      *
      * @param intent The desired intent as per resolveActivity().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned. The most important is {@link #MATCH_DEFAULT_ONLY},
-     *            to limit the resolution to only those activities that support
-     *            the {@link android.content.Intent#CATEGORY_DEFAULT}. Or, set
+     * @param flags Additional option flags to modify the data returned. The
+     *            most important is {@link #MATCH_DEFAULT_ONLY}, to limit the
+     *            resolution to only those activities that support the
+     *            {@link android.content.Intent#CATEGORY_DEFAULT}. Or, set
      *            {@link #MATCH_ALL} to prevent any filtering of the results.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching activity, ordered from best to worst. In other
      *         words, the first item is what would be returned by
      *         {@link #resolveActivity}. If there are no matching activities, an
      *         empty list is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
@@ -4222,65 +3905,28 @@
      * @param specifics An array of Intents that should be resolved to the first
      *            specific results. Can be null.
      * @param intent The desired intent as per resolveActivity().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned. The most important is {@link #MATCH_DEFAULT_ONLY},
-     *            to limit the resolution to only those activities that support
-     *            the {@link android.content.Intent#CATEGORY_DEFAULT}.
+     * @param flags Additional option flags to modify the data returned. The
+     *            most important is {@link #MATCH_DEFAULT_ONLY}, to limit the
+     *            resolution to only those activities that support the
+     *            {@link android.content.Intent#CATEGORY_DEFAULT}.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching activity. The list is ordered first by all of the
      *         intents resolved in <var>specifics</var> and then any additional
      *         activities that can handle <var>intent</var> but did not get
      *         included by one of the <var>specifics</var> intents. If there are
      *         no matching activities, an empty list is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
-    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.
      *
      * @param intent The desired intent as per resolveActivity().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching receiver, ordered from best to worst. If there are
      *         no matching receivers, an empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent,
             @ResolveInfoFlags int flags);
@@ -4290,30 +3936,11 @@
      * for a specific user.
      *
      * @param intent The desired intent as per resolveActivity().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @param userHandle UserHandle of the user being queried.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching receiver, ordered from best to worst. If there are
      *         no matching receivers, an empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     @SystemApi
@@ -4348,29 +3975,10 @@
      *
      * @param intent An intent containing all of the desired specification
      *            (action, data, type, category, and/or component).
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a ResolveInfo object containing the final service intent
      *         that was determined to be the best action. Returns null if no
      *         matching service was found.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ResolveInfo resolveService(Intent intent, @ResolveInfoFlags int flags);
 
@@ -4378,31 +3986,12 @@
      * Retrieve all services that can match the given intent.
      *
      * @param intent The desired intent as per resolveService().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching service, ordered from best to worst. In other
      *         words, the first item is what would be returned by
      *         {@link #resolveService}. If there are no matching services, an
      *         empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ResolveInfo> queryIntentServices(Intent intent,
             @ResolveInfoFlags int flags);
@@ -4411,32 +4000,13 @@
      * Retrieve all services that can match the given intent for a given user.
      *
      * @param intent The desired intent as per resolveService().
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @param userId The user id.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching service, ordered from best to worst. In other
      *         words, the first item is what would be returned by
      *         {@link #resolveService}. If there are no matching services, an
      *         empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     public abstract List<ResolveInfo> queryIntentServicesAsUser(Intent intent,
@@ -4447,30 +4017,11 @@
      *
      * @param intent An intent containing all of the desired specification
      *            (action, data, type, category, and/or component).
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @param userId The user id.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching provider, ordered from best to worst. If there are
      *         no matching services, an empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     public abstract List<ResolveInfo> queryIntentContentProvidersAsUser(
@@ -4481,29 +4032,10 @@
      *
      * @param intent An intent containing all of the desired specification
      *            (action, data, type, category, and/or component).
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_RESOLVED_FILTER},
-     *            {@link #GET_SHARED_LIBRARY_FILES}, {@link #MATCH_ALL},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DEFAULT_ONLY}, {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return Returns a List of ResolveInfo objects containing one entry for
      *         each matching provider, ordered from best to worst. If there are
      *         no matching services, an empty list or null is returned.
-     * @see #GET_META_DATA
-     * @see #GET_RESOLVED_FILTER
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ResolveInfo> queryIntentContentProviders(Intent intent,
             @ResolveInfoFlags int flags);
@@ -4512,28 +4044,9 @@
      * Find a single content provider by its base path name.
      *
      * @param name The name of the provider to find.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return A {@link ProviderInfo} object containing information about the
      *         provider. If a provider was not found, returns null.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract ProviderInfo resolveContentProvider(String name,
             @ComponentInfoFlags int flags);
@@ -4542,29 +4055,10 @@
      * Find a single content provider by its base path name.
      *
      * @param name The name of the provider to find.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @param userId The user id.
      * @return A {@link ProviderInfo} object containing information about the
      *         provider. If a provider was not found, returns null.
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      * @hide
      */
     public abstract ProviderInfo resolveContentProviderAsUser(String name,
@@ -4581,30 +4075,11 @@
      *            content providers are returned.
      * @param uid If <var>processName</var> is non-null, this is the required
      *            uid owning the requested content providers.
-     * @param flags Additional option flags. Use any combination of
-     *            {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
-     *            {@link #MATCH_ALL}, {@link #MATCH_DEFAULT_ONLY},
-     *            {@link #MATCH_DISABLED_COMPONENTS},
-     *            {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *            {@link #MATCH_DIRECT_BOOT_AWARE},
-     *            {@link #MATCH_DIRECT_BOOT_UNAWARE}, {@link #MATCH_SYSTEM_ONLY}
-     *            or {@link #MATCH_UNINSTALLED_PACKAGES} to modify the data
-     *            returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return A list of {@link ProviderInfo} objects containing one entry for
      *         each provider either matching <var>processName</var> or, if
      *         <var>processName</var> is null, all known content providers.
      *         <em>If there are no matching providers, null is returned.</em>
-     * @see #GET_META_DATA
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #MATCH_ALL
-     * @see #MATCH_DEBUG_TRIAGED_MISSING
-     * @see #MATCH_DEFAULT_ONLY
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_DIRECT_BOOT_AWARE
-     * @see #MATCH_DIRECT_BOOT_UNAWARE
-     * @see #MATCH_SYSTEM_ONLY
-     * @see #MATCH_UNINSTALLED_PACKAGES
      */
     public abstract List<ProviderInfo> queryContentProviders(
             String processName, int uid, @ComponentInfoFlags int flags);
@@ -4635,39 +4110,28 @@
      * instrumentation class.
      *
      * @param className The full name (i.e.
-     *                  com.google.apps.contacts.InstrumentList) of an
-     *                  Instrumentation class.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_META_DATA}
-     *         to modify the data returned.
-     *
-     * @return An {@link InstrumentationInfo} object containing information about the
-     *         instrumentation.
+     *            com.google.apps.contacts.InstrumentList) of an Instrumentation
+     *            class.
+     * @param flags Additional option flags to modify the data returned.
+     * @return An {@link InstrumentationInfo} object containing information
+     *         about the instrumentation.
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
-     *
-     * @see #GET_META_DATA
      */
     public abstract InstrumentationInfo getInstrumentationInfo(ComponentName className,
             @InstrumentationInfoFlags int flags) throws NameNotFoundException;
 
     /**
-     * Retrieve information about available instrumentation code.  May be used
-     * to retrieve either all instrumentation code, or only the code targeting
-     * a particular package.
+     * Retrieve information about available instrumentation code. May be used to
+     * retrieve either all instrumentation code, or only the code targeting a
+     * particular package.
      *
      * @param targetPackage If null, all instrumentation is returned; only the
-     *                      instrumentation targeting this package name is
-     *                      returned.
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_META_DATA}
-     *         to modify the data returned.
-     *
+     *            instrumentation targeting this package name is returned.
+     * @param flags Additional option flags to modify the data returned.
      * @return A list of {@link InstrumentationInfo} objects containing one
      *         entry for each matching instrumentation. If there are no
      *         instrumentation available, returns an empty list.
-     *
-     * @see #GET_META_DATA
      */
     public abstract List<InstrumentationInfo> queryInstrumentation(String targetPackage,
             @InstrumentationInfoFlags int flags);
@@ -5091,43 +4555,13 @@
             @UserIdInt int userId) throws NameNotFoundException;
 
     /**
-     * Retrieve overall information about an application package defined
-     * in a package archive file
+     * Retrieve overall information about an application package defined in a
+     * package archive file
      *
      * @param archiveFilePath The path to the archive file
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
-     * @return A PackageInfo object containing information about the
-     *         package archive. If the package could not be parsed,
-     *         returns null.
-     *
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
-     *
+     * @param flags Additional option flags to modify the data returned.
+     * @return A PackageInfo object containing information about the package
+     *         archive. If the package could not be parsed, returns null.
      */
     public PackageInfo getPackageArchiveInfo(String archiveFilePath, @PackageInfoFlags int flags) {
         final PackageParser parser = new PackageParser();
@@ -5615,41 +5049,13 @@
     public abstract void removePackageFromPreferred(String packageName);
 
     /**
-     * Retrieve the list of all currently configured preferred packages.  The
-     * first package on the list is the most preferred, the last is the
-     * least preferred.
+     * Retrieve the list of all currently configured preferred packages. The
+     * first package on the list is the most preferred, the last is the least
+     * preferred.
      *
-     * @param flags Additional option flags. Use any combination of
-     *         {@link #GET_ACTIVITIES}, {@link #GET_CONFIGURATIONS},
-     *         {@link #GET_GIDS}, {@link #GET_INSTRUMENTATION},
-     *         {@link #GET_INTENT_FILTERS}, {@link #GET_META_DATA},
-     *         {@link #GET_PERMISSIONS}, {@link #GET_PROVIDERS},
-     *         {@link #GET_RECEIVERS}, {@link #GET_SERVICES},
-     *         {@link #GET_SHARED_LIBRARY_FILES}, {@link #GET_SIGNATURES},
-     *         {@link #GET_URI_PERMISSION_PATTERNS}, {@link #GET_UNINSTALLED_PACKAGES},
-     *         {@link #MATCH_DISABLED_COMPONENTS}, {@link #MATCH_DISABLED_UNTIL_USED_COMPONENTS},
-     *         {@link #MATCH_UNINSTALLED_PACKAGES}
-     *         to modify the data returned.
-     *
-     * @return A List of PackageInfo objects, one for each preferred application,
-     *         in order of preference.
-     *
-     * @see #GET_ACTIVITIES
-     * @see #GET_CONFIGURATIONS
-     * @see #GET_GIDS
-     * @see #GET_INSTRUMENTATION
-     * @see #GET_INTENT_FILTERS
-     * @see #GET_META_DATA
-     * @see #GET_PERMISSIONS
-     * @see #GET_PROVIDERS
-     * @see #GET_RECEIVERS
-     * @see #GET_SERVICES
-     * @see #GET_SHARED_LIBRARY_FILES
-     * @see #GET_SIGNATURES
-     * @see #GET_URI_PERMISSION_PATTERNS
-     * @see #MATCH_DISABLED_COMPONENTS
-     * @see #MATCH_DISABLED_UNTIL_USED_COMPONENTS
-     * @see #MATCH_UNINSTALLED_PACKAGES
+     * @param flags Additional option flags to modify the data returned.
+     * @return A List of PackageInfo objects, one for each preferred
+     *         application, in order of preference.
      */
     public abstract List<PackageInfo> getPreferredPackages(@PackageInfoFlags int flags);
 
@@ -5765,18 +5171,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,
@@ -5786,14 +5185,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
@@ -5803,18 +5198,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
@@ -5824,15 +5212,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
@@ -5961,16 +5344,7 @@
      * determined by {@link #getInstallerPackageName(String)}.
      *
      * @param packageName the package to change the category hint for.
-     * @param categoryHint the category hint to set; one of
-     *            {@link ApplicationInfo#CATEGORY_AUDIO},
-     *            {@link ApplicationInfo#CATEGORY_GAME},
-     *            {@link ApplicationInfo#CATEGORY_IMAGE},
-     *            {@link ApplicationInfo#CATEGORY_MAPS},
-     *            {@link ApplicationInfo#CATEGORY_NEWS},
-     *            {@link ApplicationInfo#CATEGORY_PRODUCTIVITY},
-     *            {@link ApplicationInfo#CATEGORY_SOCIAL},
-     *            {@link ApplicationInfo#CATEGORY_UNDEFINED}, or
-     *            {@link ApplicationInfo#CATEGORY_VIDEO}.
+     * @param categoryHint the category hint to set.
      */
     public abstract void setApplicationCategoryHint(@NonNull String packageName,
             @ApplicationInfo.Category int categoryHint);
@@ -6265,23 +5639,14 @@
     }
 
     /**
-     * Return the install reason that was recorded when a package was first installed for a specific
-     * user. Requesting the install reason for another user will require the permission
-     * INTERACT_ACROSS_USERS_FULL.
+     * Return the install reason that was recorded when a package was first
+     * installed for a specific user. Requesting the install reason for another
+     * user will require the permission INTERACT_ACROSS_USERS_FULL.
      *
      * @param packageName The package for which to retrieve the install reason
      * @param user The user for whom to retrieve the install reason
-     *
-     * @return The install reason, currently one of {@code INSTALL_REASON_UNKNOWN} and
-     *         {@code INSTALL_REASON_POLICY}. If the package is not installed for the given user,
-     *         {@code INSTALL_REASON_UNKNOWN} is returned.
-     *
-     * @see #INSTALL_REASON_UNKNOWN
-     * @see #INSTALL_REASON_POLICY
-     * @see #INSTALL_REASON_DEVICE_RESTORE
-     * @see #INSTALL_REASON_DEVICE_SETUP
-     * @see #INSTALL_REASON_USER
-     *
+     * @return The install reason. If the package is not installed for the given
+     *         user, {@code INSTALL_REASON_UNKNOWN} is returned.
      * @hide
      */
     @TestApi
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1f78bff..e4db0f0 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;
@@ -4266,7 +4271,7 @@
         boolean visibleToEphemeral =
                 sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false);
         if (visibleToEphemeral) {
-            a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
             owner.visibleToInstantApps = true;
         }
 
@@ -4308,9 +4313,17 @@
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
+                final int visibility = visibleToEphemeral
+                        ? IntentFilter.VISIBILITY_EXPLICIT
+                        : !receiver && isImplicitlyExposedIntent(intent)
+                                ? IntentFilter.VISIBILITY_IMPLICIT
+                                : IntentFilter.VISIBILITY_NONE;
+                intent.setVisibilityToInstantApp(visibility);
                 if (intent.isVisibleToInstantApp()) {
-                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+                }
+                if (intent.isImplicitlyVisibleToInstantApp()) {
+                    a.info.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
                 }
                 if (LOG_UNSAFE_BROADCASTS && receiver
                         && (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O)) {
@@ -4341,9 +4354,17 @@
                     owner.preferredActivityFilters.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
+                final int visibility = visibleToEphemeral
+                        ? IntentFilter.VISIBILITY_EXPLICIT
+                        : !receiver && isImplicitlyExposedIntent(intent)
+                                ? IntentFilter.VISIBILITY_IMPLICIT
+                                : IntentFilter.VISIBILITY_NONE;
+                intent.setVisibilityToInstantApp(visibility);
                 if (intent.isVisibleToInstantApp()) {
-                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+                }
+                if (intent.isImplicitlyVisibleToInstantApp()) {
+                    a.info.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
                 }
             } else if (parser.getName().equals("meta-data")) {
                 if ((a.metaData = parseMetaData(res, parser, a.metaData,
@@ -4353,16 +4374,18 @@
                 // we don't have an attribute [or it's false], but, we have meta-data
                 if (!visibleToEphemeral && a.metaData.getBoolean(META_DATA_INSTANT_APPS)) {
                     visibleToEphemeral = true; // set in case there are more intent filters
-                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+                    a.info.flags &= ~ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = a.intents.size() - 1; i >= 0; --i) {
-                        a.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
+                        a.intents.get(i)
+                                .setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                     }
                     if (owner.preferredActivityFilters != null) {
                         for (int i = owner.preferredActivityFilters.size() - 1; i >= 0; --i) {
                             owner.preferredActivityFilters.get(i)
-                                    .setVisibleToInstantApp(true /*visibleToInstantApp*/);
+                                    .setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                         }
                     }
                 }
@@ -4640,7 +4663,7 @@
 
         // TODO add visibleToInstantApps attribute to activity alias
         final boolean visibleToEphemeral =
-                ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0);
+                ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0);
 
         sa.recycle();
 
@@ -4668,13 +4691,20 @@
                             + mArchiveSourcePath + " "
                             + parser.getPositionDescription());
                 } else {
-                    intent.setVisibleToInstantApp(
-                            visibleToEphemeral || isImplicitlyExposedIntent(intent));
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
+                final int visibility = visibleToEphemeral
+                        ? IntentFilter.VISIBILITY_EXPLICIT
+                        : isImplicitlyExposedIntent(intent)
+                                ? IntentFilter.VISIBILITY_IMPLICIT
+                                : IntentFilter.VISIBILITY_NONE;
+                intent.setVisibilityToInstantApp(visibility);
                 if (intent.isVisibleToInstantApp()) {
-                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+                }
+                if (intent.isImplicitlyVisibleToInstantApp()) {
+                    a.info.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
                 }
             } else if (parser.getName().equals("meta-data")) {
                 if ((a.metaData=parseMetaData(res, parser, a.metaData,
@@ -4817,7 +4847,7 @@
         final boolean visibleToEphemeral =
                 sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false);
         if (visibleToEphemeral) {
-            p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
             owner.visibleToInstantApps = true;
         }
 
@@ -4869,12 +4899,11 @@
                         intent, outError)) {
                     return false;
                 }
-                outInfo.intents.add(intent);
-                // adjust provider flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
-                if (intent.isVisibleToInstantApp()) {
-                    outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                if (visibleToEphemeral) {
+                    intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
+                    outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                 }
+                outInfo.intents.add(intent);
 
             } else if (parser.getName().equals("meta-data")) {
                 if ((outInfo.metaData=parseMetaData(res, parser,
@@ -4884,11 +4913,12 @@
                 // we don't have an attribute [or it's false], but, we have meta-data
                 if (!visibleToEphemeral && outInfo.metaData.getBoolean(META_DATA_INSTANT_APPS)) {
                     visibleToEphemeral = true; // set in case there are more intent filters
-                    outInfo.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = outInfo.intents.size() - 1; i >= 0; --i) {
-                        outInfo.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
+                        outInfo.intents.get(i)
+                                .setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                     }
                 }
 
@@ -5144,7 +5174,7 @@
         boolean visibleToEphemeral =
                 sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false);
         if (visibleToEphemeral) {
-            s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+            s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
             owner.visibleToInstantApps = true;
         }
 
@@ -5175,10 +5205,9 @@
                         intent, outError)) {
                     return null;
                 }
-                // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
-                if (intent.isVisibleToInstantApp()) {
-                    s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                if (visibleToEphemeral) {
+                    intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
+                    s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                 }
                 s.intents.add(intent);
             } else if (parser.getName().equals("meta-data")) {
@@ -5189,11 +5218,12 @@
                 // we don't have an attribute [or it's false], but, we have meta-data
                 if (!visibleToEphemeral && s.metaData.getBoolean(META_DATA_INSTANT_APPS)) {
                     visibleToEphemeral = true; // set in case there are more intent filters
-                    s.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+                    s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = s.intents.size() - 1; i >= 0; --i) {
-                        s.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
+                        s.intents.get(i)
+                                .setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
                     }
                 }
             } else {
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
index 8c21563..91dc06e 100644
--- a/core/java/android/content/pm/ProviderInfo.java
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -79,7 +79,7 @@
      * Bit in {@link #flags} indicating if the provider is visible to ephemeral applications.
      * @hide
      */
-    public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+    public static final int FLAG_VISIBLE_TO_INSTANT_APP = 0x100000;
 
     /**
      * Bit in {@link #flags}: If set, a single instance of the provider will
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index f0766be..c683ea5 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -59,7 +59,7 @@
      * Bit in {@link #flags} indicating if the service is visible to ephemeral applications.
      * @hide
      */
-    public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+    public static final int FLAG_VISIBLE_TO_INSTANT_APP = 0x100000;
 
     /**
      * Bit in {@link #flags}: If set, a single instance of the service will
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 408bee8..b559604 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -815,14 +815,7 @@
      */
     public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
             throws NotFoundException {
-        final TypedValue value = obtainTempTypedValue();
-        try {
-            final ResourcesImpl impl = mResourcesImpl;
-            impl.getValue(id, value, true);
-            return impl.loadDrawable(this, value, id, theme, true);
-        } finally {
-            releaseTempTypedValue(value);
-        }
+        return getDrawableForDensity(id, 0, theme);
     }
 
     /**
@@ -844,7 +837,9 @@
      *            This integer encodes the package, type, and resource entry.
      *            The value 0 is an invalid identifier.
      * @param density the desired screen density indicated by the resource as
-     *            found in {@link DisplayMetrics}.
+     *            found in {@link DisplayMetrics}. A value of 0 means to use the
+     *            density returned from {@link #getConfiguration()}.
+     *            This is equivalent to calling {@link #getDrawable(int)}.
      * @return Drawable An object that can be used to draw this resource.
      * @throws NotFoundException Throws NotFoundException if the given ID does
      *             not exist.
@@ -865,7 +860,9 @@
      *            This integer encodes the package, type, and resource entry.
      *            The value 0 is an invalid identifier.
      * @param density The desired screen density indicated by the resource as
-     *            found in {@link DisplayMetrics}.
+     *            found in {@link DisplayMetrics}. A value of 0 means to use the
+     *            density returned from {@link #getConfiguration()}.
+     *            This is equivalent to calling {@link #getDrawable(int, Theme)}.
      * @param theme The theme used to style the drawable attributes, may be {@code null}.
      * @return Drawable An object that can be used to draw this resource.
      * @throws NotFoundException Throws NotFoundException if the given ID does
@@ -876,37 +873,16 @@
         try {
             final ResourcesImpl impl = mResourcesImpl;
             impl.getValueForDensity(id, density, value, true);
-
-            // If the drawable's XML lives in our current density qualifier,
-            // it's okay to use a scaled version from the cache. Otherwise, we
-            // need to actually load the drawable from XML.
-            final DisplayMetrics metrics = impl.getDisplayMetrics();
-            final boolean useCache = value.density == metrics.densityDpi;
-
-            /*
-             * Pretend the requested density is actually the display density. If
-             * the drawable returned is not the requested density, then force it
-             * to be scaled later by dividing its density by the ratio of
-             * requested density to actual device density. Drawables that have
-             * undefined density or no density don't need to be handled here.
-             */
-            if (value.density > 0 && value.density != TypedValue.DENSITY_NONE) {
-                if (value.density == density) {
-                    value.density = metrics.densityDpi;
-                } else {
-                    value.density = (value.density * metrics.densityDpi) / density;
-                }
-            }
-            return impl.loadDrawable(this, value, id, theme, useCache);
+            return impl.loadDrawable(this, value, id, density, theme);
         } finally {
             releaseTempTypedValue(value);
         }
     }
 
     @NonNull
-    Drawable loadDrawable(@NonNull TypedValue value, int id, @Nullable Theme theme)
+    Drawable loadDrawable(@NonNull TypedValue value, int id, int density, @Nullable Theme theme)
             throws NotFoundException {
-        return mResourcesImpl.loadDrawable(this, value, id, theme, true);
+        return mResourcesImpl.loadDrawable(this, value, id, density, theme);
     }
 
     /**
@@ -1221,8 +1197,7 @@
      * used to open drawable, sound, and raw resources; it will fail on string
      * and color resources.
      * 
-     * @param id The resource identifier to open, as generated by the appt
-     *           tool.
+     * @param id The resource identifier to open, as generated by the aapt tool.
      * 
      * @return InputStream Access to the resource data.
      *
@@ -1278,7 +1253,7 @@
      * used to open drawable, sound, and raw resources; it will fail on string
      * and color resources.
      *
-     * @param id The resource identifier to open, as generated by the appt tool.
+     * @param id The resource identifier to open, as generated by the aapt tool.
      * @param value The TypedValue object to hold the resource information.
      *
      * @return InputStream Access to the resource data.
@@ -1300,8 +1275,7 @@
      * as uncompressed data, which typically includes things like mp3 files
      * and png images.
      * 
-     * @param id The resource identifier to open, as generated by the appt
-     *           tool.
+     * @param id The resource identifier to open, as generated by the aapt tool.
      * 
      * @return AssetFileDescriptor A new file descriptor you can use to read
      * the resource.  This includes the file descriptor itself, as well as the
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index f9acab9..02ddc89 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -523,8 +523,27 @@
     }
 
     @Nullable
-    Drawable loadDrawable(Resources wrapper, TypedValue value, int id, Resources.Theme theme,
-            boolean useCache) throws NotFoundException {
+    Drawable loadDrawable(@NonNull Resources wrapper, @NonNull TypedValue value, int id,
+            int density, @Nullable Resources.Theme theme)
+            throws NotFoundException {
+        // If the drawable's XML lives in our current density qualifier,
+        // it's okay to use a scaled version from the cache. Otherwise, we
+        // need to actually load the drawable from XML.
+        final boolean useCache = density == 0 || value.density == mMetrics.densityDpi;
+
+        // Pretend the requested density is actually the display density. If
+        // the drawable returned is not the requested density, then force it
+        // to be scaled later by dividing its density by the ratio of
+        // requested density to actual device density. Drawables that have
+        // undefined density or no density don't need to be handled here.
+        if (density > 0 && value.density > 0 && value.density != TypedValue.DENSITY_NONE) {
+            if (value.density == density) {
+                value.density = mMetrics.densityDpi;
+            } else {
+                value.density = (value.density * mMetrics.densityDpi) / density;
+            }
+        }
+
         try {
             if (TRACE_FOR_PRELOAD) {
                 // Log only framework resources
@@ -576,7 +595,7 @@
             } else if (isColorDrawable) {
                 dr = new ColorDrawable(value.data);
             } else {
-                dr = loadDrawableForCookie(wrapper, value, id, null);
+                dr = loadDrawableForCookie(wrapper, value, id, density, null);
             }
 
             // Determine if the drawable has unresolved theme attributes. If it
@@ -691,8 +710,8 @@
     /**
      * Loads a drawable from XML or resources stream.
      */
-    private Drawable loadDrawableForCookie(Resources wrapper, TypedValue value, int id,
-            Resources.Theme theme) {
+    private Drawable loadDrawableForCookie(@NonNull Resources wrapper, @NonNull TypedValue value,
+            int id, int density, @Nullable Resources.Theme theme) {
         if (value.string == null) {
             throw new NotFoundException("Resource \"" + getResourceName(id) + "\" ("
                     + Integer.toHexString(id) + ") is not a Drawable (color or path): " + value);
@@ -722,7 +741,7 @@
             if (file.endsWith(".xml")) {
                 final XmlResourceParser rp = loadXmlResourceParser(
                         file, id, value.assetCookie, "drawable");
-                dr = Drawable.createFromXml(wrapper, rp, theme);
+                dr = Drawable.createFromXmlForDensity(wrapper, rp, density, theme);
                 rp.close();
             } else {
                 final InputStream is = mAssets.openNonAsset(
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 88bb1a4..0b0f048 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -923,6 +923,15 @@
      */
     @Nullable
     public Drawable getDrawable(@StyleableRes int index) {
+        return getDrawableForDensity(index, 0);
+    }
+
+    /**
+     * Version of {@link #getDrawable(int)} that accepts an override density.
+     * @hide
+     */
+    @Nullable
+    public Drawable getDrawableForDensity(@StyleableRes int index, int density) {
         if (mRecycled) {
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
@@ -933,7 +942,13 @@
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
             }
-            return mResources.loadDrawable(value, value.resourceId, mTheme);
+
+            if (density > 0) {
+                // If the density is overridden, the value in the TypedArray will not reflect this.
+                // Do a separate lookup of the resourceId with the density override.
+                mResources.getValueForDensity(value.resourceId, density, value, true);
+            }
+            return mResources.loadDrawable(value, value.resourceId, density, mTheme);
         }
         return null;
     }
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index 7b09e26..9d217d3 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -22,6 +22,7 @@
 import android.os.Parcelable;
 
 import dalvik.annotation.optimization.FastNative;
+import dalvik.system.CloseGuard;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -37,7 +38,7 @@
  *
  * For more information, see the NDK documentation for <code>AHardwareBuffer</code>.
  */
-public final class HardwareBuffer implements Parcelable {
+public final class HardwareBuffer implements Parcelable, AutoCloseable {
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({RGBA_8888, RGBA_FP16, RGBA_1010102, RGBX_8888, RGB_888, RGB_565, BLOB})
@@ -65,6 +66,8 @@
     // Invoked on destruction
     private Runnable mCleaner;
 
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = true, value = {USAGE0_CPU_READ, USAGE0_CPU_READ_OFTEN, USAGE0_CPU_WRITE,
@@ -163,14 +166,25 @@
         NativeAllocationRegistry registry = new NativeAllocationRegistry(
                 loader, nGetNativeFinalizer(), NATIVE_HARDWARE_BUFFER_SIZE);
         mCleaner = registry.registerNativeAllocation(this, mNativeObject);
+        mCloseGuard.open("close");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            mCloseGuard.warnIfOpen();
+            close();
+        } finally {
+            super.finalize();
+        }
     }
 
     /**
      * Returns the width of this buffer in pixels.
      */
     public int getWidth() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its width "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its width "
                     + "cannot be obtained.");
         }
         return nGetWidth(mNativeObject);
@@ -180,8 +194,8 @@
      * Returns the height of this buffer in pixels.
      */
     public int getHeight() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its height "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its height "
                     + "cannot be obtained.");
         }
         return nGetHeight(mNativeObject);
@@ -193,8 +207,8 @@
      */
     @Format
     public int getFormat() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its format "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its format "
                     + "cannot be obtained.");
         }
         return nGetFormat(mNativeObject);
@@ -204,8 +218,8 @@
      * Returns the number of layers in this buffer.
      */
     public int getLayers() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its layer "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its layer "
                     + "count cannot be obtained.");
         }
         return nGetLayers(mNativeObject);
@@ -215,22 +229,36 @@
      * Returns the usage flags of the usage hints set on this buffer.
      */
     public long getUsage() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its usage "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its usage "
                     + "cannot be obtained.");
         }
         return nGetUsage(mNativeObject);
     }
 
+    /** @removed replaced by {@link #close()} */
+    @Deprecated
+    public void destroy() {
+        close();
+    }
+
+    /** @removed replaced by {@link #isClosed()} */
+    @Deprecated
+    public boolean isDestroyed() {
+        return isClosed();
+    }
+
     /**
      * Destroys this buffer immediately. Calling this method frees up any
      * underlying native resources. After calling this method, this buffer
      * must not be used in any way.
      *
-     * @see #isDestroyed()
+     * @see #isClosed()
      */
-    public void destroy() {
-        if (mNativeObject != 0) {
+    @Override
+    public void close() {
+        if (!isClosed()) {
+            mCloseGuard.close();
             mNativeObject = 0;
             mCleaner.run();
             mCleaner = null;
@@ -238,15 +266,15 @@
     }
 
     /**
-     * Indicates whether this buffer has been destroyed. A destroyed buffer
-     * cannot be used in any way: the buffer cannot be written to a parcel, etc.
+     * Indicates whether this buffer has been closed. A closed buffer cannot
+     * be used in any way: the buffer cannot be written to a parcel, etc.
      *
-     * @return True if this <code>HardwareBuffer</code> is in a destroyed state,
+     * @return True if this <code>HardwareBuffer</code> is in a closed state,
      *         false otherwise.
      *
-     * @see #destroy()
+     * @see #close()
      */
-    public boolean isDestroyed() {
+    public boolean isClosed() {
         return mNativeObject == 0;
     }
 
@@ -259,7 +287,7 @@
      * Flatten this object in to a Parcel.
      *
      * <p>Calling this method will throw an <code>IllegalStateException</code> if
-     * {@link #destroy()} has been previously called.</p>
+     * {@link #close()} has been previously called.</p>
      *
      * @param dest The Parcel in which the object should be written.
      * @param flags Additional flags about how the object should be written.
@@ -267,8 +295,8 @@
      */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and cannot be "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and cannot be "
                     + "written to a parcel.");
         }
         nWriteHardwareBufferToParcel(mNativeObject, dest);
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 10c4cb3..51506b0 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -285,17 +285,22 @@
                 }
                 // Initialize a client for data_injection.
                 if (sInjectEventQueue == null) {
-                    sInjectEventQueue = new InjectEventQueue(mMainLooper, this,
-                            mContext.getPackageName());
+                    try {
+                        sInjectEventQueue = new InjectEventQueue(
+                                mMainLooper, this, mContext.getPackageName());
+                    } catch (RuntimeException e) {
+                        Log.e(TAG, "Cannot create InjectEventQueue: " + e);
+                    }
                 }
+                return sInjectEventQueue != null;
             } else {
                 // If data injection is being disabled clean up the native resources.
                 if (sInjectEventQueue != null) {
                     sInjectEventQueue.dispose();
                     sInjectEventQueue = null;
                 }
+                return true;
             }
-            return true;
         }
     }
 
@@ -322,7 +327,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 +340,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/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index ce7894f..48b095d 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -24,6 +24,8 @@
 /**
  * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
  * RFC 4301.
+ *
+ * @hide
  */
 public final class IpSecAlgorithm implements Parcelable {
 
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 375b7ee..114e46e 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -37,6 +37,8 @@
  * <p>An IpSecManager may be obtained by calling {@link
  * android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link
  * android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE}
+ *
+ * @hide
  */
 public final class IpSecManager {
     private static final String TAG = "IpSecManager";
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 801e98c..639d1f2 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -45,6 +45,8 @@
  *
  * <p>An IpSecTransform may either represent a tunnel mode transform that operates on a wide array
  * of traffic or may represent a transport mode transform operating on a Socket or Sockets.
+ *
+ * @hide
  */
 public final class IpSecTransform implements AutoCloseable {
     private static final String TAG = "IpSecTransform";
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/Build.java b/core/java/android/os/Build.java
index 0610499..86fcfc8 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -115,8 +115,7 @@
     public static final String SERIAL = getString("no.such.thing");
 
     /**
-     * Gets the hardware serial, if available. Requires holding the {@link
-     * android.Manifest.permission#READ_PHONE_STATE} permission.
+     * Gets the hardware serial, if available.
      * @return The serial if specified.
      */
     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
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/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 1c15004..baa29b0 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -730,7 +730,7 @@
      */
     public @NonNull UUID getUuidForPath(@NonNull File path) throws IOException {
         Preconditions.checkNotNull(path);
-        final String pathString = path.getAbsolutePath();
+        final String pathString = path.getCanonicalPath();
         if (FileUtils.contains(Environment.getDataDirectory().getAbsolutePath(), pathString)) {
             return UUID_DEFAULT;
         }
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 3fa92b8..f6ad17d 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,7 +42,9 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.ResultReceiver;
+import android.util.ArraySet;
 import android.util.Log;
+import android.util.LruCache;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -63,6 +64,13 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Utility class to deal with Font ContentProviders.
@@ -103,14 +111,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
@@ -157,34 +157,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 volatile static Context sContext;  // set once in setApplicationContextForResources
 
-    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 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();
     }
 
     /**
@@ -317,90 +307,100 @@
         }
     }
 
+    private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000;
+
+    private static final long SYNC_FONT_FETCH_TIMEOUT_MS = 500;
+
     // 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;
                 }
             }
         }
     };
 
     /** @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;
-                }
+    public static Typeface getFontSync(FontRequest request) {
+        final String id = request.getIdentifier();
+        Typeface cachedTypeface = sTypefaceCache.get(id);
+        if (cachedTypeface != null) {
+            return cachedTypeface;
+        }
 
-                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;
+        // 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());
+            }
+            final Lock lock = new ReentrantLock();
+            final Condition cond = lock.newCondition();
+            final AtomicReference<Typeface> holder = new AtomicReference<>();
+            final AtomicBoolean waiting = new AtomicBoolean(true);
+            final AtomicBoolean timeout = new AtomicBoolean(false);
+
+            sHandler.post(() -> {
+                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);
                         }
-                        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);
+                        holder.set(typeface);
+                    }
+                } catch (NameNotFoundException e) {
+                    // Ignore.
+                }
+                lock.lock();
+                try {
+                    if (!timeout.get()) {
+                      waiting.set(false);
+                      cond.signal();
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            });
+            sHandler.removeCallbacks(sReplaceDispatcherThreadRunnable);
+            sHandler.postDelayed(sReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS);
+
+            long remaining = TimeUnit.MILLISECONDS.toNanos(SYNC_FONT_FETCH_TIMEOUT_MS);
+            lock.lock();
+            try {
+                if (!waiting.get()) {
+                    return holder.get();
+                }
+                for (;;) {
+                    try {
+                        remaining = cond.awaitNanos(remaining);
+                    } catch (InterruptedException e) {
+                        // do nothing.
+                    }
+                    if (!waiting.get()) {
+                        return holder.get();
+                    }
+                    if (remaining <= 0) {
+                        timeout.set(true);
+                        Log.w(TAG, "Remote font fetch timed out: " +
+                                request.getProviderAuthority() + "/" + request.getQuery());
+                        return null;
                     }
                 }
-                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);
+            } finally {
+                lock.unlock();
+            }
         }
     }
 
@@ -412,12 +412,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.
@@ -449,16 +449,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},
@@ -476,27 +474,48 @@
      * 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 caller thread.
+     *
+     * Note that the result Typeface may be cached internally and the same instance will be returned
+     * the next time you call this method with the same request. If you want to bypass this cache,
+     * use {@link #fetchFonts} and {@link #buildTypeface} instead.
+     *
      * @param context A context to be used for fetching from font provider.
      * @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.
      * @param handler A handler to be processed the font fetching.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If
+     *                           the operation is canceled, then {@link
+     *                           android.os.OperationCanceledException} will be thrown.
+     * @param callback A callback that will be triggered when results are obtained. May not be null.
      */
-    public static void requestFont(@NonNull Context context, @NonNull FontRequest request,
-            @NonNull FontRequestCallback callback, @NonNull Handler handler) {
+    public static void requestFonts(@NonNull Context context, @NonNull FontRequest request,
+            @NonNull Handler handler, @Nullable CancellationSignal cancellationSignal,
+            @NonNull FontRequestCallback callback) {
 
         final Handler callerThreadHandler = new Handler();
+        final Typeface cachedTypeface = sTypefaceCache.get(request.getIdentifier());
+        if (cachedTypeface != null) {
+            callerThreadHandler.post(() -> callback.onTypefaceRetrieved(cachedTypeface));
+            return;
+        }
+
         handler.post(() -> {
-            // TODO: Cache the result.
             FontFamilyResult result;
             try {
-                result = fetchFonts(context, null /* cancellation signal */, request);
+                result = fetchFonts(context, cancellationSignal, request);
             } catch (NameNotFoundException e) {
                 callerThreadHandler.post(() -> callback.onTypefaceRequestFailed(
                         FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND));
                 return;
             }
 
+            // Same request might be dispatched during fetchFonts. Check the cache again.
+            final Typeface anotherCachedTypeface = sTypefaceCache.get(request.getIdentifier());
+            if (anotherCachedTypeface != null) {
+                callerThreadHandler.post(() -> callback.onTypefaceRetrieved(anotherCachedTypeface));
+                return;
+            }
+
             if (result.getStatusCode() != FontFamilyResult.STATUS_OK) {
                 switch (result.getStatusCode()) {
                     case FontFamilyResult.STATUS_WRONG_CERTIFICATES:
@@ -538,7 +557,7 @@
                 }
             }
 
-            final Typeface typeface = buildTypeface(context, null /* cancellation signal */, fonts);
+            final Typeface typeface = buildTypeface(context, cancellationSignal, fonts);
             if (typeface == null) {
                 // Something went wrong during reading font files. This happens if the given font
                 // file is an unsupported font type.
@@ -547,6 +566,7 @@
                 return;
             }
 
+            sTypefaceCache.put(request.getIdentifier(), typeface);
             callerThreadHandler.post(() -> callback.onTypefaceRetrieved(typeface));
         });
     }
@@ -614,6 +634,9 @@
         }
         final Map<Uri, ByteBuffer> uriBuffer =
                 prepareFontData(context, fonts, cancellationSignal);
+        if (uriBuffer.isEmpty()) {
+            return null;
+        }
         return new Typeface.Builder(fonts, uriBuffer)
             .setFallback(fallbackFontName)
             .setWeight(weight)
@@ -641,6 +664,9 @@
         }
         final Map<Uri, ByteBuffer> uriBuffer =
                 prepareFontData(context, fonts, cancellationSignal);
+        if (uriBuffer.isEmpty()) {
+            return null;
+        }
         return new Typeface.Builder(fonts, uriBuffer).build();
     }
 
@@ -671,11 +697,17 @@
 
             ByteBuffer buffer = null;
             try (final ParcelFileDescriptor pfd =
-                    resolver.openFileDescriptor(uri, "r", cancellationSignal);
-                    final FileInputStream fis = new FileInputStream(pfd.getFileDescriptor())) {
-                final FileChannel fileChannel = fis.getChannel();
-                final long size = fileChannel.size();
-                buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
+                    resolver.openFileDescriptor(uri, "r", cancellationSignal)) {
+                if (pfd != null) {
+                    try (final FileInputStream fis =
+                            new FileInputStream(pfd.getFileDescriptor())) {
+                        final FileChannel fileChannel = fis.getChannel();
+                        final long size = fileChannel.size();
+                        buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                }
             } catch (IOException e) {
                 // ignore
             }
@@ -772,7 +804,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.
@@ -785,7 +817,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;
@@ -802,17 +833,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 f9d81da..cbd41c3 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -303,7 +303,7 @@
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_MANAGE_UNKNOWN_APP_SOURCES =
-            "android.settings.action.MANAGE_UNKNOWN_APP_SOURCES";
+            "android.settings.MANAGE_UNKNOWN_APP_SOURCES";
 
     /**
      * Activity Action: Show trusted credentials settings, opening to the user tab,
@@ -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
@@ -6993,9 +6943,8 @@
             ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+            AUTOFILL_SERVICE,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-            ACCESSIBILITY_SCRIPT_INJECTION,
-            ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
             ENABLED_ACCESSIBILITY_SERVICES,
             ENABLED_NOTIFICATION_LISTENERS,
             ENABLED_VR_LISTENERS,
@@ -8352,16 +8301,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 +8315,7 @@
          *
          * Type: long
          * @hide
+         * @deprecated to be removed
          */
         public static final String NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS =
                 "network_recommendation_request_timeout_ms";
@@ -9877,7 +9817,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..32b078f 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -34,11 +34,9 @@
 
 import com.android.internal.os.SomeArgs;
 
+import java.util.ArrayList;
 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 +48,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 +67,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 +115,15 @@
                 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) {
+                    final ArrayList<FillContext> contexts = request.getFillContexts();
+                    onFillRequest(contexts.get(contexts.size() - 1).getStructure(),
+                            request.getClientState(), request.getFlags(), cancellation,
+                            fillCallback);
+                }
                 break;
             } case MSG_ON_SAVE_REQUEST: {
                 final SomeArgs args = (SomeArgs) msg.obj;
@@ -144,7 +131,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 +164,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 +195,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,11 +219,15 @@
      *     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,
+    public void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
             int flags, @NonNull CancellationSignal cancellationSignal,
-            @NonNull FillCallback callback);
+            @NonNull FillCallback callback) {
+
+    }
 
     /**
      * Called when user requests service to save the fields of an {@link Activity}.
@@ -246,11 +240,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,10 +258,14 @@
      *        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,
-            @NonNull SaveCallback callback);
+    public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+            @NonNull SaveCallback callback) {
+
+    }
 
     /**
      * Called when the Android system disconnects from the service.
@@ -280,9 +275,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/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 7774bdd..105cd38 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -47,8 +47,13 @@
     public void onSuccess(@Nullable FillResponse response) {
         assertNotCalled();
         mCalled = true;
+
+        if (response != null) {
+            response.setRequestId(mRequestId);
+        }
+
         try {
-            mCallback.onSuccess(response, mRequestId);
+            mCallback.onSuccess(response);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java
index 2efa08c..8a28c45 100644
--- a/core/java/android/service/autofill/FillContext.java
+++ b/core/java/android/service/autofill/FillContext.java
@@ -16,6 +16,8 @@
 
 package android.service.autofill;
 
+import static android.view.autofill.Helper.DEBUG;
+
 import android.annotation.NonNull;
 import android.app.assist.AssistStructure;
 import android.os.Bundle;
@@ -71,6 +73,15 @@
     }
 
     @Override
+    public String toString() {
+        if (!DEBUG) {
+            return super.toString();
+        } else {
+            return "FillContext [mRequestId=" + mRequestId + "]";
+        }
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index aa6db4d..8ac399c 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -19,16 +19,16 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.assist.AssistStructure;
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.ArrayList;
 
 /**
  * This class represents a request to an {@link AutofillService autofill provider}
@@ -39,14 +39,15 @@
  * @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.
      */
     public static final int FLAG_MANUAL_REQUEST = 0x1;
 
     /** @hide */
+    public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE;
+
+    /** @hide */
     @IntDef(
         flag = true,
         value = {FLAG_MANUAL_REQUEST})
@@ -55,27 +56,24 @@
 
     private final int mId;
     private final @RequestFlags int mFlags;
-    private final @NonNull AssistStructure mStructure;
+    private final @NonNull ArrayList<FillContext> mContexts;
     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);
+        mContexts = new ArrayList<>();
+        parcel.readParcelableList(mContexts, null);
+
         mClientState = parcel.readBundle();
         mFlags = parcel.readInt();
     }
 
-    private FillRequest(int id, @NonNull AssistStructure structure,
+    /** @hide */
+    public FillRequest(int id, @NonNull ArrayList<FillContext> contexts,
             @Nullable Bundle clientState, @RequestFlags int flags) {
         mId = id;
         mFlags = Preconditions.checkFlagsArgument(flags, FLAG_MANUAL_REQUEST);
-        mStructure = Preconditions.checkNotNull(structure, "structure");
+        mContexts = Preconditions.checkCollectionElementsNotNull(contexts, "contexts");
         mClientState = clientState;
     }
 
@@ -96,10 +94,10 @@
     }
 
     /**
-     * @return The structure capturing the UI state.
+     * @return The contexts associated with each previous fill request.
      */
-    public @NonNull AssistStructure getStructure() {
-        return mStructure;
+    public @NonNull ArrayList<FillContext> getFillContexts() {
+        return mContexts;
     }
 
     /**
@@ -124,7 +122,7 @@
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mId);
-        parcel.writeParcelable(mStructure, flags);
+        parcel.writeParcelableList(mContexts, flags);
         parcel.writeBundle(mClientState);
         parcel.writeInt(mFlags);
     }
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 68ce0b5..5c8f3ce 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -16,6 +16,7 @@
 
 package android.service.autofill;
 
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
 import static android.view.autofill.Helper.DEBUG;
 
 import android.annotation.NonNull;
@@ -138,6 +139,7 @@
     private final @Nullable IntentSender mAuthentication;
     private final @Nullable AutofillId[] mAuthenticationIds;
     private final @Nullable AutofillId[] mIgnoredIds;
+    private int mRequestId;
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = builder.mDatasets;
@@ -147,6 +149,7 @@
         mAuthentication = builder.mAuthentication;
         mAuthenticationIds = builder.mAuthenticationIds;
         mIgnoredIds = builder.mIgnoredIds;
+        mRequestId = INVALID_REQUEST_ID;
     }
 
     /** @hide */
@@ -185,6 +188,24 @@
     }
 
     /**
+     * Associates a {@link FillResponse} to a request.
+     *
+     * <p>Set inside of the {@link FillCallback} code, not the {@link AutofillService}.
+     *
+     * @param requestId The id of the request to associate the response to.
+     *
+     * @hide
+     */
+    public void setRequestId(int requestId) {
+        mRequestId = requestId;
+    }
+
+    /** @hide */
+    public int getRequestId() {
+        return mRequestId;
+    }
+
+    /**
      * Builder for {@link FillResponse} objects. You must to provide at least
      * one dataset or set an authentication intent with a presentation view.
      */
@@ -242,7 +263,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 +275,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 +332,7 @@
 
         /**
          * @deprecated Use {@link #setClientState(Bundle)} instead.
+         * @hide
          */
         @Deprecated
         public Builder setExtras(@Nullable Bundle extras) {
@@ -375,7 +397,8 @@
         if (!DEBUG) return super.toString();
 
         return new StringBuilder(
-                "FillResponse: [datasets=").append(mDatasets)
+                "FillResponse : [mRequestId=" + mRequestId)
+                .append(", datasets=").append(mDatasets)
                 .append(", saveInfo=").append(mSaveInfo)
                 .append(", clientState=").append(mClientState != null)
                 .append(", hasPresentation=").append(mPresentation != null)
@@ -384,6 +407,7 @@
                         ? mAuthenticationIds.length : "N/A")
                 .append(", ignoredIdsSize=").append(mIgnoredIds != null
                     ? mIgnoredIds.length : "N/A")
+                .append("]")
                 .toString();
     }
 
@@ -405,6 +429,7 @@
         parcel.writeParcelable(mAuthentication, flags);
         parcel.writeParcelable(mPresentation, flags);
         parcel.writeParcelableArray(mIgnoredIds, flags);
+        parcel.writeInt(mRequestId);
     }
 
     public static final Parcelable.Creator<FillResponse> CREATOR =
@@ -425,7 +450,11 @@
             builder.setAuthentication(parcel.readParcelableArray(null, AutofillId.class),
                     parcel.readParcelable(null), parcel.readParcelable(null));
             builder.setIgnoredIds(parcel.readParcelableArray(null, AutofillId.class));
-            return builder.build();
+            final FillResponse response = builder.build();
+
+            response.setRequestId(parcel.readInt());
+
+            return response;
         }
 
         @Override
diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl
index 688ac84..2bb3e9a 100644
--- a/core/java/android/service/autofill/IFillCallback.aidl
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -27,6 +27,6 @@
  */
 interface IFillCallback {
     void onCancellable(in ICancellationSignal cancellation);
-    void onSuccess(in FillResponse response, int requestId);
+    void onSuccess(in FillResponse response);
     void onFailure(CharSequence message);
 }
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index f796444..94e5e3e 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -21,9 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.assist.AssistStructure;
 import android.content.IntentSender;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.DebugUtils;
@@ -141,6 +139,33 @@
      */
     public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 0x10;
 
+    /**
+     * Style for the negative button of the save UI to cancel the
+     * save operation. In this case, the user tapping the negative
+     * button signals that they would prefer to not save the filled
+     * content.
+     */
+    public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0;
+
+    /**
+     * Style for the negative button of the save UI to reject the
+     * save operation. This could be useful if the user needs to
+     * opt-in your service and the save prompt is an advertisement
+     * of the potential value you can add to the user. In this
+     * case, the user tapping the negative button sends a strong
+     * signal that the feature may not be useful and you may
+     * consider some backoff strategy.
+     */
+    public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1;
+
+    /** @hide */
+    @IntDef(
+        value = {
+                NEGATIVE_BUTTON_STYLE_CANCEL,
+                NEGATIVE_BUTTON_STYLE_REJECT})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface NegativeButtonStyle{}
+
     /** @hide */
     @IntDef(
        flag = true,
@@ -154,7 +179,7 @@
     @interface SaveDataType{}
 
     /**
-     * Usually {@link AutofillService#onSaveRequest(AssistStructure, Bundle, SaveCallback)}
+     * Usually {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}
      * is called once the activity finishes. If this flag is set it is called once all saved views
      * become invisible.
      */
@@ -168,7 +193,7 @@
     @interface SaveInfoFlags{}
 
     private final @SaveDataType int mType;
-    private final CharSequence mNegativeActionTitle;
+    private final @NegativeButtonStyle int mNegativeButtonStyle;
     private final IntentSender mNegativeActionListener;
     private final AutofillId[] mRequiredIds;
     private final AutofillId[] mOptionalIds;
@@ -177,7 +202,7 @@
 
     private SaveInfo(Builder builder) {
         mType = builder.mType;
-        mNegativeActionTitle = builder.mNegativeActionTitle;
+        mNegativeButtonStyle = builder.mNegativeButtonStyle;
         mNegativeActionListener = builder.mNegativeActionListener;
         mRequiredIds = builder.mRequiredIds;
         mOptionalIds = builder.mOptionalIds;
@@ -186,8 +211,8 @@
     }
 
     /** @hide */
-    public @Nullable CharSequence getNegativeActionTitle() {
-        return mNegativeActionTitle;
+    public @NegativeButtonStyle int getNegativeActionStyle() {
+        return mNegativeButtonStyle;
     }
 
     /** @hide */
@@ -226,10 +251,9 @@
     public static final class Builder {
 
         private final @SaveDataType int mType;
-        private CharSequence mNegativeActionTitle;
+        private @NegativeButtonStyle int mNegativeButtonStyle = NEGATIVE_BUTTON_STYLE_CANCEL;
         private IntentSender mNegativeActionListener;
-        // TODO(b/33197203): make mRequiredIds final once addSavableIds() is gone
-        private AutofillId[] mRequiredIds;
+        private final AutofillId[] mRequiredIds;
         private AutofillId[] mOptionalIds;
         private CharSequence mDescription;
         private boolean mDestroyed;
@@ -251,37 +275,13 @@
          * @throws IllegalArgumentException if {@code requiredIds} is {@code null} or empty.
          */
         public Builder(@SaveDataType int type, @NonNull AutofillId[] requiredIds) {
-            if (false) {// TODO(b/33197203): re-move when clients use it
             Preconditions.checkArgument(requiredIds != null && requiredIds.length > 0,
                     "must have at least one required id: " + Arrays.toString(requiredIds));
-            }
             mType = type;
             mRequiredIds = requiredIds;
         }
 
         /**
-         * @hide
-         * @deprecated
-         * // TODO(b/33197203): make sure is removed when clients migrated
-         */
-        @Deprecated
-        public Builder(@SaveDataType int type) {
-            this(type, null);
-        }
-
-        /**
-         * @hide
-         * @deprecated
-         * // TODO(b/33197203): make sure is removed when clients migrated
-         */
-        @Deprecated
-        public @NonNull Builder addSavableIds(@Nullable AutofillId... ids) {
-            throwIfDestroyed();
-            mRequiredIds = ids;
-            return this;
-        }
-
-        /**
          * Set flags changing the save behavior.
          *
          * @param flags {@link #FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE} or 0.
@@ -325,38 +325,42 @@
             return this;
         }
 
-        /**
-         * Sets the title and listener for the negative save action.
-         *
-         * <p>This allows a fill-provider to customize the text and be
-         * notified when the user selects the negative action in the save
-         * UI. Note that selecting the negative action regardless of its text
-         * and listener being customized would dismiss the save UI and if a
-         * custom listener intent is provided then this intent will be
-         * started.</p>
-         *
-         * <p>This customization could be useful for providing additional
-         * semantics to the negative action. For example, a fill-provider
-         * can use this mechanism to add a "Disable" function or a "More info"
-         * function, etc. Note that the save action is exclusively controlled
-         * by the platform to ensure user consent is collected to release
-         * data from the filled app to the fill-provider.</p>
-         *
-         * @param title The action title.
-         * @param listener The action listener.
-         * @return This builder.
-         *
-         * @throws IllegalArgumentException If the title and the listener
-         *     are not both either null or non-null.
-         */
+        /** @hide */
+        // TODO (b/37563972): Remove when callers migrate
         public @NonNull Builder setNegativeAction(@Nullable CharSequence title,
                 @Nullable IntentSender listener) {
             throwIfDestroyed();
-            if (title == null ^ listener == null) {
-                throw new IllegalArgumentException("title and listener"
-                        + " must be both non-null or null");
+            setNegativeAction(NEGATIVE_BUTTON_STYLE_CANCEL, listener);
+            return this;
+        }
+
+        /**
+         * Sets the style and listener for the negative save action.
+         *
+         * <p>This allows a fill-provider to customize the style and be
+         * notified when the user selects the negative action in the save
+         * UI. Note that selecting the negative action regardless of its style
+         * and listener being customized would dismiss the save UI and if a
+         * custom listener intent is provided then this intent will be
+         * started. The default style is {@link #NEGATIVE_BUTTON_STYLE_CANCEL}</p>
+         *
+         * @param style The action style.
+         * @param listener The action listener.
+         * @return This builder.
+         *
+         * @see #NEGATIVE_BUTTON_STYLE_CANCEL
+         * @see #NEGATIVE_BUTTON_STYLE_REJECT
+         *
+         * @throws IllegalArgumentException If the style is invalid
+         */
+        public @NonNull Builder setNegativeAction(@NegativeButtonStyle int style,
+                @Nullable IntentSender listener) {
+            throwIfDestroyed();
+            if (style != NEGATIVE_BUTTON_STYLE_CANCEL
+                    && style != NEGATIVE_BUTTON_STYLE_REJECT) {
+                throw new IllegalArgumentException("Invalid style: " + style);
             }
-            mNegativeActionTitle = title;
+            mNegativeButtonStyle = style;
             mNegativeActionListener = listener;
             return this;
         }
@@ -390,6 +394,8 @@
                 .append(", requiredIds=").append(Arrays.toString(mRequiredIds))
                 .append(", optionalIds=").append(Arrays.toString(mOptionalIds))
                 .append(", description=").append(mDescription)
+                .append(DebugUtils.flagsToString(SaveInfo.class, "NEGATIVE_BUTTON_STYLE_",
+                        mNegativeButtonStyle))
                 .append(", mFlags=").append(mFlags)
                 .append("]").toString();
     }
@@ -407,7 +413,7 @@
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mType);
         parcel.writeParcelableArray(mRequiredIds, flags);
-        parcel.writeCharSequence(mNegativeActionTitle);
+        parcel.writeInt(mNegativeButtonStyle);
         parcel.writeParcelable(mNegativeActionListener, flags);
         parcel.writeParcelableArray(mOptionalIds, flags);
         parcel.writeCharSequence(mDescription);
@@ -422,7 +428,7 @@
             // using specially crafted parcels.
             final Builder builder = new Builder(parcel.readInt(),
                     parcel.readParcelableArray(null, AutofillId.class));
-            builder.setNegativeAction(parcel.readCharSequence(), parcel.readParcelable(null));
+            builder.setNegativeAction(parcel.readInt(), parcel.readParcelable(null));
             builder.setOptionalIds(parcel.readParcelableArray(null, AutofillId.class));
             builder.setDescription(parcel.readCharSequence());
             builder.setFlags(parcel.readInt());
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/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 0f85159..7e6eb49 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -88,11 +88,7 @@
      *  {@link android.webkit.WebView#findAddress(String) findAddress()} method in
      *  {@link android.webkit.WebView} for finding addresses, which has various
      *  limitations.
-     *
-     *  @deprecated See {@link android.webkit.WebView#findAddress(String) findAddress()}
-     *  for more explanation.
      */
-    @Deprecated
     public static final int MAP_ADDRESSES = 0x08;
 
     /**
diff --git a/core/java/android/transition/ChangeClipBounds.java b/core/java/android/transition/ChangeClipBounds.java
index 8d0943c..a6398d3 100644
--- a/core/java/android/transition/ChangeClipBounds.java
+++ b/core/java/android/transition/ChangeClipBounds.java
@@ -16,6 +16,7 @@
 package android.transition;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.RectEvaluator;
 import android.content.Context;
@@ -84,6 +85,7 @@
         }
         Rect start = (Rect) startValues.values.get(PROPNAME_CLIP);
         Rect end = (Rect) endValues.values.get(PROPNAME_CLIP);
+        boolean endIsNull = end == null;
         if (start == null && end == null) {
             return null; // No animation required since there is no clip.
         }
@@ -99,6 +101,17 @@
 
         endValues.view.setClipBounds(start);
         RectEvaluator evaluator = new RectEvaluator(new Rect());
-        return ObjectAnimator.ofObject(endValues.view, "clipBounds", evaluator, start, end);
+        ObjectAnimator animator =
+                ObjectAnimator.ofObject(endValues.view, "clipBounds", evaluator, start, end);
+        if (endIsNull) {
+            final View endView = endValues.view;
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    endView.setClipBounds(null);
+                }
+            });
+        }
+        return animator;
     }
 }
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/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9d40895..f539752 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -711,6 +711,10 @@
                     mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
+                if (mSurfaceControl == null) {
+                    return;
+                }
+
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
                         if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bcf0b90..64489b4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -100,6 +100,7 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
+import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
 import android.view.inputmethod.EditorInfo;
@@ -1068,10 +1069,15 @@
     public static final String AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY = "creditCardExpirationDay";
 
     /**
-     * Hintd for the autofill services that describes the content of the view.
+     * Hints for the autofill services that describes the content of the view.
      */
     private @Nullable String[] mAutofillHints;
 
+    /**
+     * Autofill id, lazily created on calls to {@link #getAutofillId()}.
+     */
+    private AutofillId mAutofillId;
+
     /** @hide */
     @IntDef({
             AUTOFILL_TYPE_NONE,
@@ -7276,13 +7282,13 @@
      *
      * <p>This method already provides most of what's needed for autofill, but should be overridden
      * when:
-     * <ol>
-     * <li>The view contents does not include PII (Personally Identifiable Information), so it
+     * <ul>
+     *   <li>The view contents does not include PII (Personally Identifiable Information), so it
      * can call {@link ViewStructure#setDataIsSensitive(boolean)} passing {@code false}.
-     * <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
+     *   <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
      * {@link ViewStructure#setAutofillOptions(CharSequence[])},
-     * or {@link ViewStructure#setUrl(String)}.
-     * </ol>
+     * or {@link ViewStructure#setWebDomain(String)}.
+     * </ul>
      *
      * @param structure Fill in with structured view data. The default implementation
      * fills in all data that can be inferred from the view itself.
@@ -7292,12 +7298,6 @@
         onProvideStructureForAssistOrAutofill(structure, true);
     }
 
-    private void setAutofillId(ViewStructure structure) {
-        // The autofill id needs to be unique, but its value doesn't matter,
-        // so it's better to reuse the accessibility id to save space.
-        structure.setAutofillId(getAccessibilityViewId());
-    }
-
     private void onProvideStructureForAssistOrAutofill(ViewStructure structure,
             boolean forAutofill) {
         final int id = mID;
@@ -7317,7 +7317,6 @@
         }
 
         if (forAutofill) {
-            setAutofillId(structure);
             final @AutofillType int autofillType = getAutofillType();
             // Don't need to fill autofill info if view does not support it.
             // For example, only TextViews that are editable support autofill
@@ -7381,17 +7380,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 +7417,6 @@
      * @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();
-        }
     }
 
     /**
@@ -7484,6 +7465,20 @@
     }
 
     /**
+     * Gets the unique identifier of this view on the screen for Autofill purposes.
+     *
+     * @return The View's Autofill id.
+     */
+    public final AutofillId getAutofillId() {
+        if (mAutofillId == null) {
+            // The autofill id needs to be unique, but its value doesn't matter,
+            // so it's better to reuse the accessibility id to save space.
+            mAutofillId = new AutofillId(getAccessibilityViewId());
+        }
+        return mAutofillId;
+    }
+
+    /**
      * Describes the autofill type that should be used on calls to
      * {@link #autofill(AutofillValue)} and {@link #autofill(SparseArray)}.
      *
@@ -7652,7 +7647,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 +7685,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 +7696,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();
             }
         }
@@ -7727,16 +7714,23 @@
     /**
      * Dispatch creation of {@link ViewStructure} down the hierarchy.
      *
-     * <p>The structure must be filled according to the request type, which is set in the
-     * {@code flags} parameter - see the documentation on each flag for more details.
+     * <p>The default implementation does the following:
      *
-     * <p>The default implementation calls {@link #onProvideAutofillStructure(ViewStructure, int)}
-     * and {@link #onProvideAutofillVirtualStructure(ViewStructure, int)}.
+     * <ul>
+     *   <li>Sets the {@link AutofillId} in the structure.
+     *   <li>Calls {@link #onProvideAutofillStructure(ViewStructure, int)}.
+     *   <li>Calls {@link #onProvideAutofillVirtualStructure(ViewStructure, int)}.
+     * </ul>
+     *
+     * <p>When overridden, it must either call
+     * {@code super.dispatchProvideAutofillStructure(structure, flags)} or explicitly
+     * set the {@link AutofillId} in the structure (for example, by calling
+     * {@code structure.setAutofillId(getAutofillId())}).
      *
      * @param structure Fill in with structured view data.
      * @param flags optional flags (currently {@code 0}).
      */
-    public void dispatchProvideAutofillStructure(ViewStructure structure, int flags) {
+    public void dispatchProvideAutofillStructure(@NonNull ViewStructure structure, int flags) {
         dispatchProvideStructureForAssistOrAutofill(structure, true);
     }
 
@@ -7745,7 +7739,7 @@
         boolean blocked = forAutofill ? isAutofillBlocked() : isAssistBlocked();
         if (!blocked) {
             if (forAutofill) {
-                setAutofillId(structure);
+                structure.setAutofillId(getAutofillId());
                 // NOTE: flags are not currently supported, hence 0
                 onProvideAutofillStructure(structure, 0);
                 onProvideAutofillVirtualStructure(structure, 0);
@@ -9598,13 +9592,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/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1977ef5..b783482 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5823,34 +5823,6 @@
     }
 
     /**
-     * Quick invalidation method that simply transforms the dirty rect into the parent's
-     * coordinate system, pruning the invalidation if the parent has already been invalidated.
-     *
-     * @hide
-     */
-    protected ViewParent damageChildInParent(int left, int top, final Rect dirty) {
-        if ((mPrivateFlags & PFLAG_DRAWN) != 0
-                || (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) != 0) {
-            dirty.offset(left - mScrollX, top - mScrollY);
-            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
-                dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
-            }
-
-            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 ||
-                    dirty.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
-
-                if (!getMatrix().isIdentity()) {
-                    transformRect(dirty);
-                }
-
-                return mParent;
-            }
-        }
-
-        return null;
-    }
-
-    /**
      * Offset a rectangle that is in a descendant's coordinate
      * space into our coordinate space.
      * @param descendant A descendant of this view
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index f061370..21123c1 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -330,20 +330,20 @@
 
         @Override
         public void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
-            if (mHostView != null && mHostView.getParent() != null) {
-                mHostView.getParent().onDescendantInvalidated(mHostView, target);
-            }
-        }
+            if (mHostView != null) {
+                if (mHostView instanceof ViewGroup) {
+                    // Propagate invalidate through the host...
+                    ((ViewGroup) mHostView).onDescendantInvalidated(mHostView, target);
 
-        /**
-         * @hide
-         */
-        @Override
-        protected ViewParent damageChildInParent(int left, int top, Rect dirty) {
-            if (mHostView instanceof ViewGroup) {
-                return ((ViewGroup) mHostView).damageChildInParent(left, top, dirty);
+                    // ...and also this view, since it will hold the descendant, and must later
+                    // propagate the calls to update display lists if dirty
+                    super.onDescendantInvalidated(child, target);
+                } else {
+                    // Can't use onDescendantInvalidated because host isn't a ViewGroup - fall back
+                    // to invalidating.
+                    invalidate();
+                }
             }
-            return null;
         }
 
         @Override
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..fb910b8 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -284,12 +284,30 @@
     public abstract ViewStructure asyncNewChild(int index);
 
     /**
+     * Gets the {@link AutofillId} associated with this node.
+     */
+    @Nullable
+    public abstract AutofillId getAutofillId();
+
+    /**
+     * Sets the {@link AutofillId} associated with this node.
+     */
+    public abstract void setAutofillId(@NonNull AutofillId id);
+
+    /**
      * Sets the {@link AutofillId} for this virtual node.
      *
-     * @param parent parent node.
+     * @param parentId id of the parent node.
      * @param virtualId an opaque ID to the Android System; it's the same id used on
      *            {@link View#autofill(android.util.SparseArray)}.
      */
+    public abstract void setAutofillId(@NonNull AutofillId parentId, int virtualId);
+
+    /**
+     * @deprecated - use {@link #setAutofillId(AutofillId, int)} instead
+     * @hide
+     */
+    @Deprecated
     public abstract void setAutofillId(@NonNull ViewStructure parent, int virtualId);
 
     /**
@@ -355,18 +373,21 @@
     /** @hide */
     public abstract Rect getTempRect();
 
-    /** @hide */
-    public abstract void setAutofillId(int viewId);
-
-    /** @hide */
-    public abstract AutofillId getAutofillId();
+    /**
+     * @deprecated - use {@link #setWebDomain(String)} instead.
+     * @hide
+     */
+    @Deprecated
+    public abstract void setUrl(String url);
 
     /**
-     * Sets the URL represented by this node.
+     * 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/view/textclassifier/LinksInfo.java b/core/java/android/view/textclassifier/LinksInfo.java
index 3acbdc0..754c9e9 100644
--- a/core/java/android/view/textclassifier/LinksInfo.java
+++ b/core/java/android/view/textclassifier/LinksInfo.java
@@ -22,6 +22,7 @@
  * Link information that can be applied to text. See: {@link #apply(CharSequence)}.
  * Typical implementations of this interface will annotate spannable text with e.g
  * {@link android.text.style.ClickableSpan}s or other annotations.
+ * @hide
  */
 public interface LinksInfo {
 
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index dcdbe57..6b641db 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -82,6 +82,7 @@
      * This is a blocking operation you should avoid calling it on the UI thread.
      *
      * @throws IllegalArgumentException if text is null
+     * @hide
      */
     public List<TextLanguage> detectLanguages(@NonNull CharSequence text) {
         Preconditions.checkArgument(text != null);
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index 0831e20..46fed43 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -132,6 +132,7 @@
      *      a default locale, or use the system default.
      *
      * @throws IllegalArgumentException if text is null
+     * @hide
      */
     LinksInfo getLinks(
             @NonNull CharSequence text, int linkMask, @Nullable LocaleList defaultLocales);
diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java
index d94d163..209813a 100644
--- a/core/java/android/view/textclassifier/TextLanguage.java
+++ b/core/java/android/view/textclassifier/TextLanguage.java
@@ -28,6 +28,7 @@
 
 /**
  * Specifies detected languages for a section of text indicated by a start and end index.
+ * @hide
  */
 public final class TextLanguage {
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9202889..6213a63 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1731,14 +1731,7 @@
      *
      * @param addr the string to search for addresses
      * @return the address, or if no address is found, null
-     *
-     * @deprecated findAddress is deprecated. It only supports a subset of US
-     * addresses and has a high false positive rate. Calling findAddress also causes
-     * WebView to be loaded into the app, which significantly increases memory usage
-     * if the app doesn't already use WebView. Use {@link TextClassifier} instead for
-     * classifying text and finding addresses.
      */
-    @Deprecated
     public static String findAddress(String addr) {
         // TODO: Rewrite this in Java so it is not needed to start up chromium
         // Could also be deprecated
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/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 869ef71..74f22b3 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -37,19 +37,38 @@
 import java.util.List;
 
 /**
- * A concrete BaseAdapter that is backed by an array of arbitrary
- * objects.  By default this class expects that the provided resource id references
- * a single TextView.  If you want to use a more complex layout, use the constructors that
- * also takes a field id.  That field id should reference a TextView in the larger layout
- * resource.
- *
- * <p>However the TextView is referenced, it will be filled with the toString() of each object in
- * the array. You can add lists or arrays of custom objects. Override the toString() method
- * of your objects to determine what text will be displayed for the item in the list.
- *
- * <p>To use something other than TextViews for the array display, for instance, ImageViews,
- * or to have some of data besides toString() results fill the views,
- * override {@link #getView(int, View, ViewGroup)} to return the type of view you want.
+ * You can use this adapter to provide views for an {@link AdapterView},
+ * Returns a view for each object in a collection of data objects you
+ * provide, and can be used with list-based user interface widgets such as
+ * {@link ListView} or {@link Spinner}.
+ * <p>
+ * By default, the array adapter creates a view by calling {@link Object#toString()} on each
+ * data object in the collection you provide, and places the result in a TextView.
+ * You may also customize what type of view is used for the data object in the collection.
+ * To customize what type of view is used for the data object,
+ * override {@link #getView(int, View, ViewGroup)}
+ * and inflate a view resource.
+ * For a code example, see
+ * the <a href="https://developer.android.com/samples/CustomChoiceList/index.html">
+ * CustomChoiceList</a> sample.
+ * </p>
+ * <p>
+ * For an example of using an array adapter with a ListView, see the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">
+ * Adapter Views</a> guide.
+ * </p>
+ * <p>
+ * For an example of using an array adapter with a Spinner, see the
+ * <a href="{@docRoot}guide/topics/ui/controls/spinner.html">Spinners</a> guide.
+ * </p>
+ * <p class="note"><strong>Note:</strong>
+ * If you are considering using array adapter with a ListView, consider using
+ * {@link android.support.v7.widget.RecyclerView} instead.
+ * RecyclerView offers similar features with better performance and more flexibility than
+ * ListView provides.
+ * See the
+ * <a href="https://developer.android.com/guide/topics/ui/layout/recyclerview.html">
+ * Recycler View</a> guide.</p>
  */
 public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter {
     /**
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..8094bfc 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -764,13 +764,12 @@
         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
         // onProvideAutoFillStructure() to fill itself, but it does not need to call
         // dispatchProvideAutoFillStructure() to fill its children.
+        structure.setAutofillId(getAutofillId());
         onProvideAutofillStructure(structure, flags);
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 7e6f2e4..57818e2 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -55,11 +55,31 @@
 import java.io.InputStream;
 
 /**
- * Displays an arbitrary image, such as an icon.  The ImageView class
- * can load images from various sources (such as resources or content
- * providers), takes care of computing its measurement from the image so that
- * it can be used in any layout manager, and provides various display options
- * such as scaling and tinting.
+ * Displays image resources, for example {@link android.graphics.Bitmap}
+ * or {@link android.graphics.drawable.Drawable} resources.
+ * ImageView is also commonly used to {@link #setImageTintMode(PorterDuff.Mode)
+ * apply tints to an image} and handle {@link #setScaleType(ScaleType) image scaling}.
+ *
+ * <p>
+ * The following XML snippet is a common example of using an ImageView to display an image resource:
+ * </p>
+ * <pre>
+ * &lt;LinearLayout
+ *     xmlns:android="http://schemas.android.com/apk/res/android"
+ *     android:layout_width="match_parent"
+ *     android:layout_height="match_parent"&gt;
+ *     &lt;ImageView
+ *         android:layout_width="wrap_content"
+ *         android:layout_height="wrap_content"
+ *         android:src="@mipmap/ic_launcher"
+ *         /&gt;
+ * &lt;/LinearLayout&gt;
+ * </pre>
+ *
+ * <p>
+ * To learn more about Drawables, see: <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
+ * To learn more about working with Bitmaps, see: <a href="{@docRoot}topic/performance/graphics/index.htm">Handling Bitmaps</a>.
+ * </p>
  *
  * @attr ref android.R.styleable#ImageView_adjustViewBounds
  * @attr ref android.R.styleable#ImageView_src
@@ -395,9 +415,13 @@
         mMaxHeight = maxHeight;
     }
 
-    /** Return the view's drawable, or null if no drawable has been
-        assigned.
-    */
+    /**
+     * Gets the current Drawable, or null if no Drawable has been
+     * assigned.
+     *
+     * @return the view's drawable, or null if no drawable has been
+     * assigned.
+     */
     public Drawable getDrawable() {
         if (mDrawable == mRecycleableBitmapDrawable) {
             // Consider our cached version dirty since app code now has a reference to it
@@ -428,7 +452,6 @@
 
     /**
      * Sets a drawable as the content of this ImageView.
-     *
      * <p class="note">This does Bitmap reading and decoding on the UI
      * thread, which can cause a latency hiccup.  If that's a concern,
      * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
@@ -474,7 +497,10 @@
 
     /**
      * Sets the content of this ImageView to the specified Uri.
-     *
+     * Note that you use this method to load images from a local Uri only.
+     * <p/>
+     * To learn how to display images from a remote Uri see: <a href="https://developer.android.com/topic/performance/graphics/index.html">Handling Bitmaps</a>
+     * <p/>
      * <p class="note">This does Bitmap reading and decoding on the UI
      * thread, which can cause a latency hiccup.  If that's a concern,
      * consider using {@link #setImageDrawable(Drawable)} or
@@ -598,6 +624,9 @@
     }
 
     /**
+     * Get the current {@link android.content.res.ColorStateList} used to tint the image Drawable,
+     * or null if no tint is applied.
+     *
      * @return the tint applied to the image drawable
      * @attr ref android.R.styleable#ImageView_tint
      * @see #setImageTintList(ColorStateList)
@@ -626,7 +655,8 @@
     }
 
     /**
-     * @return the blending mode used to apply the tint to the image drawable
+     * Gets the blending mode used to apply the tint to the image Drawable
+     * @return the blending mode used to apply the tint to the image Drawable
      * @attr ref android.R.styleable#ImageView_tintMode
      * @see #setImageTintMode(PorterDuff.Mode)
      */
@@ -673,6 +703,13 @@
         setImageDrawable(mRecycleableBitmapDrawable);
     }
 
+    /**
+     * Set the state of the current {@link android.graphics.drawable.StateListDrawable}.
+     * For more information about State List Drawables, see: <a href="https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList">the Drawable Resource Guide</a>.
+     *
+     * @param state the state to set for the StateListDrawable
+     * @param merge if true, merges the state values for the state you specify into the current state
+     */
     public void setImageState(int[] state, boolean merge) {
         mState = state;
         mMergeState = merge;
@@ -786,17 +823,16 @@
     }
 
     /**
-     * Return the current scale type in use by this ImageView.
-     *
+     * Returns the current ScaleType that is used to scale the bounds of an image to the bounds of the ImageView.
+     * @return The ScaleType used to scale the image.
      * @see ImageView.ScaleType
-     *
      * @attr ref android.R.styleable#ImageView_scaleType
      */
     public ScaleType getScaleType() {
         return mScaleType;
     }
 
-    /** Return the view's optional matrix. This is applied to the
+    /** Returns the view's optional matrix. This is applied to the
         view's drawable when it is drawn. If there is no matrix,
         this method will return an identity matrix.
         Do not change this matrix in place but make a copy.
@@ -815,7 +851,7 @@
      * to the view's drawable when it is drawn.  Allows custom scaling,
      * translation, and perspective distortion.
      *
-     * @param matrix the transformation parameters in matrix form
+     * @param matrix The transformation parameters in matrix form.
      */
     public void setImageMatrix(Matrix matrix) {
         // collapse null and identity to just null
@@ -1367,11 +1403,10 @@
     }
 
     /**
-     * Set whether to set the baseline of this view to the bottom of the view.
+     * Sets whether the baseline of this view to the bottom of the view.
      * Setting this value overrides any calls to setBaseline.
      *
-     * @param aligned If true, the image view will be baseline aligned with
-     *      based on its bottom edge.
+     * @param aligned If true, the image view will be baseline aligned by its bottom edge.
      *
      * @attr ref android.R.styleable#ImageView_baselineAlignBottom
      */
@@ -1383,8 +1418,9 @@
     }
 
     /**
-     * Return whether this view's baseline will be considered the bottom of the view.
+     * Checks whether this view's baseline is considered the bottom of the view.
      *
+     * @return True if the ImageView's baseline is considered the bottom of the view, false if otherwise.
      * @see #setBaselineAlignBottom(boolean)
      */
     public boolean getBaselineAlignBottom() {
@@ -1392,7 +1428,7 @@
     }
 
     /**
-     * Set a tinting option for the image.
+     * Sets a tinting option for the image.
      *
      * @param color Color tint to apply.
      * @param mode How to apply the color.  The standard mode is
@@ -1416,6 +1452,12 @@
         setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
     }
 
+    /**
+     * Removes the image's {@link android.graphics.ColorFilter}.
+     *
+     * @see #setColorFilter(int)
+     * @see #getColorFilter()
+     */
     public final void clearColorFilter() {
         setColorFilter(null);
     }
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 12e35a1..569fe01 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -67,11 +67,77 @@
 
 
 /**
- * A view that shows items in a vertically scrolling list. The items
- * come from the {@link ListAdapter} associated with this view.
+ * <p>Displays a vertically-scrollable collection of views, where each view is positioned
+ * immediatelybelow the previous view in the list.  For a more modern, flexible, and performant
+ * approach to displaying lists, use {@link android.support.v7.widget.RecyclerView}.</p>
  *
- * <p>See the <a href="{@docRoot}guide/topics/ui/layout/listview.html">List View</a>
- * guide.</p>
+ * <p>To display a list, you can include a list view in your layout XML file:</p>
+ *
+ * <pre>&lt;ListView
+ *      android:id="@+id/list_view"
+ *      android:layout_width="match_parent"
+ *      android:layout_height="match_parent" /&gt;</pre>
+ *
+ * <p>A list view is an <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">
+ * adapter view</a> that does not know the details, such as type and contents, of the views it
+ * contains. Instead list view requests views on demand from a {@link ListAdapter} as needed,
+ * such as to display new views as the user scrolls up or down.</p>
+ *
+ * <p>In order to display items in the list, call {@link #setAdapter(ListAdapter adapter)}
+ * to associate an adapter with the list.  For a simple example, see the discussion of filling an
+ * adapter view with text in the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#FillingTheLayout">
+ * Layouts</a> guide.</p>
+ *
+ * <p>To display a more custom view for each item in your dataset, implement a ListAdapter.
+ * For example, extend {@link BaseAdapter} and create and configure the view for each data item in
+ * {@code getView(...)}:</p>
+ *
+ *  <pre>private class MyAdapter extends BaseAdapter {
+ *
+ *      // override other abstract methods here
+ *
+ *      &#64;Override
+ *      public View getView(int position, View convertView, ViewGroup container) {
+ *          if (convertView == null) {
+ *              convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
+ *          }
+ *
+ *          ((TextView) convertView.findViewById(android.R.id.text1))
+ *                  .setText(getItem(position));
+ *          return convertView;
+ *      }
+ *  }</pre>
+ *
+ * <p class="note">ListView attempts to reuse view objects in order to improve performance and
+ * avoid a lag in response to user scrolls.  To take advantage of this feature, check if the
+ * {@code convertView} provided to {@code getView(...)} is null before creating or inflating a new
+ * view object.  See
+ * <a href="{@docRoot}training/improving-layouts/smooth-scrolling.html">
+ * Making ListView Scrolling Smooth</a> for more ways to ensure a smooth user experience.</p>
+ *
+ * <p>For a more complete example of creating a custom adapter, see the
+ * <a href="{@docRoot}samples/CustomChoiceList/index.html">
+ *     Custom Choice List</a> sample app.</p>
+ *
+ * <p>To specify an action when a user clicks or taps on a single list item, see
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#HandlingUserSelections">
+ *     Handling click events</a>.</p>
+ *
+ * <p>To learn how to populate a list view with a CursorAdapter, see the discussion of filling an
+ * adapter view with text in the
+ * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#FillingTheLayout">
+ * Layouts</a> guide.
+ * See <a href="{@docRoot}guide/topics/ui/layout/listview.html">
+ *     Using a Loader</a>
+ * to learn how to avoid blocking the main thread when using a cursor.</p>
+ *
+ * <p class="note">Note, many examples use {@link android.app.ListActivity ListActivity}
+ * or {@link android.app.ListFragment ListFragment}
+ * to display a list view. Instead, favor the more flexible approach when writing your own app:
+ * use a more generic Activity subclass or Fragment subclass and add a list view to the layout
+ * or view hierarchy directly.  This approach gives you more direct control of the
+ * list view and adapter.</p>
  *
  * @attr ref android.R.styleable#ListView_entries
  * @attr ref android.R.styleable#ListView_divider
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 16a31f1..399cfac 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -178,18 +178,43 @@
 import java.util.Locale;
 
 /**
- * Displays text to the user and optionally allows them to edit it.  A TextView
- * is a complete text editor, however the basic class is configured to not
- * allow editing; see {@link EditText} for a subclass that configures the text
- * view for editing.
- *
+ * A user interface element that displays text to the user.
+ * To provide user-editable text, see {@link EditText}.
  * <p>
- * To allow users to copy some or all of the TextView's value and paste it somewhere else, set the
- * XML attribute {@link android.R.styleable#TextView_textIsSelectable
- * android:textIsSelectable} to "true" or call
- * {@link #setTextIsSelectable setTextIsSelectable(true)}. The {@code textIsSelectable} flag
- * allows users to make selection gestures in the TextView, which in turn triggers the system's
- * built-in copy/paste controls.
+ * The following code sample shows a typical use, with an XML layout
+ * and code to modify the contents of the text view:
+ * </p>
+
+ * <pre>
+ * &lt;LinearLayout
+       xmlns:android="http://schemas.android.com/apk/res/android"
+       android:layout_width="match_parent"
+       android:layout_height="match_parent"&gt;
+ *    &lt;TextView
+ *        android:id="@+id/text_view_id"
+ *        android:layout_height="wrap_content"
+ *        android:layout_width="wrap_content"
+ *        android:text="@string/hello" /&gt;
+ * &lt;/LinearLayout&gt;
+ * </pre>
+ * <p>
+ * This code sample demonstrates how to modify the contents of the text view
+ * defined in the previous XML layout:
+ * </p>
+ * <pre>
+ * public class MainActivity extends Activity {
+ *
+ *    protected void onCreate(Bundle savedInstanceState) {
+ *         super.onCreate(savedInstanceState);
+ *         setContentView(R.layout.activity_main);
+ *         final TextView helloTextView = (TextView) findViewById(R.id.text_view_id);
+ *         helloTextView.setText(R.string.user_greeting);
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * To customize the appearance of TextView, see <a href="https://developer.android.com/guide/topics/ui/themes.html">Styles and Themes</a>.
+ * </p>
  * <p>
  * <b>XML attributes</b>
  * <p>
@@ -674,7 +699,7 @@
     int mTextEditSuggestionHighlightStyle;
 
     /**
-     * EditText specific data, created on demand when one of the Editor fields is used.
+     * {@link EditText} specific data, created on demand when one of the Editor fields is used.
      * See {@link #createEditorIfNeeded()}.
      */
     private Editor mEditor;
@@ -1346,6 +1371,9 @@
                         autoSizePresetTextSizes.recycle();
                     }
                     break;
+                case com.android.internal.R.styleable.TextView_justificationMode:
+                    mJustificationMode = a.getInt(attr, Layout.JUSTIFICATION_MODE_NONE);
+                    break;
             }
         }
 
@@ -2172,10 +2200,11 @@
      * with an argument of {@link android.widget.TextView.BufferType#SPANNABLE BufferType.SPANNABLE}
      * or {@link android.widget.TextView.BufferType#EDITABLE BufferType.EDITABLE}, you can cast
      * the return value from this method to Spannable or Editable, respectively.
-     * <p/>
-     * The content of the return value should not be modified. If you want a modifiable one, you
-     * should make your own copy first.
      *
+     * <p>The content of the return value should not be modified. If you want a modifiable one, you
+     * should make your own copy first.</p>
+     *
+     * @return The text displayed by the text view.
      * @attr ref android.R.styleable#TextView_text
      */
     @ViewDebug.CapturedViewProperty
@@ -2185,6 +2214,7 @@
 
     /**
      * Returns the length, in characters, of the text managed by this TextView
+     * @return The length of the text managed by the TextView in characters.
      */
     public int length() {
         return mText.length();
@@ -2201,26 +2231,28 @@
     }
 
     /**
-     * @return the height of one standard line in pixels.  Note that markup
-     * within the text can cause individual lines to be taller or shorter
-     * than this height, and the layout may contain additional first-
-     * or last-line padding.
+     * Gets the vertical distance between lines of text, in pixels.
+     * Note that markup within the text can cause individual lines
+     * to be taller or shorter than this height, and the layout may
+     * contain additional first-or last-line padding.
+     * @return The height of one standard line in pixels.
      */
     public int getLineHeight() {
         return FastMath.round(mTextPaint.getFontMetricsInt(null) * mSpacingMult + mSpacingAdd);
     }
 
     /**
-     * @return the Layout that is currently being used to display the text.
-     * This can be null if the text or width has recently changes.
+     * Gets the {@link android.text.Layout} that is currently being used to display the text.
+     * This value can be null if the text or width has recently changed.
+     * @return The Layout that is currently being used to display the text.
      */
     public final Layout getLayout() {
         return mLayout;
     }
 
     /**
-     * @return the Layout that is currently being used to display the hint text.
-     * This can be null.
+     * @return the {@link android.text.Layout} that is currently being used to
+     * display the hint text. This can be null.
      */
     final Layout getHintLayout() {
         return mHintLayout;
@@ -2272,8 +2304,9 @@
     }
 
     /**
-     * @return the current key listener for this TextView.
+     * Gets the current {@link KeyListener} for the TextView.
      * This will frequently be null for non-EditText TextViews.
+     * @return the current key listener for this TextView.
      *
      * @attr ref android.R.styleable#TextView_numeric
      * @attr ref android.R.styleable#TextView_digits
@@ -2350,17 +2383,20 @@
     }
 
     /**
-     * @return the movement method being used for this TextView.
+     * Gets the {@link android.text.method.MovementMethod} being used for this TextView,
+     * which provides positioning, scrolling, and text selection functionality.
      * This will frequently be null for non-EditText TextViews.
+     * @return the movement method being used for this TextView.
+     * @see android.text.method.MovementMethod
      */
     public final MovementMethod getMovementMethod() {
         return mMovement;
     }
 
     /**
-     * Sets the movement method (arrow key handler) to be used for
-     * this TextView.  This can be null to disallow using the arrow keys
-     * to move the cursor or scroll the view.
+     * Sets the {@link android.text.method.MovementMethod} for handling arrow key movement
+     * for this TextView. This can be null to disallow using the arrow keys to move the
+     * cursor or scroll the view.
      * <p>
      * Be warned that if you want a TextView with a key listener or movement
      * method not to be focusable, or if you want a TextView without a
@@ -2397,9 +2433,9 @@
     }
 
     /**
+     * Gets the current {@link android.text.method.TransformationMethod} for the TextView.
+     * This is frequently null, except for single-line and password fields.
      * @return the current transformation method for this TextView.
-     * This will frequently be null except for single-line and password
-     * fields.
      *
      * @attr ref android.R.styleable#TextView_password
      * @attr ref android.R.styleable#TextView_singleLine
@@ -3432,8 +3468,8 @@
     }
 
     /**
-     * Set the default {@link LocaleList} of the text in this TextView to a one-member list
-     * containing just the given value.
+     * Set the default {@link Locale} of the text in this TextView to a one-member
+     * {@link LocaleList} containing just the given Locale.
      *
      * @param locale the {@link Locale} for drawing text, must not be null.
      *
@@ -3492,7 +3528,7 @@
     }
 
     /**
-     * @return the size (in scaled pixels) of thee default text size in this TextView.
+     * @return the size (in scaled pixels) of the default text size in this TextView.
      * @hide
      */
     @ViewDebug.ExportedProperty(category = "text")
@@ -3574,16 +3610,19 @@
     }
 
     /**
-     * @return the extent by which text is currently being stretched
-     * horizontally.  This will usually be 1.
+     * Gets the extent by which text should be stretched horizontally.
+     * This will usually be 1.0.
+     * @return The horizontal scale factor.
      */
     public float getTextScaleX() {
         return mTextPaint.getTextScaleX();
     }
 
     /**
-     * Sets the extent by which text should be stretched horizontally.
-     *
+     * Sets the horizontal scale factor for text. The default value
+     * is 1.0. Values greater than 1.0 stretch the text wider.
+     * Values less than 1.0 make the text narrower. By default, this value is 1.0.
+     * @param size The horizontal scale factor.
      * @attr ref android.R.styleable#TextView_textScaleX
      */
     @android.view.RemotableViewMethod
@@ -3626,8 +3665,8 @@
     }
 
     /**
-     * @return the current typeface and style in which the text is being
-     * displayed.
+     * Gets the current {@link Typeface} that is used to style the text.
+     * @return The current Typeface.
      *
      * @see #setTypeface(Typeface)
      *
@@ -3660,8 +3699,9 @@
     }
 
     /**
-     * @return the extent by which text is currently being letter-spaced.
-     * This will normally be 0.
+     * Gets the text letter-space value, which determines the spacing between characters.
+     * The value returned is in ems. Normally, this value is 0.0.
+     * @return The text letter-space value in ems.
      *
      * @see #setLetterSpacing(float)
      * @see Paint#setLetterSpacing
@@ -3671,12 +3711,13 @@
     }
 
     /**
-     * Sets text letter-spacing.  The value is in 'EM' units.  Typical values
+     * Sets text letter-spacing in em units.  Typical values
      * for slight expansion will be around 0.05.  Negative values tighten text.
      *
      * @see #getLetterSpacing()
      * @see Paint#getLetterSpacing
      *
+     * @param letterSpacing A text letter-space value in ems.
      * @attr ref android.R.styleable#TextView_letterSpacing
      */
     @android.view.RemotableViewMethod
@@ -3741,7 +3782,8 @@
     }
 
     /**
-     * @return the currently set break strategy.
+     * Gets the current strategy for breaking paragraphs into lines.
+     * @return the current strategy for breaking paragraphs into lines.
      *
      * @attr ref android.R.styleable#TextView_breakStrategy
      * @see #setBreakStrategy(int)
@@ -3752,9 +3794,12 @@
     }
 
     /**
-     * Sets the hyphenation frequency. The default value for both TextView and EditText, which is
-     * set from the theme, is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
+     * Sets the frequency of automatic hyphenation to use when determining word breaks.
+     * The default value for both TextView and {@link EditText} is
+     * {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
+     * Note that the default hyphenation frequency value is set from the theme.
      *
+     * @param hyphenationFrequency The hyphenation frequency to use.
      * @attr ref android.R.styleable#TextView_hyphenationFrequency
      * @see #getHyphenationFrequency()
      */
@@ -3768,7 +3813,9 @@
     }
 
     /**
-     * @return the currently set hyphenation frequency.
+     * Gets the current frequency of automatic hyphenation to be used when determining word breaks.
+     * @return the current frequency of automatic hyphenation to be used when determining word
+     * breaks.
      *
      * @attr ref android.R.styleable#TextView_hyphenationFrequency
      * @see #setHyphenationFrequency(int)
@@ -3927,7 +3974,7 @@
     }
 
     /**
-     * <p>Return the current color selected for normal text.</p>
+     * Return the current color selected for normal text.
      *
      * @return Returns the current text color.
      */
@@ -4037,7 +4084,8 @@
     }
 
     /**
-     * @return the vertical offset of the shadow layer
+     * Gets the vertical offset of the shadow layer.
+     * @return The vertical offset of the shadow layer.
      *
      * @see #setShadowLayer(float, float, float, int)
      *
@@ -4048,6 +4096,7 @@
     }
 
     /**
+     * Gets the color of the shadow layer.
      * @return the color of the shadow layer
      *
      * @see #setShadowLayer(float, float, float, int)
@@ -4060,8 +4109,9 @@
     }
 
     /**
-     * @return the base paint used for the text.  Please use this only to
-     * consult the Paint's properties and not to change them.
+     * Gets the {@link TextPaint} used for the text.
+     * Use this only to consult the Paint's properties and not to change them.
+     * @return The base paint used for the text.
      */
     public TextPaint getPaint() {
         return mTextPaint;
@@ -4105,7 +4155,7 @@
     }
 
     /**
-     * Returns the list of URLSpans attached to the text
+     * Returns the list of {@link android.text.style.URLSpan URLSpans} attached to the text
      * (by {@link Linkify} or otherwise) if any.  You can call
      * {@link URLSpan#getURL} on them to find where they link to
      * or use {@link Spanned#getSpanStart} and {@link Spanned#getSpanEnd}
@@ -4266,7 +4316,8 @@
     }
 
     /**
-     * @return the flags on the Paint being used to display the text.
+     * Gets the flags on the Paint being used to display the text.
+     * @return The flags on the Paint being used to display the text.
      * @see Paint#getFlags
      */
     public int getPaintFlags() {
@@ -5691,8 +5742,8 @@
 
     /**
      * Change the editor type integer associated with the text view, which
-     * will be reported to an IME with {@link EditorInfo#imeOptions} when it
-     * has focus.
+     * is reported to an Input Method Editor (IME) with {@link EditorInfo#imeOptions}
+     * when it has focus.
      * @see #getImeOptions
      * @see android.view.inputmethod.EditorInfo
      * @attr ref android.R.styleable#TextView_imeOptions
@@ -5704,8 +5755,8 @@
     }
 
     /**
-     * Get the type of the IME editor.
-     *
+     * Get the type of the Input Method Editor (IME).
+     * @return the type of the IME
      * @see #setImeOptions(int)
      * @see android.view.inputmethod.EditorInfo
      */
@@ -7532,7 +7583,7 @@
 
     /**
      * Called by the framework in response to a text auto-correction (such as fixing a typo using a
-     * a dictionary) from the current input method, provided by it calling
+     * dictionary) from the current input method, provided by it calling
      * {@link InputConnection#commitCorrection(CorrectionInfo) InputConnection.commitCorrection()}.
      * The default implementation flashes the background of the corrected word to provide
      * feedback to the user.
@@ -9636,6 +9687,11 @@
         return super.onTrackballEvent(event);
     }
 
+    /**
+     * Sets the Scroller used for producing a scrolling animation
+     *
+     * @param s A Scroller instance
+     */
     public void setScroller(Scroller s) {
         mScroller = s;
     }
@@ -10114,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) {
@@ -10581,6 +10635,7 @@
     /**
      * Returns whether this text view is a current input method target.  The
      * default implementation just checks with {@link InputMethodManager}.
+     * @return True if the TextView is a current input method target; false otherwise.
      */
     public boolean isInputMethodTarget() {
         InputMethodManager imm = InputMethodManager.peekInstance();
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index fb00c4392..de289bb 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -519,13 +519,12 @@
         }
     }
 
-    // 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
         // onProvideAutoFillStructure() to fill itself, but it does not need to call
         // dispatchProvideAutoFillStructure() to fill its children.
+        structure.setAutofillId(getAutofillId());
         onProvideAutofillStructure(structure, flags);
     }
 
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/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 11e7102..fb6b8b0 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -332,8 +332,12 @@
     }
 
     private void addMinimizedTarget(boolean isHorizontalDivision) {
-        int position = mTaskHeightInMinimizedMode;
-        position += isHorizontalDivision ? mInsets.top : mInsets.left;
+        // In portrait offset the position by the statusbar height, in landscape add the statusbar
+        // height as well to match portrait offset
+        int position = mTaskHeightInMinimizedMode + mInsets.top;
+        if (!isHorizontalDivision) {
+            position += mInsets.left;
+        }
         mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
     }
 
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/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index d046996..f1b19e17 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -427,6 +427,11 @@
     String8 clientName(packageUtf.c_str());
     sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
 
+    if (queue == NULL) {
+        jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
+        return 0;
+    }
+
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
     if (messageQueue == NULL) {
         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 18a1360..2921b37 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -83,7 +83,7 @@
             colorType = kN32_SkColorType;
             alphaType = kOpaque_SkAlphaType;
             break;
-        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT:
+        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
             colorType = kRGBA_F16_SkColorType;
             alphaType = kPremul_SkAlphaType;
             break;
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 155a939..3131302 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -126,6 +126,7 @@
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.LOCAL_NAME_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.UUID" />
     <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
@@ -3160,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.
@@ -3701,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/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index a6892c6..2f7ad3a 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -16,85 +16,88 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_save"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
-    android:paddingStart="16dip"
-    android:paddingEnd="16dip"
-    android:paddingTop="16dip"
-    android:paddingBottom="16dip"
-    android:elevation="16dp"
-    android:background="?android:attr/colorBackground"
     android:orientation="vertical">
 
     <LinearLayout
+        android:id="@+id/autofill_save"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal">
+        android:layout_marginTop="32dp"
+        android:padding="16dp"
+        android:elevation="32dp"
+        android:background="?android:attr/colorBackground"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/autofill_save_title"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:text="@string/autofill_save_title"
+                android:textSize="16sp"
+                android:textColor="?android:attr/textColorPrimary"
+                android:layout_weight="1">
+            </TextView>
+
+            <ImageView
+                android:id="@+id/autofill_save_close"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="16dp"
+                android:src="@android:drawable/ic_close"
+                android:alpha="0.54"
+                android:background="?android:attr/selectableItemBackgroundBorderless">
+            </ImageView>
+
+        </LinearLayout>
 
         <TextView
-            android:id="@+id/autofill_save_title"
-            android:layout_width="wrap_content"
+            android:id="@+id/autofill_save_subtitle"
+            android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:text="@string/autofill_save_title"
-            android:singleLine="true">
+            android:layout_marginTop="4dp"
+            android:visibility="gone">
         </TextView>
 
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:visibility="invisible" >
-        </Space>
-
-        <ImageView
-            android:id="@+id/autofill_save_close"
+        <com.android.internal.widget.ButtonBarLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:src="@android:drawable/ic_close"
-            android:background="?android:attr/selectableItemBackgroundBorderless">
-        </ImageView>
+            android:layout_gravity="end"
+            android:layout_marginTop="16dp"
+            android:layout_weight="1"
+            android:orientation="horizontal">
+
+            <Space
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:visibility="invisible">
+            </Space>
+
+            <Button
+                android:id="@+id/autofill_save_no"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="?android:attr/buttonBarButtonStyle"
+                android:text="@string/autofill_save_no">
+            </Button>
+
+            <Button
+                android:id="@+id/autofill_save_yes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                style="@style/Widget.Material.Button.Colored"
+                android:text="@string/autofill_save_yes">
+            </Button>
+
+        </com.android.internal.widget.ButtonBarLayout>
 
     </LinearLayout>
 
-    <TextView
-        android:id="@+id/autofill_save_subtitle"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:visibility="invisible" >
-    </TextView>
-
-    <com.android.internal.widget.ButtonBarLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:layout_marginTop="16dp"
-        android:layout_weight="1"
-        android:orientation="horizontal">
-
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:visibility="invisible" >
-        </Space>
-
-        <Button
-            android:id="@+id/autofill_save_no"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/autofill_save_no" >
-        </Button>
-
-        <Button
-            android:id="@+id/autofill_save_yes"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/autofill_save_yes" >
-        </Button>
-
-   </com.android.internal.widget.ButtonBarLayout>
-
 </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index 74f0e57..76b3528 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -33,7 +33,8 @@
             android:layout_gravity="top"
             android:layout_marginTop="@dimen/notification_content_margin_top"
             android:layout_marginBottom="@dimen/notification_action_list_height"
-            android:paddingTop="10dp"
+            android:paddingTop="4dp"
+            android:paddingBottom="6dp"
             android:clipToPadding="false"
             android:orientation="vertical">
 
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 86bb518..b66167e 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -837,7 +837,7 @@
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji da dodaje poruke u prijemno sanduče govorne pošte."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmena dozvola za geografske lokacije Pregledača"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb sajtovima."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji da izmeni dozvole Pregledača za utvrđivanje geografske lokacije. Zlonamerne aplikacije to mogu da zloupotrebe i iskoriste za slanje informacija o lokaciji nasumičnim veb-sajtovima."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da pregledač zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 83db42c..754e04f 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1736,10 +1736,8 @@
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"বিষয়বস্তুগুলি অটো-ফিল করা যাবে না"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> এ সংরক্ষণ করবেন?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="LABEL">%2$s</xliff:g> এ <xliff:g id="TYPE">%1$s</xliff:g> সংরক্ষণ করবেন?"</string>
-    <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
-    <skip />
-    <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
-    <skip />
+    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> <xliff:g id="LABEL">%3$s</xliff:g> এ সংরক্ষণ করবেন?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> <xliff:g id="LABEL">%4$s</xliff:g> এ সংরক্ষণ করবেন?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"সংরক্ষণ করুন"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"না থাক"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"পাসওয়ার্ড"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0a63cdf..b0ea791 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1735,8 +1735,8 @@
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"El contingut no es pot emplenar automàticament"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"Vols desar-ho a <xliff:g id="LABEL">%1$s</xliff:g>?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"Vols desar la informació del camp <xliff:g id="TYPE">%1$s</xliff:g> a <xliff:g id="LABEL">%2$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Vols desar la informació dels camps <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vols desar la informació dels camps <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> a <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
+    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"Vols desar <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="LABEL">%3$s</xliff:g>?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"Vols desar <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g> a <xliff:g id="LABEL">%4$s</xliff:g>?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Desa"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"No, gràcies"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"contrasenya"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6e930ff..e283c3d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -391,7 +391,7 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Audio aufnehmen"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Diese App kann jederzeit Ton über das Mikrofon aufnehmen."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Diese App kann jederzeit Audio über das Mikrofon aufnehmen."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"Befehle an die SIM senden"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index c46146d..08bff7d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -495,7 +495,7 @@
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"consultar el contenido de la tarjeta SD"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Permite que la aplicación lea el contenido del almacenamiento USB."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permite que la aplicación lea el contenido de la tarjeta SD."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"editar o borrar contenido de USB"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"editar o borrar contenido de almacenamiento USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modificar o eliminar el contenido de la tarjeta SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite escribir en el almacenamiento USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que la aplicación escriba en la tarjeta SD."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7312fa6..25bdc11 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -346,7 +346,7 @@
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"به برنامه امکان می‌دهد قسمت‌هایی از خود را در حافظه دائمی کند. این کار حافظه موجود را برای سایر برنامه‌ها محدود کرده و باعث کندی تلفن می‌شود."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"اندازه گیری فضای حافظه برنامه"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"‏به برنامه اجازه می‎دهد تا کدها، داده‎ها و اندازه‎های حافظهٔ پنهان خود را بازیابی کند"</string>
-    <string name="permlab_writeSettings" msgid="2226195290955224730">"اصلاح تنظیمات سیستم"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"تغییر تنظیمات سیستم"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"‏به برنامه اجازه می‎دهد تا داده‎های تنظیم سیستم را تغییر دهد. برنامه‎های مخرب می‎توانند پیکربندی سیستم شما را خراب کنند."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"اجرا شدن در هنگام راه‌اندازی"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"به برنامه اجازه می‌دهد که به محض پایان راه‌اندازی سیستم، راه‌اندازی شود. این ویژگی ممکن است باعث شود راه‌اندازی دستگاه مدت زمان بیشتری طول بکشد و به برنامه اجازه می‌دهد با همیشه درحال اجرا بودنش باعث کاهش سرعت کلی دستگاه شود."</string>
@@ -360,7 +360,7 @@
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در رایانهٔ لوحی شما را بخواند از جمله، تعداد دفعات تماس‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا به روش‌های دیگری به افراد خاصی ارتباط برقرار کرده‌اید. این با برنامه‌ها امکان می‌دهد داده‌های مخاطب شما را ذخیره کنند و برنامه‌های مخرب ممکن است داده‌های مخاطب را بدون اطلاع شما به اشتراک بگذارند."</string>
     <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در تلویزیون شما را از جمله تعداد تماس‌‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه می‌دهد تا داده‌های مخاطب را ذخیره کند و شاید برنامه‌های مخرب داده‌های مخاطب را بدون اطلاع شما به اشتراک بگذارند."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در تلفن شما را بخواند از جمله، تعداد دفعات تماس‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا به روش‌های دیگری با افراد خاصی ارتباط برقرار کرده‌اید. این به برنامه‌ها امکان می‌دهد داده‌های مخاطب شما را ذخیره کنند و برنامه‌های مخرب ممکن است داده‌های مخاطب را بدون اطلاع شما به اشتراک بگذارند."</string>
-    <string name="permlab_writeContacts" msgid="5107492086416793544">"اصلاح مخاطبین شما"</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"تغییر مخاطبین"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در رایانهٔ لوحی شما را از جمله تعداد تماس‌‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه می‌دهد داده‌های مخاطب را حذف نماید."</string>
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در تلویزیون شما را از جمله تعداد تماس‌‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه می‌دهد داده‌های مخاطب را حذف نماید."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"به برنامه اجازه می‌دهد داده‌های مربوط به مخاطبین ذخیره شده در تلفن شما را از جمله تعداد تماس‌‌هایی که برقرار کرده‌اید، ایمیل‌هایی که ارسال کرده‌اید یا ارتباطاتی را که به هر شکل با مخاطبین خاصی برقرار کردید تغییر دهد. این مجوز به برنامه اجازه می‌دهد داده‌های مخاطب را حذف نماید."</string>
@@ -389,7 +389,7 @@
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"‏این برنامه می‌تواند براساس منابع شبکه مانند دکل‌های مخابراتی و شبکه‌های Wi-Fi، مکان شما را تشخیص دهد. این خدمات مکان باید روشن و در تلویزیون شما دردسترس باشند تا برنامه بتواند از آن‌ها استفاده کند."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"‏این برنامه می‌تواند براساس منابع شبکه مانند دکل‌های مخابراتی و شبکه‌های Wi-Fi، مکان شما را تشخیص دهد. این خدمات مکان باید روشن و در تلفن شما دردسترس باشند تا برنامه بتواند از آن‌ها استفاده کند."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"تغییر تنظیمات صوتی"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"به برنامه امکان می‌دهد تنظیمات صوتی کلی مانند میزان صدا و بلندگوی مورد استفاده برای پخش صدا را اصلاح کند."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"به برنامه امکان می‌دهد تنظیمات صوتی کلی مانند میزان صدا و بلندگوی مورد استفاده برای پخش صدا را تغییر دهد."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ضبط صدا"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"این برنامه می‌تواند در هرزمانی با استفاده از میکروفون صدا ضبط کند."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"ارسال فرمان به سیم کارت"</string>
@@ -488,15 +488,15 @@
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"خواندن تنظیمات همگام‌سازی"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"به برنامه اجازه می‌دهد تنظیمات را برای یک حساب بخواند. به‌عنوان مثال، این ویژگی می‌تواند تعیین کند آیا حساب «افراد» شما با یک حساب همگام‌سازی شده است."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"تغییر وضعیت همگام‌سازی بین فعال و غیرفعال"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"به یک برنامه اجازه می‌دهد تنظیمات همگام‌سازی را برای یک حساب اصلاح کند. به‌عنوان مثال، از این ویژگی می‌توان برای فعال کردن همگام‌سازی برنامه «افراد» با یک حساب استفاده کرد."</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"به برنامه اجازه می‌دهد تنظیمات همگام‌سازی را برای حساب تغییر دهد. به‌عنوان مثال، از این ویژگی می‌توان برای فعال کردن همگام‌سازی برنامه «افراد» با یک حساب استفاده کرد."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"خواندن اطلاعات آماری همگام‌سازی"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"به یک برنامه اجازه می‌دهد وضعیت همگام‌سازی یک حساب را بخواند، از جمله سابقه رویدادهای همگام‌سازی و میزان داده‌های همگام‌سازی شده."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"‏خواندن محتویات حافظهٔ USB شما"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"‏خواندن محتویات کارت SD شما"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"‏به برنامه اجازه می‌دهد محتواهای فضای ذخیره USB را بخواند."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"‏به برنامه اجازه می‌دهد محتواهای کارت SD شما را بخواند."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"‏اصلاح یا حذف محتویات حافظهٔ USB شما"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"‏محتوای کارت SD شما را اصلاح کرده یا تغییر دهد"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"‏تغییر یا حذف محتویات حافظه USB"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"‏تغییر یا حذف محتوای کارت SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"‏به برنامه اجازه می‎دهد تا در حافظهٔ USB بنویسد."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"‏به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"‏تماس گرفتن/دریافت تماس از طریق SIP"</string>
@@ -517,7 +517,7 @@
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"‏به برنامه اجازه می‎دهد تا کاربرد شبکه را در طول زمان برای برنامه‎ها و شبکه‎های خاص بخواند."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"مدیریت خط‌مشی شبکه"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"‏به برنامه اجازه می‎دهد تا خط‌مشی‎های شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string>
-    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"اصلاح محاسبه استفاده از شبکه"</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"تغییر محاسبه استفاده از شبکه"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"‏به برنامه اجازه می‎دهد تا نحوه محاسبه کاربرد شبکه در برنامه را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"اعلان‌های دسترسی"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"به برنامه اجازه می‌دهد به بازیابی، بررسی و پاک کردن اعلان‌ها از جمله موارد پست شده توسط سایر برنامه‌ها بپردازد."</string>
@@ -826,9 +826,9 @@
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"خواندن سابقه و نشانک‌های وب شما"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"به برنامه اجازه می‌دهد سابقه نشانی‌های وب را که مرورگر بازدید کرده است و همه نشانک‌های مرورگر را بخواند. توجه: این مجوز توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نیست."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"نوشتن نشانک‌های وب و سابقه"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"به برنامه اجازه می‌دهد سابقه مرورگر یا نشانک‌های ذخیره شده در رایانهٔ لوحی شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد داده‌های مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نباشد."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"به برنامه اجازه می‌دهد سابقه مرورگر یا نشانک‌های ذخیره‌شده در رایانهٔ لوحی شما را تغییر دهد. این ممکن است به برنامه اجازه دهد داده‌های مرورگر را حذف کند یا تغییر دهد. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نباشد."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"به برنامه اجازه می‌دهد تا سابقه یا نشانک‌های ذخیره شده مرورگر در تلویزیون شما را تغییر دهد. شاید به برنامه اجازه دهد تا داده‌های «مرورگر» را پاک کند یا تغییر دهد. توجه: این مجوز شاید توسط مرورگرهای شخص ثالث یا سایر برنامه‌ها با قابلیت‌های مرور وب اجرا شود."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"به برنامه اجازه می‌دهد سابقه مرورگر یا نشانک‌های ذخیره شده در تلفن شما را اصلاح کند. این ویژگی ممکن است به برنامه اجازه دهد داده‌های مرورگر را حذف یا اصلاح کند. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نباشد."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"به برنامه اجازه می‌دهد سابقه مرورگر یا نشانک‌های ذخیره‌شده در تلفن شما را تغییر دهد. این ممکن است به برنامه اجازه دهد داده‌های مرورگر را حذف کند یا تغییر دهد. توجه: این مجوز ممکن است توسط مرورگرهای شخص ثالث یا سایر برنامه‌های دارای قابلیت مرور وب قابل اجرا نباشد."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"تنظیم یک هشدار"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"‏به برنامه اجازه می‎دهد تا هشداری را در برنامه ساعت زنگدار نصب شده تنظیم کند. برخی از برنامه‎های ساعت زنگدار نمی‌‎توانند این ویژگی را اعمال کنند."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"افزودن پست صوتی"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index fdea62a..5b7b377 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1641,7 +1641,7 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"Jusqu\'à ce que vous désactiviez le mode Ne pas déranger"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"Jusqu\'à ce que vous désactiviez ce mode"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Jusqu\'à ce que vous désactiviez la fonctionnalité \"Ne pas déranger\""</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 82481d5..58adbca 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1736,10 +1736,8 @@
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"કન્ટેન્ટ સ્વતઃ ભરી શકાતું નથી"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> માં સાચવીએ?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ને <xliff:g id="LABEL">%2$s</xliff:g> માં સાચવીએ?"</string>
-    <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
-    <skip />
-    <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
-    <skip />
+    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="LABEL">%3$s</xliff:g>માં <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> સાચવીએ?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="LABEL">%4$s</xliff:g>માં <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> સાચવીએ?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"સાચવો"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"નહીં આભાર"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"પાસવર્ડ"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 4769676..43c18da7 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1736,10 +1736,8 @@
     <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"सामग्रींची स्‍वयं-भरणा करता येणार नाही"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> वर जतन करायचे?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="LABEL">%2$s</xliff:g> वर <xliff:g id="TYPE">%1$s</xliff:g> जतन करायचे?"</string>
-    <!-- no translation found for autofill_save_title_with_2types (8875796560521962098) -->
-    <skip />
-    <!-- no translation found for autofill_save_title_with_3types (6889899028382843493) -->
-    <skip />
+    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="LABEL">%3$s</xliff:g> वर <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> जतन करायचे का?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="LABEL">%4$s</xliff:g> वर <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> जतन करायचे का?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"जतन करा"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"नाही धन्यवाद"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"संकेतशब्द"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 5252422..dd71d43 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1737,7 +1737,7 @@
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ကို <xliff:g id="LABEL">%2$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
     <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>၊ <xliff:g id="TYPE_1">%2$s</xliff:g> ကို <xliff:g id="LABEL">%3$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
-    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>၊ <xliff:g id="TYPE_1">%2$s</xliff:g>၊ <xliff:g id="TYPE_2">%3$s</xliff:g> ကို <xliff:g id="LABEL">%4$s</xliff:g>သို့ သိမ်းဆည်းလိုပါသလား။"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>၊ <xliff:g id="TYPE_1">%2$s</xliff:g>၊ <xliff:g id="TYPE_2">%3$s</xliff:g> ကို <xliff:g id="LABEL">%4$s</xliff:g> သို့ သိမ်းဆည်းလိုပါသလား။"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"သိမ်းရန်"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"မလိုပါ"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"စကားဝှက်"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 71fd285..702e2fb 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1733,7 +1733,7 @@
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਲਿਖਤ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਘੜੀ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"ਆਟੋਫਿਲ ਵਿਕਲਪ"</string>
-    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ਸਮੱਗਰੀਆਂ ਆਟੋਫਿਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"ਸਮੱਗਰੀਆਂ ਨੂੰ ਆਟੋਫਿਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> ਨੂੰ <xliff:g id="LABEL">%2$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
     <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ਨੂੰ <xliff:g id="LABEL">%3$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੀਏ?"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 3ac621a..e32823f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -322,7 +322,7 @@
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Приложение получит доступ к сообщениям широковещательных SMS-служб, которые в некоторых странах используются для информирования населения об экстренных ситуациях. Вредоносные программы могут помешать работе устройства, на которое поступают такие сообщения."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Просмотр фидов пользователя"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Приложение сможет получать сведения о синхронизируемых в настоящее время фидах."</string>
-    <string name="permlab_sendSms" msgid="7544599214260982981">"отправка и просмотр SMS-сообщений"</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"Отправка и просмотр SMS-сообщений"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Приложение сможет отправлять SMS. Учтите, что вредоносные программы смогут отправлять сообщения без уведомления, что может привести к непредвиденным расходам."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"Просмотр SMS и MMS"</string>
     <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"Приложение может считывать SMS-сообщения на планшете."</string>
@@ -378,7 +378,7 @@
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Приложение сможет вносить изменения в список вызовов телефона и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"Датчики (например, пульсометр)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Приложение сможет получить доступ к данным датчиков, размещенных на теле, например измеряющих частоту сердцебиения."</string>
-    <string name="permlab_readCalendar" msgid="6716116972752441641">"Просмотр мероприятий и других данных календаря"</string>
+    <string name="permlab_readCalendar" msgid="6716116972752441641">"Чтение мероприятий и данных"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре планшета."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре телевизора."</string>
     <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре телефона."</string>
@@ -467,7 +467,7 @@
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Доступ к настройкам Bluetooth на телевизоре, установка соединений с сопряженными устройствами и принятие запросов на подключение."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Приложение сможет просматривать конфигурацию Bluetooth на телефоне, а также запрашивать и подтверждать соединение с другими устройствами."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Управление NFC-модулем"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"Приложение сможет обмениваться данными с NFC-метками, картами и устройствами считывания, используя связь малого радиуса действия."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Приложение сможет обмениваться данными с NFC-метками, картами и устройствами считывания, используя NFC."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Отключение функции блокировки экрана"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Приложение сможет отключать блокировку экрана и другие функции защиты. Например, блокировка экрана будет отключаться при получении входящего вызова и включаться после завершения разговора."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление сканером отпечатков"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 6e13582..6dc7761 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -837,7 +837,7 @@
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"додавање говорне поште"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дозвољава апликацији да додаје поруке у пријемно сандуче говорне поште."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"измена дозвола за географске локације Прегледача"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дозвољава апликацији да измени дозволе Прегледача за утврђивање географске локације. Злонамерне апликације то могу да злоупотребе и искористе за слање информација о локацији насумичним веб сајтовима."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дозвољава апликацији да измени дозволе Прегледача за утврђивање географске локације. Злонамерне апликације то могу да злоупотребе и искористе за слање информација о локацији насумичним веб-сајтовима."</string>
     <string name="save_password_message" msgid="767344687139195790">"Желите ли да прегледач запамти ову лозинку?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Не сада"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Запамти"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 664a038..d104bb7 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -181,7 +181,7 @@
     <string name="work_profile_deleted_details" msgid="6307630639269092360">"Programu ya msimamizi wa wasifu wa kazini imepotea au ina hitilafu. Kwa sababu hiyo, wasifu wako wa kazini na data husika imefutwa. Wasiliana na msimamizi wako kwa usaidizi."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Wasifu wako wa kazini haupatikani tena kwenye kifaa hiki"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Kifaa kinadhibitiwa"</string>
-    <string name="network_logging_notification_text" msgid="7930089249949354026">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia trafiki ya mtandao. Gonga ili upate maelezo zaidi."</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao. Gonga ili upate maelezo zaidi."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Data iliyomo kwenye kifaa chako itafutwa"</string>
     <string name="factory_reset_message" msgid="7972496262232832457">"Huwezi kutumia programu ya msimamizi. Sasa data iliyo kwenye kifaa chako itafutwa.\n\nIkiwa una maswali yoyote, wasiliana na msimamizi wa shirika lako."</string>
     <string name="me" msgid="6545696007631404292">"Mimi"</string>
@@ -277,7 +277,7 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Vihisi vya Mwili"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kihisi kuhusu alama zako muhimu"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kitambuzi kuhusu alama zako muhimu"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Rejesha maudhui ya dirisha"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Chunguza maudhui ya dirisha unaloingiliana nalo."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Washa Chunguza kwa Mguso"</string>
@@ -466,9 +466,9 @@
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Huruhusu programu kuomba njia za kuongeza na kufuta violezo vya kitambulisho kwa matumizi."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"tumia maunzi ya kitambulisho"</string>
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Huruhusu programu kutumia maunzi ya kitambulisho kwa uthibitisho"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Kihisi kimegundua sehemu ya kitambulisho. Tafadhali jaribu tena."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Kitambuzi kimegundua sehemu ya kitambulisho. Tafadhali jaribu tena."</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Haikuweza kuchakata kitambulisho. Tafadhali jaribu tena."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Kihisi kitambulisho ni kichafu. Tafadhali kisafishe na ujaribu tena."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Kitambuzi alama ya kidole ni kichafu. Tafadhali kisafishe na ujaribu tena."</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Ulisogeza kidole kwa kasi mno. Tafadhali jaribu tena."</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Kidole kilisogezwa polepole zaidi. Tafadhali jaribu tena."</string>
   <string-array name="fingerprint_acquired_vendor">
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index ee2438f..35e4455 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1733,11 +1733,11 @@
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Vaqtni kiritish uchun matn kiritish rejimiga o‘ting."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Vaqtni kiritish uchun soat rejimiga o‘ting."</string>
     <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Avtomatik to‘ldirish parametrlari"</string>
-    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Kontentlarni avtomatik to‘ldirib bo‘lmaydi"</string>
+    <string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Avtomatik to‘ldirib bo‘lmaydi"</string>
     <string name="autofill_save_title" msgid="7081244500504163245">"<xliff:g id="LABEL">%1$s</xliff:g> xizmatiga saqlansinmi?"</string>
     <string name="autofill_save_title_with_type" msgid="4977385733042555659">"<xliff:g id="TYPE">%1$s</xliff:g> <xliff:g id="LABEL">%2$s</xliff:g> xizmatiga saqlansinmi?"</string>
-    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%3$s</xliff:g> yorlig‘iga saqlansinmi?"</string>
-    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%4$s</xliff:g> yorlig‘iga saqlansinmi?"</string>
+    <string name="autofill_save_title_with_2types" msgid="8875796560521962098">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%3$s</xliff:g> ichiga saqlansinmi?"</string>
+    <string name="autofill_save_title_with_3types" msgid="6889899028382843493">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ma’lumotlari <xliff:g id="LABEL">%4$s</xliff:g> ichiga saqlansinmi?"</string>
     <string name="autofill_save_yes" msgid="6398026094049005921">"Saqlash"</string>
     <string name="autofill_save_no" msgid="2625132258725581787">"Yo‘q, kerak emas"</string>
     <string name="autofill_save_type_password" msgid="5288448918465971568">"parol"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1daecdd..2d1a20b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -285,7 +285,7 @@
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"启用触摸浏览"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"设备将大声读出您点按的内容,同时您可以通过手势来浏览屏幕。"</string>
     <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"启用网页无障碍增强功能"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"安装脚本以方便访问应用的内容。"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"可能会安装程序以便访问应用的内容。"</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"监测您输入的文字"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"包含个人数据,例如信用卡号和密码。"</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"控制显示内容放大功能"</string>
@@ -832,7 +832,7 @@
     <string name="permlab_setAlarm" msgid="1379294556362091814">"设置闹钟"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"允许应用在已安装的闹钟应用中设置闹钟。有些闹钟应用可能无法实现此功能。"</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"添加语音邮件"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"允许应用向您的语音信箱收件箱添加邮件。"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"允许应用在您的语音信箱中留言。"</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"修改“浏览器”地理位置的权限"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"允许应用修改“浏览器”的地理位置权限。恶意应用可能借此向任意网站发送位置信息。"</string>
     <string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8682d7d..3898cae 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2332,10 +2332,18 @@
         <attr name="importantForAutofill">
             <!-- Let the Android System use its heuristics to determine if the view is important for autofill. -->
             <flag name="auto" value="0" />
-            <!-- Hint the Android System that this view is important for autofill. -->
+            <!-- Hint the Android System that this view is important for autofill,
+                  and its children (if any) will be traversed.. -->
             <flag name="yes" value="0x1" />
-            <!-- Hint the Android System that this view is *not* important for autofill. -->
+            <!-- Hint the Android System that this view is *not* important for autofill,
+                  but its children (if any) will be traversed.. -->
             <flag name="no" value="0x2" />
+            <!-- Hint the Android System that this view is important for autofill,
+                 but its children (if any) will not be traversed. -->
+            <flag name="yesExcludeDescendants" value="0x4" />
+            <!-- Hint the Android System that this view is *not* important for autofill,
+                 and its children (if any) will not be traversed. -->
+            <flag name="noExcludeDescendants" value="0x8" />
         </attr>
 
         <!-- Boolean that controls whether a view can take focus while in touch mode.
@@ -3426,7 +3434,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 +3467,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
@@ -4776,6 +4782,13 @@
         <attr name="autoSizeMinTextSize" format="dimension" />
         <!-- The maximum text size constraint to be used when auto-sizing text. -->
         <attr name="autoSizeMaxTextSize" format="dimension" />
+        <!-- Mode for justification. -->
+        <attr name="justificationMode">
+            <!-- No justification. -->
+            <enum name="none" value="0" />
+            <!-- Justification by stretching word spacing. -->
+            <enum name="inter_word" value = "1" />
+        </attr>
     </declare-styleable>
     <declare-styleable name="TextViewAppearance">
         <!-- Base text color, typeface, size, and style. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 27a4d5c..0fa1fdb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2833,4 +2833,34 @@
 
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
+
+    <!-- Configuration for automotive -->
+    <bool name="enable_pbap_pce_profile">false</bool>
+
+    <!-- Default data warning level in mb -->
+    <integer name="default_data_warning_level_mb">2048</integer>
+
+    <!-- Whether to send a custom package name with the PSD.-->
+    <bool name="config_sendPackageName">false</bool>
+
+    <!-- Name for the set of keys associating package names -->
+    <string name="config_helpPackageNameKey" translatable="false"></string>
+
+    <!-- Name for the set of values of package names -->
+    <string name="config_helpPackageNameValue" translatable="false"></string>
+
+    <!-- Intent key for the package name keys -->
+    <string name="config_helpIntentExtraKey" translatable="false"></string>
+
+    <!-- Intent key for package name values -->
+    <string name="config_helpIntentNameKey" translatable="false"></string>
+
+    <!-- Intent key for the package name keys -->
+    <string name="config_feedbackIntentExtraKey" translatable="false"></string>
+
+    <!-- Intent key for package name values -->
+    <string name="config_feedbackIntentNameKey" translatable="false"></string>
+
+    <!-- The apps that need to be hidden when they are disabled -->
+    <string-array name="config_hideWhenDisabled_packageNames"></string-array>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 89c912fd..e13026b 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2821,6 +2821,7 @@
         <public name="requiredSystemPropertyName" />
         <!-- @hide @SystemApi -->
         <public name="requiredSystemPropertyValue" />
+        <public name="justificationMode" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bd35073..35b12ff 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -212,6 +212,21 @@
     <!-- Displayed to tell the user that they should switch their network preference. -->
     <string name="NetworkPreferenceSwitchSummary">To improve reception, try changing the type selected at System &gt; Network &amp; Internet &gt; Mobile networks &gt; Preferred network type."</string>
 
+    <!-- Telephony notification channel name for a channel containing network alert notifications. -->
+    <string name="notification_channel_network_alert">Alerts</string>
+    <!-- Telephony notification channel name for a channel containing call forwarding notifications. -->
+    <string name="notification_channel_call_forward">Call forwarding</string>
+    <!-- Telephony notification channel name for a channel containing emergency callback mode notifications. -->
+    <string name="notification_channel_emergency_callback">Emergency callback mode</string>
+    <!-- Telephony notification channel name for a channel containing mobile data alert notifications. -->
+    <string name="notification_channel_mobile_data_alert">Mobile data alerts</string>
+    <!-- Telephony notification channel name for a channel containing sms notifications. -->
+    <string name="notification_channel_sms">SMS messages</string>
+    <!-- Telephony notification channel name for a channel containing voice mail notifications. -->
+    <string name="notification_channel_voice_mail">Voicemail messages</string>
+    <!-- Telephony notification channel name for a channel containing wifi calling status notifications. -->
+    <string name="notification_channel_wfc">Wi-Fi calling</string>
+
     <!-- Displayed to tell the user that peer changed TTY mode -->
     <string name="peerTtyModeFull">Peer requested TTY Mode FULL</string>
     <string name="peerTtyModeHco">Peer requested TTY Mode HCO</string>
@@ -698,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. -->
@@ -4587,23 +4595,26 @@
     <!-- Accessibility title for the autofill dialog used to select a list of options to autofill an activity. [CHAR LIMIT=NONE] -->
     <string name="autofill_picker_accessibility_title">Autofill options</string>
 
+    <!-- Accessibility title for the autofill dialog used to ask user to save the information on the screen by sending it to an Autofill Service. [CHAR LIMIT=NONE] -->
+    <string name="autofill_save_accessibility_title">Save for Autofill</string>
+
     <!-- Toast message shown when user manually request autofill but service could not figure out the data that would autofill the screen contents. [CHAR LIMIT=NONE] -->
     <string name="autofill_error_cannot_autofill">Contents can\u2019t be autofilled</string>
 
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title">Save to <xliff:g id="label" example="MyPass">%1$s</xliff:g>?</string>
+    <string name="autofill_save_title">Save to &lt;b><xliff:g id="label" example="MyPass">%1$s</xliff:g>&lt;/b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to <xliff:g id="label" example="MyPass">%2$s</xliff:g>?</string>
+    <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%2$s</xliff:g>&lt;/b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, and the service does knows what the activity represents, and it represents 2 types of
          data (for example, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g>, <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to <xliff:g id="label" example="MyPass">%3$s</xliff:g>?</string>
+    <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g> and <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%3$s</xliff:g>&lt;/b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, and the service does knows what the activity represents, and it represents 3 types of
          data (for example, username, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to <xliff:g id="label" example="MyPass">%4$s</xliff:g>?</string>
+    <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%4$s</xliff:g>&lt;/b>?</string>
     <!-- Label for the autofill save button [CHAR LIMIT=NONE] -->
     <string name="autofill_save_yes">Save</string>
     <!-- Label for the autofill cancel button [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1dd8227..63a5cfd7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -523,6 +523,13 @@
   <java-symbol type="string" name="RestrictedOnDataContent" />
   <java-symbol type="string" name="RestrictedOnEmergencyContent" />
   <java-symbol type="string" name="RestrictedOnNormalContent" />
+  <java-symbol type="string" name="notification_channel_network_alert" />
+  <java-symbol type="string" name="notification_channel_call_forward" />
+  <java-symbol type="string" name="notification_channel_emergency_callback" />
+  <java-symbol type="string" name="notification_channel_mobile_data_alert" />
+  <java-symbol type="string" name="notification_channel_sms" />
+  <java-symbol type="string" name="notification_channel_voice_mail" />
+  <java-symbol type="string" name="notification_channel_wfc" />
   <java-symbol type="string" name="SetupCallDefault" />
   <java-symbol type="string" name="accept" />
   <java-symbol type="string" name="activity_chooser_view_see_all" />
@@ -2886,6 +2893,7 @@
   <java-symbol type="string" name="autofill_error_cannot_autofill" />
   <java-symbol type="string" name="autofill" />
   <java-symbol type="string" name="autofill_picker_accessibility_title " />
+  <java-symbol type="string" name="autofill_save_accessibility_title " />
   <java-symbol type="string" name="autofill_save_title" />
   <java-symbol type="string" name="autofill_save_title_with_type" />
   <java-symbol type="string" name="autofill_save_title_with_2types" />
@@ -2976,4 +2984,18 @@
   <java-symbol type="bool" name="config_quickSettingsSupported" />
 
   <java-symbol type="style" name="Theme.DeviceDefault.QuickSettings" />
+
+  <java-symbol type="bool" name="enable_pbap_pce_profile" />
+
+  <java-symbol type="integer" name="default_data_warning_level_mb" />
+
+  <java-symbol type="bool" name="config_sendPackageName" />
+  <java-symbol type="string" name="config_helpPackageNameKey" />
+  <java-symbol type="string" name="config_helpPackageNameValue" />
+  <java-symbol type="string" name="config_helpIntentExtraKey" />
+  <java-symbol type="string" name="config_helpIntentNameKey" />
+  <java-symbol type="string" name="config_feedbackIntentExtraKey" />
+  <java-symbol type="string" name="config_feedbackIntentNameKey" />
+
+  <java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 5669189..94a515b 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1266,6 +1266,11 @@
             <meta-data android:name="com.android.frameworks.coretests.reference" android:resource="@xml/metadata" />
         </provider>
 
+        <provider android:name="android.provider.MockFontProvider"
+                  android:authorities="android.provider.fonts.font"
+                  android:exported="false"
+                  android:multiprocess="true" />
+
         <!-- Application components used for content tests -->
         <provider android:name="android.content.MemoryFileProvider"
                 android:authorities="android.content.MemoryFileProvider"
diff --git a/core/tests/coretests/assets/fonts/samplefont1.ttf b/core/tests/coretests/assets/fonts/samplefont1.ttf
new file mode 100644
index 0000000..020436a
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/samplefont1.ttf
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/samplefont1.ttx b/core/tests/coretests/assets/fonts/samplefont1.ttx
new file mode 100644
index 0000000..40fa268
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/samplefont1.ttx
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
+
+  <GlyphOrder>
+    <GlyphID id="0" name=".notdef"/>
+    <GlyphID id="1" name="a"/>
+  </GlyphOrder>
+
+  <head>
+    <tableVersion value="1.0"/>
+    <fontRevision value="1.0"/>
+    <checkSumAdjustment value="0x640cdb2f"/>
+    <magicNumber value="0x5f0f3cf5"/>
+    <flags value="00000000 00000011"/>
+    <unitsPerEm value="1000"/>
+    <created value="Fri Mar 17 07:26:00 2017"/>
+    <macStyle value="00000000 00000000"/>
+    <lowestRecPPEM value="7"/>
+    <fontDirectionHint value="2"/>
+    <glyphDataFormat value="0"/>
+  </head>
+
+  <hhea>
+    <tableVersion value="1.0"/>
+    <ascent value="1000"/>
+    <descent value="-200"/>
+    <lineGap value="0"/>
+    <caretSlopeRise value="1"/>
+    <caretSlopeRun value="0"/>
+    <caretOffset value="0"/>
+    <reserved0 value="0"/>
+    <reserved1 value="0"/>
+    <reserved2 value="0"/>
+    <reserved3 value="0"/>
+    <metricDataFormat value="0"/>
+  </hhea>
+
+  <maxp>
+    <tableVersion value="0x10000"/>
+    <maxZones value="0"/>
+    <maxTwilightPoints value="0"/>
+    <maxStorage value="0"/>
+    <maxFunctionDefs value="0"/>
+    <maxInstructionDefs value="0"/>
+    <maxStackElements value="0"/>
+    <maxSizeOfInstructions value="0"/>
+    <maxComponentElements value="0"/>
+  </maxp>
+
+  <OS_2>
+    <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+         will be recalculated by the compiler -->
+    <version value="3"/>
+    <xAvgCharWidth value="594"/>
+    <usWeightClass value="400"/>
+    <usWidthClass value="5"/>
+    <fsType value="00000000 00001000"/>
+    <ySubscriptXSize value="650"/>
+    <ySubscriptYSize value="600"/>
+    <ySubscriptXOffset value="0"/>
+    <ySubscriptYOffset value="75"/>
+    <ySuperscriptXSize value="650"/>
+    <ySuperscriptYSize value="600"/>
+    <ySuperscriptXOffset value="0"/>
+    <ySuperscriptYOffset value="350"/>
+    <yStrikeoutSize value="50"/>
+    <yStrikeoutPosition value="300"/>
+    <sFamilyClass value="0"/>
+    <panose>
+      <bFamilyType value="0"/>
+      <bSerifStyle value="0"/>
+      <bWeight value="5"/>
+      <bProportion value="0"/>
+      <bContrast value="0"/>
+      <bStrokeVariation value="0"/>
+      <bArmStyle value="0"/>
+      <bLetterForm value="0"/>
+      <bMidline value="0"/>
+      <bXHeight value="0"/>
+    </panose>
+    <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+    <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+    <achVendID value="UKWN"/>
+    <fsSelection value="00000000 01000000"/>
+    <usFirstCharIndex value="32"/>
+    <usLastCharIndex value="122"/>
+    <sTypoAscender value="800"/>
+    <sTypoDescender value="-200"/>
+    <sTypoLineGap value="200"/>
+    <usWinAscent value="1000"/>
+    <usWinDescent value="200"/>
+    <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+    <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+    <sxHeight value="500"/>
+    <sCapHeight value="700"/>
+    <usDefaultChar value="0"/>
+    <usBreakChar value="32"/>
+    <usMaxContext value="0"/>
+  </OS_2>
+
+  <hmtx>
+    <mtx name=".notdef" width="500" lsb="93"/>
+    <mtx name="a" width="500" lsb="93"/>
+  </hmtx>
+
+  <cmap>
+    <tableVersion version="0"/>
+    <cmap_format_4 platformID="3" platEncID="10" language="0">
+      <map code="0x0061" name="a" />
+    </cmap_format_4>
+  </cmap>
+
+  <loca>
+    <!-- The 'loca' table will be calculated by the compiler -->
+  </loca>
+
+  <glyf>
+    <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
+    <TTGlyph name="a" xMin="0" yMin="0" xMax="0" yMax="0" />
+  </glyf>
+
+  <name>
+    <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
+      SampleFont-Regular
+    </namerecord>
+    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+      Regular
+    </namerecord>
+    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+      Sample Font
+    </namerecord>
+    <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+      SampleFont-Regular
+    </namerecord>
+  </name>
+
+  <post>
+    <formatType value="3.0"/>
+    <italicAngle value="0.0"/>
+    <underlinePosition value="-75"/>
+    <underlineThickness value="50"/>
+    <isFixedPitch value="0"/>
+    <minMemType42 value="0"/>
+    <maxMemType42 value="0"/>
+    <minMemType1 value="0"/>
+    <maxMemType1 value="0"/>
+  </post>
+
+</ttFont>
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/FontsContractE2ETest.java b/core/tests/coretests/src/android/provider/FontsContractE2ETest.java
new file mode 100644
index 0000000..51916ff
--- /dev/null
+++ b/core/tests/coretests/src/android/provider/FontsContractE2ETest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.provider;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.graphics.Typeface;
+import android.graphics.fonts.FontRequest;
+import android.os.Handler;
+import android.provider.FontsContract.Columns;
+import android.provider.FontsContract.FontFamilyResult;
+import android.provider.FontsContract.FontInfo;
+import android.provider.FontsContract;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FontsContractE2ETest {
+    private static final String AUTHORITY = "android.provider.fonts.font";
+    private static final String PACKAGE = "com.android.frameworks.coretests";
+
+    // Signature to be used for authentication to access content provider.
+    // In this test case, the content provider and consumer live in the same package, self package's
+    // signature works.
+    private static List<List<byte[]>> SIGNATURE;
+    static {
+        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        try {
+            PackageManager manager = context.getPackageManager();
+            PackageInfo info = manager.getPackageInfo(
+                    context.getPackageName(), PackageManager.GET_SIGNATURES);
+            ArrayList<byte[]> out = new ArrayList<>();
+            for (Signature sig : info.signatures) {
+                out.add(sig.toByteArray());
+            }
+            SIGNATURE = new ArrayList<>();
+            SIGNATURE.add(out);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Before
+    public void setUp() {
+        MockFontProvider.prepareFontFiles(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+    }
+
+    @After
+    public void tearDown() {
+        MockFontProvider.cleanUpFontFiles(
+                InstrumentationRegistry.getInstrumentation().getTargetContext());
+    }
+
+    private static class TestCallback extends FontsContract.FontRequestCallback {
+        private Typeface mTypeface;
+
+        private int mSuccessCallCount;
+        private int mFailedCallCount;
+
+        public void onTypefaceRetrieved(Typeface typeface) {
+            mTypeface = typeface;
+            mSuccessCallCount++;
+        }
+
+        public void onTypefaceRequestFailed(int reason) {
+            mFailedCallCount++;
+        }
+
+        public Typeface getTypeface() {
+            return mTypeface;
+        }
+
+        public int getSuccessCallCount() {
+            return mSuccessCallCount;
+        }
+
+        public int getFailedCallCount() {
+            return mFailedCallCount;
+        }
+    }
+
+    @Test
+    public void typefaceCacheTest() throws NameNotFoundException {
+        Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        Context ctx = inst.getTargetContext();
+
+        final TestCallback callback = new TestCallback();
+        inst.runOnMainSync(() -> {
+            FontRequest request = new FontRequest(
+                    AUTHORITY, PACKAGE, "singleFontFamily", SIGNATURE);
+            FontsContract.requestFonts(ctx, request, new Handler(), null, callback);
+        });
+        inst.waitForIdleSync();
+        assertEquals(1, callback.getSuccessCallCount());
+        assertEquals(0, callback.getFailedCallCount());
+        assertNotNull(callback.getTypeface());
+
+        final TestCallback callback2 = new TestCallback();
+        inst.runOnMainSync(() -> {
+            FontRequest request = new FontRequest(
+                    AUTHORITY, PACKAGE, "singleFontFamily", SIGNATURE);
+            FontsContract.requestFonts(ctx, request, new Handler(), null, callback2);
+        });
+        inst.waitForIdleSync();
+        assertEquals(1, callback2.getSuccessCallCount());
+        assertEquals(0, callback2.getFailedCallCount());
+        assertSame(callback.getTypeface(), callback2.getTypeface());
+
+        final TestCallback callback3 = new TestCallback();
+        inst.runOnMainSync(() -> {
+            FontRequest request = new FontRequest(
+                    AUTHORITY, PACKAGE, "singleFontFamily2", SIGNATURE);
+            FontsContract.requestFonts(ctx, request, new Handler(), null, callback3);
+        });
+        inst.waitForIdleSync();
+        assertEquals(1, callback3.getSuccessCallCount());
+        assertEquals(0, callback3.getFailedCallCount());
+        assertNotSame(callback.getTypeface(), callback3.getTypeface());
+    }
+
+    @Test
+    public void typefaceNotCacheTest() throws NameNotFoundException {
+        Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        Context ctx = inst.getTargetContext();
+
+        FontRequest request = new FontRequest(
+                AUTHORITY, PACKAGE, "singleFontFamily", SIGNATURE);
+        FontFamilyResult result = FontsContract.fetchFonts(
+                ctx, null /* cancellation signal */, request);
+        assertEquals(FontFamilyResult.STATUS_OK, result.getStatusCode());
+        Typeface typeface = FontsContract.buildTypeface(
+                ctx, null /* cancellation signal */, result.getFonts());
+
+        FontFamilyResult result2 = FontsContract.fetchFonts(
+                ctx, null /* cancellation signal */, request);
+        assertEquals(FontFamilyResult.STATUS_OK, result2.getStatusCode());
+        Typeface typeface2 = FontsContract.buildTypeface(
+                ctx, null /* cancellation signal */, result2.getFonts());
+
+        // Neighter fetchFonts nor buildTypeface should cache the Typeface.
+        assertNotSame(typeface, typeface2);
+    }
+
+    @Test
+    public void typefaceNullFdTest() throws NameNotFoundException {
+        Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        Context ctx = inst.getTargetContext();
+
+        FontRequest request = new FontRequest(
+                AUTHORITY, PACKAGE, MockFontProvider.NULL_FD_QUERY, SIGNATURE);
+        FontFamilyResult result = FontsContract.fetchFonts(
+                ctx, null /* cancellation signal */, request);
+        assertNull(FontsContract.buildTypeface(
+                ctx, null /* cancellation signal */, result.getFonts()));
+    }
+
+    @Test
+    public void getFontSyncTest() {
+        FontRequest request = new FontRequest(AUTHORITY, PACKAGE, "singleFontFamily", SIGNATURE);
+        assertNotNull(FontsContract.getFontSync(request));
+    }
+
+    @Test
+    public void getFontSyncTest_timeout() {
+        FontRequest request = new FontRequest(
+                AUTHORITY, PACKAGE, MockFontProvider.BLOCKING_QUERY, SIGNATURE);
+        assertNull(FontsContract.getFontSync(request));
+        MockFontProvider.unblock();
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/MockFontProvider.java b/core/tests/coretests/src/android/provider/MockFontProvider.java
new file mode 100644
index 0000000..ad5b130
--- /dev/null
+++ b/core/tests/coretests/src/android/provider/MockFontProvider.java
@@ -0,0 +1,266 @@
+/*
+ * 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.provider;
+
+import static android.provider.FontsContract.Columns;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.fonts.FontVariationAxis;
+import android.net.Uri;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.android.internal.annotations.GuardedBy;
+
+public class MockFontProvider extends ContentProvider {
+    final static String AUTHORITY = "android.provider.fonts.font";
+
+    private static final long BLOCKING_TIMEOUT_MS = 10000;  // 10 sec
+    private static final Lock sLock = new ReentrantLock();
+    private static final Condition sCond = sLock.newCondition();
+    @GuardedBy("sLock")
+    private static boolean sSignaled;
+
+    private static void blockUntilSignal() {
+        long remaining = TimeUnit.MILLISECONDS.toNanos(BLOCKING_TIMEOUT_MS);
+        sLock.lock();
+        try {
+            sSignaled = false;
+            while (!sSignaled) {
+                try {
+                    remaining = sCond.awaitNanos(remaining);
+                } catch (InterruptedException e) {
+                    // do nothing.
+                }
+                if (sSignaled) {
+                    return;
+                }
+                if (remaining <= 0) {
+                    // Timed out
+                    throw new RuntimeException("Timeout during waiting");
+                }
+            }
+        } finally {
+            sLock.unlock();
+        }
+    }
+
+    public static void unblock() {
+        sLock.lock();
+        try {
+            sSignaled = true;
+            sCond.signal();
+        } finally {
+            sLock.unlock();
+        }
+    }
+
+    final static String[] FONT_FILES = {
+        "samplefont1.ttf",
+    };
+    private static final int NO_FILE_ID = 255;
+    private static final int SAMPLE_FONT_FILE_0_ID = 0;
+
+    static class Font {
+        public Font(int id, int fileId, int ttcIndex, String varSettings, int weight, int italic,
+                int resultCode) {
+            mId = id;
+            mFileId = fileId;
+            mTtcIndex = ttcIndex;
+            mVarSettings = varSettings;
+            mWeight = weight;
+            mItalic = italic;
+            mResultCode = resultCode;
+        }
+
+        public int getId() {
+            return mId;
+        }
+
+        public int getTtcIndex() {
+            return mTtcIndex;
+        }
+
+        public String getVarSettings() {
+            return mVarSettings;
+        }
+
+        public int getWeight() {
+            return mWeight;
+        }
+
+        public int getItalic() {
+            return mItalic;
+        }
+
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        public int getFileId() {
+            return mFileId;
+        }
+
+        private int mId;
+        private int mFileId;
+        private int mTtcIndex;
+        private String mVarSettings;
+        private int mWeight;
+        private int mItalic;
+        private int mResultCode;
+    };
+
+    public static final String BLOCKING_QUERY = "queryBlockingQuery";
+    public static final String NULL_FD_QUERY = "nullFdQuery";
+
+    private static Map<String, Font[]> QUERY_MAP;
+    static {
+        HashMap<String, Font[]> map = new HashMap<>();
+        int id = 0;
+
+        map.put("singleFontFamily", new Font[] {
+            new Font(id++, SAMPLE_FONT_FILE_0_ID, 0, null, 400, 0, Columns.RESULT_CODE_OK),
+        });
+
+        map.put("singleFontFamily2", new Font[] {
+            new Font(id++, SAMPLE_FONT_FILE_0_ID, 0, null, 700, 0, Columns.RESULT_CODE_OK),
+        });
+
+        map.put(BLOCKING_QUERY, new Font[] {
+            new Font(id++, SAMPLE_FONT_FILE_0_ID, 0, null, 700, 0, Columns.RESULT_CODE_OK),
+        });
+
+        map.put(NULL_FD_QUERY, new Font[] {
+            new Font(id++, NO_FILE_ID, 0, null, 700, 0, Columns.RESULT_CODE_OK),
+        });
+
+        QUERY_MAP = Collections.unmodifiableMap(map);
+    }
+
+    private static Cursor buildCursor(Font[] in) {
+        MatrixCursor cursor = new MatrixCursor(new String[] {
+                Columns._ID, Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.WEIGHT,
+                Columns.ITALIC, Columns.RESULT_CODE, Columns.FILE_ID});
+        for (Font font : in) {
+            MatrixCursor.RowBuilder builder = cursor.newRow();
+            builder.add(Columns._ID, font.getId());
+            builder.add(Columns.FILE_ID, font.getFileId());
+            builder.add(Columns.TTC_INDEX, font.getTtcIndex());
+            builder.add(Columns.VARIATION_SETTINGS, font.getVarSettings());
+            builder.add(Columns.WEIGHT, font.getWeight());
+            builder.add(Columns.ITALIC, font.getItalic());
+            builder.add(Columns.RESULT_CODE, font.getResultCode());
+        }
+        return cursor;
+    }
+
+    public MockFontProvider() {
+    }
+
+    public static void prepareFontFiles(Context context) {
+        final AssetManager mgr = context.getAssets();
+        for (String file : FONT_FILES) {
+            try (InputStream is = mgr.open("fonts/" + file)) {
+                Files.copy(is, getCopiedFile(context, file).toPath(),
+                        StandardCopyOption.REPLACE_EXISTING);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public static void cleanUpFontFiles(Context context) {
+        for (String file : FONT_FILES) {
+            getCopiedFile(context, file).delete();
+        }
+    }
+
+    public static File getCopiedFile(Context context, String path) {
+        return new File(context.getFilesDir(), path);
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) {
+        final int id = (int)ContentUris.parseId(uri);
+        if (id == NO_FILE_ID) {
+            return null;
+        }
+        final File targetFile = getCopiedFile(getContext(), FONT_FILES[id]);
+        try {
+            return ParcelFileDescriptor.open(targetFile, ParcelFileDescriptor.MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return "vnd.android.cursor.dir/vnd.android.provider.font";
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final String query = selectionArgs[0];
+        if (query.equals(BLOCKING_QUERY)) {
+            blockUntilSignal();
+        }
+        return buildCursor(QUERY_MAP.get(query));
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException("insert is not supported.");
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("delete is not supported.");
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("update is not supported.");
+    }
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d7887d3..ad4afae 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -37,7 +37,8 @@
 
 /** Tests that ensure appropriate settings are backed up. */
 @RunWith(AndroidJUnit4.class)
-@Presubmit
+// TODO(b/37684646): Can re-enable pre-submit once test is fixed.
+//@Presubmit
 @SmallTest
 public class SettingsBackupTest {
 
@@ -72,6 +73,8 @@
                     Settings.System.USER_ROTATION, // backup candidate?
                     Settings.System.VIBRATE_IN_SILENT, // deprecated?
                     Settings.System.VIBRATE_ON, // candidate for backup?
+                    Settings.System.VOLUME_ACCESSIBILITY, // used internally, changing value will
+                                                          // not change volume
                     Settings.System.VOLUME_ALARM, // deprecated since API 2?
                     Settings.System.VOLUME_BLUETOOTH_SCO, // deprecated since API 2?
                     Settings.System.VOLUME_MASTER, // candidate for backup?
@@ -121,6 +124,7 @@
                     Settings.Global.CAPTIVE_PORTAL_HTTPS_URL,
                     Settings.Global.CAPTIVE_PORTAL_HTTP_URL,
                     Settings.Global.CAPTIVE_PORTAL_MODE,
+                    Settings.Global.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS,
                     Settings.Global.CAPTIVE_PORTAL_SERVER,
                     Settings.Global.CAPTIVE_PORTAL_USE_HTTPS,
                     Settings.Global.CAPTIVE_PORTAL_USER_AGENT,
@@ -207,6 +211,8 @@
                     Settings.Global.INTENT_FIREWALL_UPDATE_CONTENT_URL,
                     Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL,
                     Settings.Global.JOB_SCHEDULER_CONSTANTS,
+                    Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
+                    Settings.Global.LANG_ID_UPDATE_METADATA_URL,
                     Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
                     Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
                     Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
@@ -300,6 +306,8 @@
                     Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL,
                     Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
+                    Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
+                    Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
                     Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
                     Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
                     Settings.Global.SMS_SHORT_CODE_CONFIRMATION,
@@ -376,7 +384,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,
@@ -387,7 +394,6 @@
                  Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
                  Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
                  Settings.Secure.ASSIST_STRUCTURE_ENABLED,
-                 Settings.Secure.AUTOFILL_SERVICE,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
                  Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
diff --git a/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/Color.java b/graphics/java/android/graphics/Color.java
index 8cbf921..bdd828f 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -24,7 +24,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
-
+import android.annotation.SuppressAutoDoc;
 import android.util.Half;
 import com.android.internal.util.XmlUtils;
 
@@ -289,6 +289,7 @@
  * and <code>(1.0, 0.0, 0.0, 0.5)</code>.</p>
  */
 @AnyThread
+@SuppressAutoDoc
 public class Color {
     @ColorInt public static final int BLACK       = 0xFF000000;
     @ColorInt public static final int DKGRAY      = 0xFF444444;
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index f2957a3..5814df5 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -22,6 +22,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.annotation.SuppressAutoDoc;
 import android.util.Pair;
 
 import java.util.ArrayList;
@@ -131,6 +132,7 @@
  */
 @AnyThread
 @SuppressWarnings("StaticInitializerReferencesSubClass")
+@SuppressAutoDoc
 public abstract class ColorSpace {
     /**
      * Standard CIE 1931 2° illuminant A, encoded in xyY.
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 90bdd81..24fb673 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -107,7 +107,7 @@
      *
      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
      *
-     * @throws Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
+     * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(int texName) {
         this(texName, false);
@@ -128,7 +128,7 @@
      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
      * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
      *
-     * @throws Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
+     * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(int texName, boolean singleBufferMode) {
         mCreatorLooper = Looper.myLooper();
@@ -155,7 +155,7 @@
      *
      * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
      *
-     * @throws Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
+     * @throws android.view.Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(boolean singleBufferMode) {
         mCreatorLooper = Looper.myLooper();
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 115c77f..60b1542 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.getFontSync(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/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index 283a3e2..ffadad9 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -16,8 +16,6 @@
 
 package android.graphics.drawable;
 
-import static android.graphics.drawable.Drawable.obtainAttributes;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -218,14 +216,16 @@
 
         // The density may have changed since the last update. This will
         // apply scaling to any existing constant state properties.
-        final int density = Drawable.resolveDensity(r, 0);
-        state.setDensity(density);
+        final int deviceDensity = Drawable.resolveDensity(r, 0);
+        state.setDensity(deviceDensity);
+        state.mSrcDensityOverride = mSrcDensityOverride;
 
         final ChildDrawable[] array = state.mChildren;
         for (int i = 0; i < state.mChildren.length; i++) {
             final ChildDrawable layer = array[i];
-            layer.setDensity(density);
+            layer.setDensity(deviceDensity);
         }
+
         inflateLayers(r, parser, attrs, theme);
     }
 
@@ -444,7 +444,7 @@
     /**
      * Inflates child layers using the specified parser.
      */
-    void inflateLayers(@NonNull Resources r, @NonNull XmlPullParser parser,
+    private void inflateLayers(@NonNull Resources r, @NonNull XmlPullParser parser,
             @NonNull AttributeSet attrs, @Nullable Theme theme)
             throws XmlPullParserException, IOException {
         final LayerState state = mLayerState;
@@ -491,7 +491,8 @@
                 }
 
                 // We found a child drawable. Take ownership.
-                layer.mDrawable = Drawable.createFromXmlInner(r, parser, attrs, theme);
+                layer.mDrawable = Drawable.createFromXmlInnerForDensity(r, parser, attrs,
+                        mLayerState.mSrcDensityOverride, theme);
                 layer.mDrawable.setCallback(this);
                 state.mChildrenChangingConfigurations |=
                         layer.mDrawable.getChangingConfigurations();
@@ -509,7 +510,8 @@
         // Extract the theme attributes, if any.
         layer.mThemeAttrs = a.extractThemeAttrs();
 
-        Drawable dr = a.getDrawable(R.styleable.AdaptiveIconDrawableLayer_drawable);
+        Drawable dr = a.getDrawableForDensity(R.styleable.AdaptiveIconDrawableLayer_drawable,
+                state.mSrcDensityOverride);
         if (dr != null) {
             if (layer.mDrawable != null) {
                 // It's possible that a drawable was already set, in which case
@@ -951,7 +953,13 @@
         final static int N_CHILDREN = 2;
         ChildDrawable[] mChildren;
 
+        // The density at which to render the drawable and its children.
         int mDensity;
+
+        // The density to use when inflating/looking up the children drawables. A value of 0 means
+        // use the system's density.
+        int mSrcDensityOverride = 0;
+
         int mOpacityOverride = PixelFormat.UNKNOWN;
 
         @Config int mChangingConfigurations;
@@ -986,6 +994,7 @@
                 mAutoMirrored = orig.mAutoMirrored;
                 mThemeAttrs = orig.mThemeAttrs;
                 mOpacityOverride = orig.mOpacityOverride;
+                mSrcDensityOverride = orig.mSrcDensityOverride;
             } else {
                 for (int i = 0; i < N_CHILDREN; i++) {
                     mChildren[i] = new ChildDrawable(mDensity);
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 5004667..e3740e3 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -41,6 +41,7 @@
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.LayoutDirection;
+import android.util.TypedValue;
 import android.view.Gravity;
 
 import com.android.internal.R;
@@ -49,6 +50,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 /**
  * A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a
@@ -749,7 +751,7 @@
         super.inflate(r, parser, attrs, theme);
 
         final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.BitmapDrawable);
-        updateStateFromTypedArray(a);
+        updateStateFromTypedArray(a, mSrcDensityOverride);
         verifyRequiredAttributes(a);
         a.recycle();
 
@@ -775,7 +777,8 @@
     /**
      * Updates the constant state from the values in the typed array.
      */
-    private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
+    private void updateStateFromTypedArray(TypedArray a, int srcDensityOverride)
+            throws XmlPullParserException {
         final Resources r = a.getResources();
         final BitmapState state = mBitmapState;
 
@@ -785,9 +788,37 @@
         // Extract the theme attributes, if any.
         state.mThemeAttrs = a.extractThemeAttrs();
 
+        state.mSrcDensityOverride = srcDensityOverride;
+
+        state.mTargetDensity = Drawable.resolveDensity(r, 0);
+
         final int srcResId = a.getResourceId(R.styleable.BitmapDrawable_src, 0);
         if (srcResId != 0) {
-            final Bitmap bitmap = BitmapFactory.decodeResource(r, srcResId);
+            final TypedValue value = new TypedValue();
+            r.getValueForDensity(srcResId, srcDensityOverride, value, true);
+
+            // Pretend the requested density is actually the display density. If
+            // the drawable returned is not the requested density, then force it
+            // to be scaled later by dividing its density by the ratio of
+            // requested density to actual device density. Drawables that have
+            // undefined density or no density don't need to be handled here.
+            if (srcDensityOverride > 0 && value.density > 0
+                    && value.density != TypedValue.DENSITY_NONE) {
+                if (value.density == srcDensityOverride) {
+                    value.density = r.getDisplayMetrics().densityDpi;
+                } else {
+                    value.density =
+                            (value.density * r.getDisplayMetrics().densityDpi) / srcDensityOverride;
+                }
+            }
+
+            Bitmap bitmap = null;
+            try (InputStream is = r.openRawResource(srcResId, value)) {
+                bitmap = BitmapFactory.decodeResourceStream(r, value, is, null, null);
+            } catch (Exception e) {
+                // Do nothing and pick up the error below.
+            }
+
             if (bitmap == null) {
                 throw new XmlPullParserException(a.getPositionDescription() +
                         ": <bitmap> requires a valid 'src' attribute");
@@ -796,8 +827,6 @@
             state.mBitmap = bitmap;
         }
 
-        state.mTargetDensity = r.getDisplayMetrics().densityDpi;
-
         final boolean defMipMap = state.mBitmap != null ? state.mBitmap.hasMipMap() : false;
         setMipMap(a.getBoolean(R.styleable.BitmapDrawable_mipMap, defMipMap));
 
@@ -839,8 +868,6 @@
         if (tileModeY != TILE_MODE_UNDEFINED) {
             setTileModeY(parseTileMode(tileModeY));
         }
-
-        state.mTargetDensity = Drawable.resolveDensity(r, 0);
     }
 
     @Override
@@ -855,7 +882,7 @@
         if (state.mThemeAttrs != null) {
             final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.BitmapDrawable);
             try {
-                updateStateFromTypedArray(a);
+                updateStateFromTypedArray(a, state.mSrcDensityOverride);
             } catch (XmlPullParserException e) {
                 rethrowAsRuntimeException(e);
             } finally {
@@ -929,7 +956,14 @@
         float mBaseAlpha = 1.0f;
         Shader.TileMode mTileModeX = null;
         Shader.TileMode mTileModeY = null;
+
+        // The density to use when looking up the bitmap in Resources. A value of 0 means use
+        // the system's density.
+        int mSrcDensityOverride = 0;
+
+        // The density at which to render the bitmap.
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+
         boolean mAutoMirrored = false;
 
         @Config int mChangingConfigurations;
@@ -949,6 +983,7 @@
             mGravity = bitmapState.mGravity;
             mTileModeX = bitmapState.mTileModeX;
             mTileModeY = bitmapState.mTileModeY;
+            mSrcDensityOverride = bitmapState.mSrcDensityOverride;
             mTargetDensity = bitmapState.mTargetDensity;
             mBaseAlpha = bitmapState.mBaseAlpha;
             mPaint = new Paint(bitmapState.mPaint);
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 559e3d3..9ae747d 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -18,6 +18,8 @@
 
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.content.pm.ActivityInfo.Config;
 import android.graphics.*;
 import android.graphics.PorterDuff.Mode;
@@ -213,6 +215,25 @@
         return mColorState.mTint != null && mColorState.mTint.hasFocusStateSpecified();
     }
 
+    /**
+     * @hide
+     * @param mode new transfer mode
+     */
+    @Override
+    public void setXfermode(@Nullable Xfermode mode) {
+        mPaint.setXfermode(mode);
+        invalidateSelf();
+    }
+
+    /**
+     * @hide
+     * @return current transfer mode
+     */
+    @TestApi
+    public Xfermode getXfermode() {
+        return mPaint.getXfermode();
+    }
+
     @Override
     public int getOpacity() {
         if (mTintFilter != null || mPaint.getColorFilter() != null) {
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 44fb1c7..f17cd76 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -189,6 +189,21 @@
     private int mLayoutDirection;
 
     /**
+     * The source density to use when looking up resources using
+     * {@link Resources#getDrawableForDensity(int, int, Theme)}. A value of 0 means there is no
+     * override and the system density will be used.
+     *
+     * NOTE(adamlesinski): This is transient state used to get around the public API that does not
+     * account for source density overrides. Custom drawables implemented by developers do not need
+     * to be aware of the source density override, as it is only used by Launcher to load higher
+     * resolution icons from external Resources packages, which do not execute custom code.
+     * This is all to support the {@link Resources#getDrawableForDensity(int, int, Theme)} API.
+     *
+     * @hide
+     */
+    protected int mSrcDensityOverride = 0;
+
+    /**
      * Draw in its bounds (set via setBounds) respecting optional effects such
      * as alpha (set via setAlpha) and color filter (set via setColorFilter).
      *
@@ -1197,7 +1212,8 @@
      * create resources in XML, see
      * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
      */
-    public static Drawable createFromXml(Resources r, XmlPullParser parser)
+    @NonNull
+    public static Drawable createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser)
             throws XmlPullParserException, IOException {
         return createFromXml(r, parser, null);
     }
@@ -1207,7 +1223,20 @@
      * For more information on how to create resources in XML, see
      * <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
      */
-    public static Drawable createFromXml(Resources r, XmlPullParser parser, Theme theme)
+    @NonNull
+    public static Drawable createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser,
+            @Nullable Theme theme) throws XmlPullParserException, IOException {
+        return createFromXmlForDensity(r, parser, 0, theme);
+    }
+
+    /**
+     * Version of {@link #createFromXml(Resources, XmlPullParser, Theme)} that accepts a density
+     * override.
+     * @hide
+     */
+    @NonNull
+    public static Drawable createFromXmlForDensity(@NonNull Resources r,
+            @NonNull XmlPullParser parser, int density, @Nullable Theme theme)
             throws XmlPullParserException, IOException {
         AttributeSet attrs = Xml.asAttributeSet(parser);
 
@@ -1222,7 +1251,7 @@
             throw new XmlPullParserException("No start tag found");
         }
 
-        Drawable drawable = createFromXmlInner(r, parser, attrs, theme);
+        Drawable drawable = createFromXmlInnerForDensity(r, parser, attrs, density, theme);
 
         if (drawable == null) {
             throw new RuntimeException("Unknown initial tag: " + parser.getName());
@@ -1236,8 +1265,9 @@
      * a tag in an XML document, tries to create a Drawable from that tag.
      * Returns null if the tag is not a valid drawable.
      */
-    public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
+    @NonNull
+    public static Drawable createFromXmlInner(@NonNull Resources r, @NonNull XmlPullParser parser,
+            @NonNull AttributeSet attrs) throws XmlPullParserException, IOException {
         return createFromXmlInner(r, parser, attrs, null);
     }
 
@@ -1247,14 +1277,29 @@
      * document, tries to create a Drawable from that tag. Returns {@code null}
      * if the tag is not a valid drawable.
      */
-    public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs,
-            Theme theme) throws XmlPullParserException, IOException {
-        return r.getDrawableInflater().inflateFromXml(parser.getName(), parser, attrs, theme);
+    @NonNull
+    public static Drawable createFromXmlInner(@NonNull Resources r, @NonNull XmlPullParser parser,
+            @NonNull AttributeSet attrs, @Nullable Theme theme)
+            throws XmlPullParserException, IOException {
+        return createFromXmlInnerForDensity(r, parser, attrs, 0, theme);
+    }
+
+    /**
+     * Version of {@link #createFromXmlInner(Resources, XmlPullParser, AttributeSet, Theme)} that
+     * accepts an override density.
+     */
+    @NonNull
+    static Drawable createFromXmlInnerForDensity(@NonNull Resources r,
+            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, int density,
+            @Nullable Theme theme) throws XmlPullParserException, IOException {
+        return r.getDrawableInflater().inflateFromXmlForDensity(parser.getName(), parser, attrs,
+                density, theme);
     }
 
     /**
      * Create a drawable from file path name.
      */
+    @Nullable
     public static Drawable createFromPath(String pathName) {
         if (pathName == null) {
             return null;
@@ -1316,6 +1361,16 @@
     }
 
     /**
+     * Sets the source override density for this Drawable. If non-zero, this density is to be used
+     * for any calls to {@link Resources#getDrawableForDensity(int, int, Theme)} or
+     * {@link Resources#getValueForDensity(int, int, TypedValue, boolean)}.
+     * @hide
+     */
+    final void setSrcDensityOverride(int density) {
+        mSrcDensityOverride = density;
+    }
+
+    /**
      * This abstract class is used by {@link Drawable}s to store shared constant state and data
      * between Drawables. {@link BitmapDrawable}s created from the same resource will for instance
      * share a unique bitmap stored in their ConstantState.
diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java
index 3404d8c..eea7048 100644
--- a/graphics/java/android/graphics/drawable/DrawableInflater.java
+++ b/graphics/java/android/graphics/drawable/DrawableInflater.java
@@ -112,6 +112,17 @@
     public Drawable inflateFromXml(@NonNull String name, @NonNull XmlPullParser parser,
             @NonNull AttributeSet attrs, @Nullable Theme theme)
             throws XmlPullParserException, IOException {
+        return inflateFromXmlForDensity(name, parser, attrs, 0, theme);
+    }
+
+    /**
+     * Version of {@link #inflateFromXml(String, XmlPullParser, AttributeSet, Theme)} that accepts
+     * an override density.
+     */
+    @NonNull
+    Drawable inflateFromXmlForDensity(@NonNull String name, @NonNull XmlPullParser parser,
+            @NonNull AttributeSet attrs, int density, @Nullable Theme theme)
+            throws XmlPullParserException, IOException {
         // Inner classes must be referenced as Outer$Inner, but XML tag names
         // can't contain $, so the <drawable> tag allows developers to specify
         // the class in an attribute. We'll still run it through inflateFromTag
@@ -127,6 +138,7 @@
         if (drawable == null) {
             drawable = inflateFromClass(name);
         }
+        drawable.setSrcDensityOverride(density);
         drawable.inflate(mRes, parser, attrs, theme);
         return drawable;
     }
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 431b63b..cf821bb 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -131,6 +131,7 @@
         final int densityDpi = r.getDisplayMetrics().densityDpi;
         final int targetDensity = densityDpi == 0 ? DisplayMetrics.DENSITY_DEFAULT : densityDpi;
         state.setDensity(targetDensity);
+        state.mSrcDensityOverride = mSrcDensityOverride;
 
         final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.DrawableWrapper);
         updateStateFromTypedArray(a);
@@ -437,7 +438,8 @@
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
             if (type == XmlPullParser.START_TAG) {
-                dr = Drawable.createFromXmlInner(r, parser, attrs, theme);
+                dr = Drawable.createFromXmlInnerForDensity(r, parser, attrs,
+                        mState.mSrcDensityOverride, theme);
             }
         }
 
@@ -452,6 +454,14 @@
         @Config int mChangingConfigurations;
         int mDensity = DisplayMetrics.DENSITY_DEFAULT;
 
+        /**
+         * The density to use when looking up resources from
+         * {@link Resources#getDrawableForDensity(int, int, Theme)}.
+         * A value of 0 means there is no override and the system density will be used.
+         * @hide
+         */
+        int mSrcDensityOverride = 0;
+
         Drawable.ConstantState mDrawableState;
 
         DrawableWrapperState(@Nullable DrawableWrapperState orig, @Nullable Resources res) {
@@ -459,6 +469,7 @@
                 mThemeAttrs = orig.mThemeAttrs;
                 mChangingConfigurations = orig.mChangingConfigurations;
                 mDrawableState = orig.mDrawableState;
+                mSrcDensityOverride = orig.mSrcDensityOverride;
             }
 
             final int density;
diff --git a/graphics/java/android/graphics/fonts/FontRequest.java b/graphics/java/android/graphics/fonts/FontRequest.java
index c7a5830..df3951c 100644
--- a/graphics/java/android/graphics/fonts/FontRequest.java
+++ b/graphics/java/android/graphics/fonts/FontRequest.java
@@ -35,6 +35,9 @@
     private final String mQuery;
     private final List<List<byte[]>> mCertificates;
 
+    // Used for key of the cache.
+    private final String mIdentifier;
+
     /**
      * @param providerAuthority The authority of the Font Provider to be used for the request. This
      *         should be a system installed app.
@@ -49,6 +52,8 @@
         mQuery = Preconditions.checkNotNull(query);
         mProviderPackage = Preconditions.checkNotNull(providerPackage);
         mCertificates = Collections.emptyList();
+        mIdentifier = new StringBuilder(mProviderAuthority).append("-").append(mProviderPackage)
+                .append("-").append(mQuery).toString();
     }
 
     /**
@@ -68,6 +73,8 @@
         mProviderPackage = Preconditions.checkNotNull(providerPackage);
         mQuery = Preconditions.checkNotNull(query);
         mCertificates = Preconditions.checkNotNull(certificates);
+        mIdentifier = new StringBuilder(mProviderAuthority).append("-").append(mProviderPackage)
+                .append("-").append(mQuery).toString();
     }
 
     /**
@@ -102,6 +109,11 @@
         return mCertificates;
     }
 
+    /** @hide */
+    public String getIdentifier() {
+        return mIdentifier;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -121,6 +133,8 @@
         mQuery = in.readString();
         mCertificates = new ArrayList<>();
         in.readList(mCertificates, null);
+        mIdentifier = new StringBuilder(mProviderAuthority).append("-").append(mProviderPackage)
+                .append("-").append(mQuery).toString();
     }
 
     public static final Parcelable.Creator<FontRequest> CREATOR =
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/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index 2ec8d33..0f98392 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -95,9 +95,6 @@
      * For privacy reasons, you cannot distinguish between (1) and (2). If attestation is
      * unsuccessful, the device may not support it in general or the user may have permanently
      * disabled it.
-     * <p>
-     * The caller must hold {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
-     * permission.
      *
      * @param context the context to use for retrieving device identifiers.
      * @param idTypes the types of device identifiers to attest.
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/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 052c018..55b74ed 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -28,6 +28,7 @@
 #include <ui/ColorSpace.h>
 
 #include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <SkBitmap.h>
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index 60dbe00..6d9c5e2 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -33,6 +33,7 @@
     private final int mClientUid;
     private final String mClientId;
     private final String mPackageName;
+    private final int mSdkTarget;
     private int mGainRequest;
     private int mLossReceived;
     private int mFlags;
@@ -49,7 +50,7 @@
      * @hide
      */
     public AudioFocusInfo(AudioAttributes aa, int clientUid, String clientId, String packageName,
-            int gainRequest, int lossReceived, int flags) {
+            int gainRequest, int lossReceived, int flags, int sdk) {
         mAttributes = aa == null ? new AudioAttributes.Builder().build() : aa;
         mClientUid = clientUid;
         mClientId = clientId == null ? "" : clientId;
@@ -57,6 +58,7 @@
         mGainRequest = gainRequest;
         mLossReceived = lossReceived;
         mFlags = flags;
+        mSdkTarget = sdk;
     }
 
 
@@ -97,6 +99,9 @@
     public int getLossReceived() { return mLossReceived; }
 
     /** @hide */
+    public int getSdkTarget() { return mSdkTarget; }
+
+    /** @hide */
     public void clearLossReceived() { mLossReceived = 0; }
 
     /**
@@ -122,6 +127,7 @@
         dest.writeInt(mGainRequest);
         dest.writeInt(mLossReceived);
         dest.writeInt(mFlags);
+        dest.writeInt(mSdkTarget);
     }
 
     @SystemApi
@@ -161,6 +167,9 @@
         if (mFlags != other.mFlags) {
             return false;
         }
+        if (mSdkTarget != other.mSdkTarget) {
+            return false;
+        }
         return true;
     }
 
@@ -175,7 +184,8 @@
                     in.readString(), //String packageName
                     in.readInt(), //int gainRequest
                     in.readInt(), //int lossReceived
-                    in.readInt() //int flags
+                    in.readInt(), //int flags
+                    in.readInt()  //int sdkTarget
                     );
         }
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 4adbf79..ce07c99 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -34,6 +34,7 @@
 import android.media.session.MediaSessionLegacyHelper;
 import android.media.session.MediaSessionManager;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -2483,13 +2484,21 @@
         registerAudioFocusRequest(afr);
         final IAudioService service = getService();
         final int status;
+        int sdk;
+        try {
+            sdk = getContext().getApplicationInfo().targetSdkVersion;
+        } catch (NullPointerException e) {
+            // some tests don't have a Context
+            sdk = Build.VERSION.SDK_INT;
+        }
         try {
             status = service.requestAudioFocus(afr.getAudioAttributes(),
                     afr.getFocusGain(), mICallBack,
                     mAudioFocusDispatcher,
                     getIdForAudioFocusListener(afr.getOnAudioFocusChangeListener()),
                     getContext().getOpPackageName() /* package name */, afr.getFlags(),
-                    ap != null ? ap.cb() : null);
+                    ap != null ? ap.cb() : null,
+                    sdk);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2515,7 +2524,7 @@
                     AudioSystem.IN_VOICE_COMM_FOCUS_ID,
                     getContext().getOpPackageName(),
                     AUDIOFOCUS_FLAG_LOCK,
-                    null /* policy token */);
+                    null /* policy token */, 0 /* sdk n/a here*/);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 884d41e..9c138e3 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -121,7 +121,7 @@
 
     int requestAudioFocus(in AudioAttributes aa, int durationHint, IBinder cb,
             IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
-            IAudioPolicyCallback pcb);
+            IAudioPolicyCallback pcb, int sdk);
 
     int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, in AudioAttributes aa,
             in String callingPackageName);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 293ceea..5cbccea 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -140,7 +140,7 @@
  *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
  *         {@link #setLooping(boolean)},
  *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
- *         {@link #stop()}, {@link #seekTo(int, int)}, {@link #prepare()} or
+ *         {@link #stop()}, {@link #seekTo(long, int)}, {@link #prepare()} or
  *         {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
  *         methods is called right after a MediaPlayer object is constructed,
  *         the user supplied callback method OnErrorListener.onError() won't be
@@ -286,9 +286,9 @@
  *         </ul>
  *         </li>
  *     <li>The playback position can be adjusted with a call to
- *         {@link #seekTo(int, int)}.
+ *         {@link #seekTo(long, int)}.
  *         <ul>
- *         <li>Although the asynchronuous {@link #seekTo(int, int)}
+ *         <li>Although the asynchronuous {@link #seekTo(long, int)}
  *         call returns right away, the actual seek operation may take a while to
  *         finish, especially for audio/video being streamed. When the actual
  *         seek operation completes, the internal player engine calls a user
@@ -296,9 +296,9 @@
  *         has been registered beforehand via
  *         {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
  *         <li>Please
- *         note that {@link #seekTo(int, int)} can also be called in the other states,
+ *         note that {@link #seekTo(long, int)} can also be called in the other states,
  *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
- *         </em> state. When {@link #seekTo(int, int)} is called in those states,
+ *         </em> state. When {@link #seekTo(long, int)} is called in those states,
  *         one video frame will be displayed if the stream has video and the requested
  *         position is valid.
  *         </li>
@@ -1704,42 +1704,42 @@
     public native SyncParams getSyncParams();
 
     /**
-     * Seek modes used in method seekTo(int, int) to move media position
+     * Seek modes used in method seekTo(long, int) to move media position
      * to a specified location.
      *
      * Do not change these mode values without updating their counterparts
      * in include/media/IMediaSource.h!
      */
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * right before or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_PREVIOUS_SYNC    = 0x00;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * right after or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_NEXT_SYNC        = 0x01;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a sync (or key) frame associated with a data source that is located
      * closest to (in time) or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_CLOSEST_SYNC     = 0x02;
     /**
-     * This mode is used with {@link #seekTo(int, int)} to move media position to
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
      * a frame (not necessarily a key frame) associated with a data source that
      * is located closest to or at the given time.
      *
-     * @see #seekTo(int, int)
+     * @see #seekTo(long, int)
      */
     public static final int SEEK_CLOSEST          = 0x03;
 
@@ -1754,7 +1754,7 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SeekMode {}
 
-    private native final void _seekTo(int msec, int mode);
+    private native final void _seekTo(long msec, int mode);
 
     /**
      * Moves the media to specified time position by considering the given mode.
@@ -1786,17 +1786,25 @@
      * initialized
      * @throws IllegalArgumentException if the mode is invalid.
      */
-    public void seekTo(int msec, @SeekMode int mode) throws IllegalStateException {
+    public void seekTo(long msec, @SeekMode int mode) {
         if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
             final String msg = "Illegal seek mode: " + mode;
             throw new IllegalArgumentException(msg);
         }
+        // TODO: pass long to native, instead of truncating here.
+        if (msec > Integer.MAX_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE);
+            msec = Integer.MAX_VALUE;
+        } else if (msec < Integer.MIN_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE);
+            msec = Integer.MIN_VALUE;
+        }
         _seekTo(msec, mode);
     }
 
     /**
      * Seeks to specified time position.
-     * Same as {@link #seekTo(int, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
+     * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
      *
      * @param msec the offset in milliseconds from the start to seek to
      * @throws IllegalStateException if the internal player engine has not been
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..6f4118e 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";
 
@@ -1480,8 +1488,7 @@
         /**
          * The URI for the preview video.
          *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}. The data in the column must be
-         * a URL, or a URI in one of the following formats:
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
          *
          * <ul>
          * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
@@ -1497,9 +1504,8 @@
         String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
 
         /**
-         * The last playback position (in milliseconds) of the preview video.
-         *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         * The last playback position (in milliseconds) of the original content of this preview
+         * program.
          *
          * <p>Can be empty.
          *
@@ -1509,9 +1515,7 @@
                 "last_playback_position_millis";
 
         /**
-         * The duration (in milliseconds) of the preview video.
-         *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         * The duration (in milliseconds) of the original content of this preview program.
          *
          * <p>Can be empty.
          *
@@ -2741,8 +2745,6 @@
          *
          * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
          *
-         * <p>This is a required field.
-         *
          * <p>Type: INTEGER (long)
          */
         public static final String COLUMN_CHANNEL_ID = "channel_id";
@@ -2989,6 +2991,8 @@
          */
         public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS =
                 "last_engagement_time_utc_millis";
+
+        private WatchNextPrograms() {}
     }
 
     /**
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 2fc4afd..3711462 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -662,15 +662,15 @@
 }
 
 static void
-android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec, jint mode)
+android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jlong msec, jint mode)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    ALOGV("seekTo: %d(msec), mode=%d", msec, mode);
-    process_media_player_call( env, thiz, mp->seekTo(msec, (MediaPlayerSeekMode)mode), NULL, NULL );
+    ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
+    process_media_player_call( env, thiz, mp->seekTo((int)msec, (MediaPlayerSeekMode)mode), NULL, NULL );
 }
 
 static jint
@@ -1398,7 +1398,7 @@
     {"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer_getPlaybackParams},
     {"setSyncParams",     "(Landroid/media/SyncParams;)V",  (void *)android_media_MediaPlayer_setSyncParams},
     {"getSyncParams",     "()Landroid/media/SyncParams;",   (void *)android_media_MediaPlayer_getSyncParams},
-    {"_seekTo",             "(II)V",                            (void *)android_media_MediaPlayer_seekTo},
+    {"_seekTo",             "(JI)V",                            (void *)android_media_MediaPlayer_seekTo},
     {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},
     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},
     {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
index 9e50490..4361b96 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -25,6 +25,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -42,7 +43,9 @@
 import java.io.OutputStream;
 import java.io.Writer;
 import java.io.FileOutputStream;
+import java.util.HashSet;
 import java.util.Random;
+import java.util.Set;
 /**
  * Junit / Instrumentation test case for the media player api
 
@@ -69,6 +72,7 @@
     public static int mMediaInfoBadInterleavingCount = 0;
     public static int mMediaInfoNotSeekableCount = 0;
     public static int mMediaInfoMetdataUpdateCount = 0;
+    private static Set<String> mSupportedTypes = new HashSet<>();
 
     public static String printCpuInfo(){
         String cm = "dumpsys cpuinfo";
@@ -789,11 +793,12 @@
     };
 
     public static boolean playMediaSamples(String filePath) throws Exception {
-        return playMediaSamples(filePath, 2000);
+        return playMediaSamples(filePath, 2000, false /* streamingTest */);
     }
 
-    // For each media file, forward twice and backward once, then play to the end
-    public static boolean playMediaSamples(String filePath, int buffertime) throws Exception {
+    // For each media file, just play to the end
+    public static boolean playMediaSamples(String filePath, int buffertime, boolean streamingTest)
+            throws Exception {
         int duration = 0;
         int curPosition = 0;
         int nextPosition = 0;
@@ -808,27 +813,39 @@
         mFailedToCompleteWithNoError = true;
         String testResult;
 
-        final MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        final MediaExtractor extractor = new MediaExtractor();
         boolean hasSupportedVideo = false;
 
-        try {
-            extractor.setDataSource(filePath);
-
-            for (int index = 0; index < extractor.getTrackCount(); ++index) {
-                MediaFormat format = extractor.getTrackFormat(index);
-                String mime = format.getString(MediaFormat.KEY_MIME);
-                if (!mime.startsWith("video/")) {
-                    continue;
-                }
-
-                if (list.findDecoderForFormat(format) != null) {
-                    hasSupportedVideo = true;
-                    break;
+        if (!streamingTest) {
+            if (mSupportedTypes.isEmpty()) {
+                final MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+                for (MediaCodecInfo info : list.getCodecInfos()) {
+                    for (String type : info.getSupportedTypes()) {
+                        mSupportedTypes.add(type);
+                    }
                 }
             }
-        } finally {
-            extractor.release();
+            final MediaExtractor extractor = new MediaExtractor();
+
+            try {
+                extractor.setDataSource(filePath);
+
+                for (int index = 0; index < extractor.getTrackCount(); ++index) {
+                    MediaFormat format = extractor.getTrackFormat(index);
+                    String type = format.getString(MediaFormat.KEY_MIME);
+                    if (!type.startsWith("video/")) {
+                        continue;
+                    }
+
+                    if (mSupportedTypes.contains(type)) {
+                        hasSupportedVideo = true;
+                        break;
+                    }
+                }
+            } finally {
+                extractor.release();
+            }
+        } else { // streamingTest
+            hasSupportedVideo = true;
         }
 
         initializeMessageLooper();
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
index d92c857..6a820ec 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
@@ -144,7 +144,7 @@
                 //Get url
                 String filename = urls.get(i);
                 onCompleteSuccess =
-                    CodecTest.playMediaSamples(filename, 60000);
+                    CodecTest.playMediaSamples(filename, 60000, true /* streamingTest */);
                 if (!onCompleteSuccess){
                     //Don't fail the test right away, print out the failure file.
                     fileWithError += filename + '\n';
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 329514c..0f0a7e9d 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -1469,6 +1469,13 @@
                                     }
                                     break;
                                 }
+                            } else {
+                                if (finishDrawingRunnable != null) {
+                                    Log.w(TAG, "Warning, !readyToDraw() but waiting for " +
+                                            "draw finished! Early reporting draw finished.");
+                                    finishDrawingRunnable.run();
+                                    finishDrawingRunnable = null;
+                                }
                             }
                             // By design, this is the only place in a GLThread thread where we wait().
                             if (LOG_THREADS) {
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/PrintSpooler/res/drawable/ic_pdf_printer.xml b/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml
new file mode 100644
index 0000000..8196650
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable/ic_pdf_printer.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2017 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="36dp"
+    android:height="36dp"
+    android:viewportWidth="48.0"
+    android:viewportHeight="48.0"
+    android:tint="@color/pdf_printer_color">
+    <path
+        android:pathData="M40,4L16,4c-2.21,0 -4,1.79 -4,4v24c0,2.21 1.79,4 4,4h24c2.21,0 4,-1.79 4,-4L44,8c0,-2.21 -1.79,-4 -4,-4zM23,19c0,1.66 -1.34,3 -3,3h-2v4h-3L15,14h5c1.66,0 3,1.34 3,3v2zM33,23c0,1.66 -1.34,3 -3,3h-5L25,14h5c1.66,0 3,1.34 3,3v6zM41,17h-3v2h3v3h-3v4h-3L35,14h6v3zM18,19h2v-2h-2v2zM8,12L4,12v28c0,2.21 1.79,4 4,4h28v-4L8,40L8,12zM28,23h2v-6h-2v6z"
+        android:fillColor="@android:color/black"/>
+</vector>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml
index d83d364..a15fff5 100644
--- a/packages/PrintSpooler/res/values/colors.xml
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -24,4 +24,5 @@
 
     <color name="material_grey_500">#ffa3a3a3</color>
 
+    <color name="pdf_printer_color">#009688</color>
 </resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index ccdec62..601491a 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -2442,7 +2442,7 @@
                 if (position == 0 && getPdfPrinter() != null) {
                     PrinterHolder printerHolder = (PrinterHolder) getItem(position);
                     title = printerHolder.printer.getName();
-                    icon = getResources().getDrawable(R.drawable.ic_menu_savetopdf, null);
+                    icon = getResources().getDrawable(R.drawable.ic_pdf_printer, null);
                 } else if (position == 1) {
                     title = getMoreItemTitle();
                 }
@@ -2450,7 +2450,7 @@
                 if (position == 1 && getPdfPrinter() != null) {
                     PrinterHolder printerHolder = (PrinterHolder) getItem(position);
                     title = printerHolder.printer.getName();
-                    icon = getResources().getDrawable(R.drawable.ic_menu_savetopdf, null);
+                    icon = getResources().getDrawable(R.drawable.ic_pdf_printer, null);
                 } else if (position == getCount() - 1) {
                     title = getMoreItemTitle();
                 } else {
diff --git a/packages/SettingsLib/res/values/config.xml b/packages/SettingsLib/res/values/config.xml
deleted file mode 100755
index 64f21b5..0000000
--- a/packages/SettingsLib/res/values/config.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<resources>
-    <!-- Configuration for automotive -->
-    <bool name="enable_pbap_pce_profile">false</bool>
-
-    <!-- Default data warning level in mb -->
-    <integer name="default_data_warning_level_mb">2048</integer>
-
-    <!-- Whether to send a custom package name with the PSD.-->
-    <bool name="config_sendPackageName">false</bool>
-
-    <!-- Name for the set of keys associating package names -->
-    <string name="config_helpPackageNameKey" translatable="false"></string>
-
-    <!-- Name for the set of values of package names -->
-    <string name="config_helpPackageNameValue" translatable="false"></string>
-
-    <!-- Intent key for the package name keys -->
-    <string name="config_helpIntentExtraKey" translatable="false"></string>
-
-    <!-- Intent key for package name values -->
-    <string name="config_helpIntentNameKey" translatable="false"></string>
-
-    <!-- Intent key for the package name keys -->
-    <string name="config_feedbackIntentExtraKey" translatable="false"></string>
-
-    <!-- Intent key for package name values -->
-    <string name="config_feedbackIntentNameKey" translatable="false"></string>
-
-    <!-- The apps that need to be hided when they are disabled -->
-    <string-array name="config_hideWhenDisabled_packageNames"></string-array>
-</resources>
\ No newline at end of file
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/HelpUtils.java b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java
index 58047bb..2c26410 100644
--- a/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java
@@ -180,21 +180,24 @@
         }
 
         Resources resources = context.getResources();
-        boolean includePackageName = resources.getBoolean(R.bool.config_sendPackageName);
+        boolean includePackageName =
+                resources.getBoolean(com.android.internal.R.bool.config_sendPackageName);
 
         if (sendPackageName && includePackageName) {
             String[] packageNameKey =
-                    {resources.getString(R.string.config_helpPackageNameKey)};
+                    {resources.getString(com.android.internal.R.string.config_helpPackageNameKey)};
             String[] packageNameValue =
-                    {resources.getString(R.string.config_helpPackageNameValue)};
+                    {resources.getString(
+                            com.android.internal.R.string.config_helpPackageNameValue)};
             String helpIntentExtraKey =
-                    resources.getString(R.string.config_helpIntentExtraKey);
+                    resources.getString(com.android.internal.R.string.config_helpIntentExtraKey);
             String helpIntentNameKey =
-                    resources.getString(R.string.config_helpIntentNameKey);
+                    resources.getString(com.android.internal.R.string.config_helpIntentNameKey);
             String feedbackIntentExtraKey =
-                    resources.getString(R.string.config_feedbackIntentExtraKey);
+                    resources.getString(
+                            com.android.internal.R.string.config_feedbackIntentExtraKey);
             String feedbackIntentNameKey =
-                    resources.getString(R.string.config_feedbackIntentNameKey);
+                    resources.getString(com.android.internal.R.string.config_feedbackIntentNameKey);
             intent.putExtra(helpIntentExtraKey, packageNameKey);
             intent.putExtra(helpIntentNameKey, packageNameValue);
             intent.putExtra(feedbackIntentExtraKey, packageNameKey);
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index c109704..66dfecd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -50,8 +50,8 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
-import com.android.settingslib.R;
 
 import java.io.File;
 import java.io.IOException;
@@ -1276,8 +1276,7 @@
                     return true;
                 } else {
                     this.mounted = false;
-                    this.icon = context.getDrawable(
-                            com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
+                    this.icon = context.getDrawable(R.drawable.sym_app_on_sd_unavailable_icon);
                 }
             } else if (!this.mounted) {
                 // If the app wasn't mounted but is now mounted, reload
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 1ea592d..5a9a749 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -32,7 +32,7 @@
 import android.content.Intent;
 import android.os.ParcelUuid;
 import android.util.Log;
-import com.android.settingslib.R;
+import com.android.internal.R;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
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/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 994ea88..b69232c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -32,7 +32,7 @@
 import android.text.format.Time;
 import android.util.Log;
 
-import com.android.settingslib.R;
+import com.android.internal.R;
 
 import java.util.Date;
 import java.util.Locale;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 314791e..646b6ba 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -15,8 +15,8 @@
  */
 package com.android.settingslib.wifi;
 
+import android.annotation.MainThread;
 import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -41,6 +41,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.provider.Settings;
+import android.support.annotation.GuardedBy;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
@@ -65,8 +66,6 @@
  * Tracks saved or available wifi networks and their state.
  */
 public class WifiTracker {
-    // TODO(sghuman): Document remaining methods with @UiThread and @WorkerThread where possible.
-    // TODO(sghuman): Refactor to avoid calling certain methods on the UiThread.
     // TODO(b/36733768): Remove flag includeSaved and includePasspoints.
 
     private static final String TAG = "WifiTracker";
@@ -91,40 +90,40 @@
     private final boolean mIncludeSaved;
     private final boolean mIncludeScans;
     private final boolean mIncludePasspoints;
-    private final MainHandler mMainHandler;
+    @VisibleForTesting final MainHandler mMainHandler;
     private final WorkHandler mWorkHandler;
 
     private WifiTrackerNetworkCallback mNetworkCallback;
 
     private int mNumSavedNetworks;
+
+    @GuardedBy("mLock")
     private boolean mRegistered;
 
-    /** Updated using main handler. Clone of this collection is returned
-     * from {@link #getAccessPoints()}
+    /**
+     * The externally visible access point list.
+     *
+     * Updated using main handler. Clone of this collection is returned from
+     * {@link #getAccessPoints()}
      */
     private final List<AccessPoint> mAccessPoints = new ArrayList<>();
 
     /**
-     * Protects APs contained in {@link #mInternalAccessPoints} from being modified concurrently
-     * while its being read. Usage contract:
+     * The internal list of access points, synchronized on itself.
      *
-     * 1. MainHandler opens the condition after copying the states thereby
-     *    allowing WorkerHandler to mutate the contents.
-     * 2. WorkerHandler after mutating the contents, sends a message to MainHandler to copy the
-     *    states and closes the condition.
-     *
-     * This is better than synchronizing on a variable because it prevents MainHandler from
-     * unnecessarily blocking/waiting to acquire lock for copying states. When MainHandler is about
-     * to access {@link #mInternalAccessPoints}, it is assumed that it has exclusively lock on the
-     * contents.
-     */
-    private final ConditionVariable mInternalAccessPointsWriteLock = new ConditionVariable(true);
-
-    /** Guarded by mInternalAccessPointsWriteLock, updated using worker handler.
      * Never exposed outside this class.
      */
+    @GuardedBy("mLock")
     private final List<AccessPoint> mInternalAccessPoints = new ArrayList<>();
 
+    /**
+    * Synchronization lock for managing concurrency between main and worker threads.
+    *
+    * <p>This lock should be held for all background work.
+    * TODO(b/37674366): Remove the worker thread so synchronization is no longer necessary.
+    */
+    private final Object mLock = new Object();
+
     //visible to both worker and main thread. Guarded by #mInternalAccessPoints
     private final AccessPointListenerAdapter mAccessPointListenerAdapter
             = new AccessPointListenerAdapter();
@@ -138,10 +137,12 @@
 
     private final NetworkScoreManager mNetworkScoreManager;
     private final WifiNetworkScoreCache mScoreCache;
-    private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
     private boolean mNetworkScoringUiEnabled;
     private final ContentObserver mObserver;
 
+    @GuardedBy("mLock")
+    private final Set<NetworkKey> mRequestedScores = new ArraySet<>();
+
     @VisibleForTesting
     Scanner mScanner;
 
@@ -212,13 +213,17 @@
 
         mNetworkScoreManager = networkScoreManager;
 
-        mScoreCache = new WifiNetworkScoreCache(context, new CacheListener(mMainHandler) {
+        mScoreCache = new WifiNetworkScoreCache(context, new CacheListener(mWorkHandler) {
             @Override
             public void networkCacheUpdated(List<ScoredNetwork> networks) {
+                synchronized (mLock) {
+                    if (!mRegistered) return;
+                }
+
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.v(TAG, "Score cache was updated with networks: " + networks);
                 }
-                Message.obtain(mWorkHandler, WorkHandler.MSG_UPDATE_NETWORK_SCORES).sendToTarget();
+                updateNetworkScores();
             }
         });
 
@@ -236,17 +241,19 @@
     /**
      * Synchronously update the list of access points with the latest information.
      */
+    @MainThread
     public void forceUpdate() {
-        mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+        synchronized (mLock) {
+            mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+            mLastInfo = mWifiManager.getConnectionInfo();
+            mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
+            updateAccessPointsLocked();
 
-        mLastInfo = mWifiManager.getConnectionInfo();
-        mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
-        updateAccessPoints();
-
-        // Synchronously copy access points
-        mMainHandler.removeMessages(MainHandler.MSG_ACCESS_POINT_CHANGED);
-        mMainHandler.handleMessage(
-                Message.obtain(mMainHandler, MainHandler.MSG_ACCESS_POINT_CHANGED));
+            // Synchronously copy access points
+            mMainHandler.removeMessages(MainHandler.MSG_ACCESS_POINT_CHANGED);
+            mMainHandler.handleMessage(
+                    Message.obtain(mMainHandler, MainHandler.MSG_ACCESS_POINT_CHANGED));
+        }
     }
 
     /**
@@ -290,22 +297,25 @@
      * <p>Registers listeners and starts scanning for wifi networks. If this is not called
      * then forceUpdate() must be called to populate getAccessPoints().
      */
+    @MainThread
     public void startTracking() {
-        registerScoreCache();
+        synchronized (mLock) {
+            registerScoreCache();
 
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
-                false /* notifyForDescendants */,
-                mObserver);
-        mObserver.onChange(false /* selfChange */); // Set the initial value for mScoringUiEnabled
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.NETWORK_SCORING_UI_ENABLED),
+                    false /* notifyForDescendants */,
+                    mObserver);
+            mObserver.onChange(false /* selfChange */); // Set mScoringUiEnabled
 
-        resumeScanning();
-        if (!mRegistered) {
-            mContext.registerReceiver(mReceiver, mFilter);
-            // NetworkCallback objects cannot be reused. http://b/20701525 .
-            mNetworkCallback = new WifiTrackerNetworkCallback();
-            mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
-            mRegistered = true;
+            resumeScanning();
+            if (!mRegistered) {
+                mContext.registerReceiver(mReceiver, mFilter);
+                // NetworkCallback objects cannot be reused. http://b/20701525 .
+                mNetworkCallback = new WifiTrackerNetworkCallback();
+                mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+                mRegistered = true;
+            }
         }
     }
 
@@ -323,44 +333,49 @@
             Log.d(TAG, "Requesting scores for Network Keys: " + keys);
         }
         mNetworkScoreManager.requestScores(keys.toArray(new NetworkKey[keys.size()]));
-        mRequestedScores.addAll(keys);
+        synchronized (mLock) {
+            mRequestedScores.addAll(keys);
+        }
     }
 
     /**
      * Stop tracking wifi networks and scores.
      *
-     * <p>Unregisters all listeners and stops scanning for wifi networks. This should always
-     * be called when done with a WifiTracker (if startTracking was called) to ensure
-     * proper cleanup.
+     * <p>This should always be called when done with a WifiTracker (if startTracking was called) to
+     * ensure proper cleanup and prevent any further callbacks from occuring.
      */
+    @MainThread
     public void stopTracking() {
-        if (mRegistered) {
-            mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
-            mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_NETWORK_INFO);
-            mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_NETWORK_SCORES);
-            mContext.unregisterReceiver(mReceiver);
-            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
-            mRegistered = false;
+        synchronized (mLock) {
+            if (mRegistered) {
+                mContext.unregisterReceiver(mReceiver);
+                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+                mRegistered = false;
+            }
+            unregisterAndClearScoreCache();
+            pauseScanning();
+            mContext.getContentResolver().unregisterContentObserver(mObserver);
+
+            mWorkHandler.removePendingMessages();
+            mMainHandler.removePendingMessages();
         }
-        pauseScanning();
-
-        unregisterAndClearScoreCache();
-
-        mContext.getContentResolver().unregisterContentObserver(mObserver);
     }
 
     private void unregisterAndClearScoreCache() {
         mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, mScoreCache);
         mScoreCache.clearScores();
 
-        // Clear the scores on the work handler to avoid concurrent modification exceptions
-        mWorkHandler.post(() -> mRequestedScores.clear());
+        // Synchronize on mLock to avoid concurrent modification during updateAccessPointsLocked
+        synchronized (mLock) {
+            mRequestedScores.clear();
+        }
     }
 
     /**
      * Gets the current list of access points. Should be called from main thread, otherwise
      * expect inconsistencies
      */
+    @MainThread
     public List<AccessPoint> getAccessPoints() {
         return new ArrayList<>(mAccessPoints);
     }
@@ -441,16 +456,20 @@
         return null;
     }
 
-    private void updateAccessPoints() {
-        // Wait until main worker is done copying the states. This is done to prevent propagation
-        // of accesspoint states while the update is in progress.
-        long before = System.currentTimeMillis();
-        mInternalAccessPointsWriteLock.block();
-        if (DBG) {
-            Log.d(TAG, "Acquired AP lock on WorkerHandler. Time to wait = "
-                    + (System.currentTimeMillis() - before) + " ms.");
+    /** Safely modify {@link #mInternalAccessPoints} by acquiring {@link #mLock} first. */
+    private void updateAccessPointsLocked() {
+        synchronized (mLock) {
+            updateAccessPoints();
         }
+    }
 
+    /**
+     * Update the internal list of access points.
+     *
+     * <p>Should never be called directly, use {@link #updateAccessPointsLocked()} instead.
+     */
+    @GuardedBy("mLock")
+    private void updateAccessPoints() {
         // Swap the current access points into a cached list.
         List<AccessPoint> cachedAccessPoints = new ArrayList<>(mInternalAccessPoints);
         ArrayList<AccessPoint> accessPoints = new ArrayList<>();
@@ -460,8 +479,8 @@
             accessPoint.clearConfig();
         }
 
-        /* Lookup table to more quickly update AccessPoints by only considering objects with the
-         * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
+    /* Lookup table to more quickly update AccessPoints by only considering objects with the
+     * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
         Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();
         WifiConfiguration connectionConfig = null;
         if (mLastInfo != null) {
@@ -584,7 +603,8 @@
 
         mInternalAccessPoints.clear();
         mInternalAccessPoints.addAll(accessPoints);
-        mMainHandler.scheduleAPCopyingAndCloseWriteLock();
+
+        mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
     }
 
     @VisibleForTesting
@@ -641,59 +661,48 @@
             connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId());
         }
 
-        // Lock required to prevent accidental copying of AccessPoint states while the modification
-        // is in progress. see #copyAndNotifyListeners
-        long before = System.currentTimeMillis();
-        mInternalAccessPointsWriteLock.block();
-        if (DBG) {
-            Log.d(TAG, "Acquired AP lock on WorkerHandler for updating NetworkInfo. Wait time = " +
-                    (System.currentTimeMillis() - before) + "ms.");
-        }
-
         boolean updated = false;
         boolean reorder = false; // Only reorder if connected AP was changed
-        for (int i = mInternalAccessPoints.size() - 1; i >= 0; --i) {
-            AccessPoint ap = mInternalAccessPoints.get(i);
-            boolean previouslyConnected = ap.isActive();
-            if (ap.update(connectionConfig, mLastInfo, mLastNetworkInfo)) {
-                updated = true;
-                if (previouslyConnected != ap.isActive()) reorder = true;
+
+        synchronized (mLock) {
+            for (int i = mInternalAccessPoints.size() - 1; i >= 0; --i) {
+                AccessPoint ap = mInternalAccessPoints.get(i);
+                boolean previouslyConnected = ap.isActive();
+                if (ap.update(connectionConfig, mLastInfo, mLastNetworkInfo)) {
+                    updated = true;
+                    if (previouslyConnected != ap.isActive()) reorder = true;
+                }
+                if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
+                    reorder = true;
+                    updated = true;
+                }
             }
-            if (ap.update(mScoreCache, mNetworkScoringUiEnabled)) {
-                reorder = true;
-                updated = true;
-            }
+
+            if (reorder) Collections.sort(mInternalAccessPoints);
+
+            if (updated) mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
         }
-
-        if (reorder) Collections.sort(mInternalAccessPoints);
-
-        if (updated) mMainHandler.scheduleAPCopyingAndCloseWriteLock();
     }
 
     /**
      * Update all the internal access points rankingScores, badge and metering.
      *
      * <p>Will trigger a resort and notify listeners of changes if applicable.
+     *
+     * <p>Synchronized on {@link #mLock}.
      */
     private void updateNetworkScores() {
-        // Lock required to prevent accidental copying of AccessPoint states while the modification
-        // is in progress. see #copyAndNotifyListeners
-        long before = System.currentTimeMillis();
-        mInternalAccessPointsWriteLock.block();
-        if (DBG) {
-            Log.d(TAG, "Acquired AP lock on WorkerHandler for inserting NetworkScores. Wait time = " +
-                    (System.currentTimeMillis() - before) + "ms.");
-        }
-
-        boolean reorder = false;
-        for (int i = 0; i < mInternalAccessPoints.size(); i++) {
-            if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
-                reorder = true;
+        synchronized (mLock) {
+            boolean updated = false;
+            for (int i = 0; i < mInternalAccessPoints.size(); i++) {
+                if (mInternalAccessPoints.get(i).update(mScoreCache, mNetworkScoringUiEnabled)) {
+                    updated = true;
+                }
             }
-        }
-        if (reorder) {
-            Collections.sort(mInternalAccessPoints);
-            mMainHandler.scheduleAPCopyingAndCloseWriteLock();
+            if (updated) {
+                Collections.sort(mInternalAccessPoints);
+                mMainHandler.sendEmptyMessage(MainHandler.MSG_ACCESS_POINT_CHANGED);
+            }
         }
     }
 
@@ -733,7 +742,10 @@
                         .sendToTarget();
                 mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
             } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
-                mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO);
+                NetworkInfo info =
+                        mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
+                mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info)
+                        .sendToTarget();
             }
         }
     };
@@ -749,10 +761,11 @@
         }
     }
 
-    private final class MainHandler extends Handler {
-        private static final int MSG_CONNECTED_CHANGED = 0;
-        private static final int MSG_WIFI_STATE_CHANGED = 1;
-        private static final int MSG_ACCESS_POINT_CHANGED = 2;
+    @VisibleForTesting
+    final class MainHandler extends Handler {
+        @VisibleForTesting static final int MSG_CONNECTED_CHANGED = 0;
+        @VisibleForTesting static final int MSG_WIFI_STATE_CHANGED = 1;
+        @VisibleForTesting static final int MSG_ACCESS_POINT_CHANGED = 2;
         private static final int MSG_RESUME_SCANNING = 3;
         private static final int MSG_PAUSE_SCANNING = 4;
 
@@ -789,10 +802,12 @@
             }
         }
 
-        void scheduleAPCopyingAndCloseWriteLock() {
-            //prevent worker thread from modifying mInternalAccessPoints
-            mInternalAccessPointsWriteLock.close();
-            sendEmptyMessage(MSG_ACCESS_POINT_CHANGED);
+        void removePendingMessages() {
+            removeMessages(MSG_ACCESS_POINT_CHANGED);
+            removeMessages(MSG_CONNECTED_CHANGED);
+            removeMessages(MSG_WIFI_STATE_CHANGED);
+            removeMessages(MSG_PAUSE_SCANNING);
+            removeMessages(MSG_RESUME_SCANNING);
         }
     }
 
@@ -801,7 +816,6 @@
         private static final int MSG_UPDATE_NETWORK_INFO = 1;
         private static final int MSG_RESUME = 2;
         private static final int MSG_UPDATE_WIFI_STATE = 3;
-        private static final int MSG_UPDATE_NETWORK_SCORES = 4;
 
         public WorkHandler(Looper looper) {
             super(looper);
@@ -809,9 +823,18 @@
 
         @Override
         public void handleMessage(Message msg) {
+            synchronized (mLock) {
+                processMessage(msg);
+            }
+        }
+
+        @GuardedBy("mLock")
+        private void processMessage(Message msg) {
+            if (!mRegistered) return;
+
             switch (msg.what) {
                 case MSG_UPDATE_ACCESS_POINTS:
-                    updateAccessPoints();
+                    updateAccessPointsLocked();
                     break;
                 case MSG_UPDATE_NETWORK_INFO:
                     updateNetworkInfo((NetworkInfo) msg.obj);
@@ -836,11 +859,15 @@
                     mMainHandler.obtainMessage(MainHandler.MSG_WIFI_STATE_CHANGED, msg.arg1, 0)
                             .sendToTarget();
                     break;
-                case MSG_UPDATE_NETWORK_SCORES:
-                    updateNetworkScores();
-                    break;
             }
         }
+
+        private void removePendingMessages() {
+            removeMessages(MSG_UPDATE_ACCESS_POINTS);
+            removeMessages(MSG_UPDATE_NETWORK_INFO);
+            removeMessages(MSG_RESUME);
+            removeMessages(MSG_UPDATE_WIFI_STATE);
+        }
     }
 
     @VisibleForTesting
@@ -959,11 +986,12 @@
 
     /**
      * Responsible for copying access points from {@link #mInternalAccessPoints} and notifying
-     * accesspoint listeners. Mutation of the accesspoints returned is done on the main thread.
+     * accesspoint listeners.
      *
      * @param notifyListeners if true, accesspoint listeners are notified, otherwise notifications
      *                        dropped.
      */
+    @MainThread
     private void copyAndNotifyListeners(boolean notifyListeners) {
         // Need to watch out for memory allocations on main thread.
         SparseArray<AccessPoint> oldAccessPoints = new SparseArray<>();
@@ -974,17 +1002,15 @@
             oldAccessPoints.put(accessPoint.mId, accessPoint);
         }
 
-        //synchronize to prevent modification of "mInternalAccessPoints" by worker thread.
-        long before = System.currentTimeMillis();
-        try {
-            if (DBG) {
-                Log.d(TAG, "Starting to copy AP items on the MainHandler");
-            }
-            if (notifyListeners) {
-                notificationMap = mAccessPointListenerAdapter.mPendingNotifications.clone();
-            }
+        if (DBG) {
+            Log.d(TAG, "Starting to copy AP items on the MainHandler");
+        }
+        if (notifyListeners) {
+            notificationMap = mAccessPointListenerAdapter.mPendingNotifications.clone();
+        }
 
-            mAccessPointListenerAdapter.mPendingNotifications.clear();
+        mAccessPointListenerAdapter.mPendingNotifications.clear();
+        synchronized (mLock) {
             for (AccessPoint internalAccessPoint : mInternalAccessPoints) {
                 AccessPoint accessPoint = oldAccessPoints.get(internalAccessPoint.mId);
                 if (accessPoint == null) {
@@ -994,12 +1020,6 @@
                 }
                 updatedAccessPoints.add(accessPoint);
             }
-        } finally {
-            mInternalAccessPointsWriteLock.open();
-            if (DBG) {
-                Log.d(TAG, "Opened AP Write lock on the MainHandler. Time to copy = " +
-                        (System.currentTimeMillis() - before) + " ms.");
-            }
         }
 
         mAccessPoints.clear();
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
index a2becf7..79cee04 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
@@ -23,8 +23,6 @@
  * Factory method used to inject WifiTracker instances.
  */
 public class WifiTrackerFactory {
-    private static boolean sTestingMode = false;
-
     private static WifiTracker sTestingWifiTracker;
 
     @Keep // Keep proguard from stripping this method since it is only used in tests
@@ -35,7 +33,7 @@
     public static WifiTracker create(
             Context context, WifiTracker.WifiListener wifiListener, Looper workerLooper,
             boolean includeSaved, boolean includeScans, boolean includePasspoints) {
-        if(sTestingMode) {
+        if(sTestingWifiTracker != null) {
             return sTestingWifiTracker;
         }
         return new WifiTracker(
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/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 3e01b34..154fde2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -17,6 +17,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.when;
@@ -24,7 +25,6 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.NetworkKey;
 import android.net.ScoredNetwork;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
@@ -40,6 +40,7 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.text.SpannableString;
 import android.text.style.TtsSpan;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index b938fe2..f519a90 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -20,13 +20,17 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -60,7 +64,6 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Matchers;
@@ -129,7 +132,7 @@
     private Handler mScannerHandler;
     private HandlerThread mMainThread;
     private HandlerThread mWorkerThread;
-    private Looper mLooper;
+    private Looper mWorkerLooper;
     private Looper mMainLooper;
     private int mOriginalScoringUiSettingValue;
 
@@ -141,7 +144,7 @@
 
         mWorkerThread = new HandlerThread("TestHandlerWorkerThread");
         mWorkerThread.start();
-        mLooper = mWorkerThread.getLooper();
+        mWorkerLooper = mWorkerThread.getLooper();
         mMainThread = new HandlerThread("TestHandlerThread");
         mMainThread.start();
         mMainLooper = mMainThread.getLooper();
@@ -252,9 +255,7 @@
             tracker.mReceiver.onReceive(mContext, intent);
         }
 
-        mAccessPointsChangedLatch = new CountDownLatch(1);
         sendScanResultsAndProcess(tracker);
-        assertTrue(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
         return tracker;
     }
@@ -264,7 +265,7 @@
                 new WifiTracker(
                         mContext,
                         mockWifiListener,
-                        mLooper,
+                        mWorkerLooper,
                         true,
                         true,
                         true,
@@ -349,7 +350,7 @@
         scanResult.capabilities = "";
 
         WifiTracker tracker = new WifiTracker(
-                InstrumentationRegistry.getTargetContext(), null, mLooper, true, true);
+                InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
 
         AccessPoint result = tracker.getCachedOrCreate(scanResult, new ArrayList<AccessPoint>());
         assertTrue(result.mAccessPointListener != null);
@@ -365,7 +366,7 @@
         configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
 
         WifiTracker tracker = new WifiTracker(
-                InstrumentationRegistry.getTargetContext(), null, mLooper, true, true);
+                InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
 
         AccessPoint result = tracker.getCachedOrCreate(configuration, new ArrayList<AccessPoint>());
         assertTrue(result.mAccessPointListener != null);
@@ -433,7 +434,8 @@
     }
 
     @Test
-    public void startTrackingShouldRequestScoresForCurrentAccessPoints() throws InterruptedException {
+    public void startTrackingAfterStopTracking_shouldRequestNewScores()
+            throws InterruptedException {
         // Start the tracker and inject the initial scan results and then stop tracking
         WifiTracker tracker =  createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
 
@@ -442,6 +444,7 @@
 
         mRequestScoresLatch = new CountDownLatch(1);
         startTracking(tracker);
+        tracker.forceUpdate();
         assertTrue("Latch timed out",
                 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
@@ -462,9 +465,10 @@
     private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException {
         // Updating scores can happen together or one after the other, so the latch countdown is set
         // to 2.
-        mAccessPointsChangedLatch = new CountDownLatch(2);
+        mAccessPointsChangedLatch = new CountDownLatch(3);
         updateScores();
-        mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
+        assertTrue("onAccessPointChanged was not called three times",
+            mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
     }
 
     @Test
@@ -648,27 +652,33 @@
         WifiTracker tracker =  createTrackerWithScanResultsAndAccessPoint1Connected();
         assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
 
-        WifiConfiguration configuration = new WifiConfiguration();
-        configuration.SSID = SSID_1;
-        configuration.BSSID = BSSID_1;
-        configuration.networkId = CONNECTED_NETWORK_ID;
-        when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
-
         int newRssi = CONNECTED_RSSI + 10;
         WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO);
         info.setRssi(newRssi);
-        when(mockWifiManager.getConnectionInfo()).thenReturn(info);
 
-        mAccessPointsChangedLatch = new CountDownLatch(1);
+        CountDownLatch latch = new CountDownLatch(1);
+
+        // Once the new info has been fetched, we need to wait for the access points to be copied
+        doAnswer(invocation -> {
+                    latch.countDown();
+                    mAccessPointsChangedLatch = new CountDownLatch(1);
+                    return info;
+                }).when(mockWifiManager).getConnectionInfo();
+
         tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION));
-        assertTrue(mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        assertTrue("New connection info never retrieved",
+                latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+        assertTrue("onAccessPointsChanged never called",
+                mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
 
-        verify(mockWifiManager, atLeast(2)).getConnectionInfo();
         assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
     }
 
     @Test
     public void forceUpdateShouldSynchronouslyFetchLatestInformation() throws Exception {
+        Network mockNetwork = mock(Network.class);
+        when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
+
         when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
 
         WifiConfiguration configuration = new WifiConfiguration();
@@ -682,13 +692,58 @@
         networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
         when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
 
-
         WifiTracker tracker = createMockedWifiTracker();
-        startTracking(tracker);
         tracker.forceUpdate();
 
+        verify(mockWifiManager).getConnectionInfo();
+        verify(mockWifiManager, times(2)).getConfiguredNetworks();
+        verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
+
         verify(mockWifiListener).onAccessPointsChanged();
         assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
         assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
     }
+
+    @Test
+    public void stopTrackingShouldRemoveWifiListenerCallbacks() throws Exception {
+        WifiTracker tracker = createMockedWifiTracker();
+        startTracking(tracker);
+
+        CountDownLatch latch = new CountDownLatch(1);
+        CountDownLatch lock = new CountDownLatch(1);
+        tracker.mMainHandler.post(() -> {
+            try {
+                lock.await();
+                latch.countDown();
+            } catch (InterruptedException e) {
+                fail("Interrupted Exception while awaiting lock release: " + e);
+            }
+        });
+
+        // Enqueue messages
+        tracker.mMainHandler.sendEmptyMessage(
+                WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED);
+        tracker.mMainHandler.sendEmptyMessage(
+                WifiTracker.MainHandler.MSG_CONNECTED_CHANGED);
+        tracker.mMainHandler.sendEmptyMessage(
+                WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED);
+
+        tracker.stopTracking();
+
+        verify(mockWifiListener, atMost(1)).onAccessPointsChanged();
+        verify(mockWifiListener, atMost(1)).onConnectedChanged();
+        verify(mockWifiListener, atMost(1)).onWifiStateChanged(anyInt());
+
+        lock.countDown();
+        assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
+
+        assertThat(tracker.mMainHandler.hasMessages(
+                WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED)).isFalse();
+        assertThat(tracker.mMainHandler.hasMessages(
+                WifiTracker.MainHandler.MSG_CONNECTED_CHANGED)).isFalse();
+        assertThat(tracker.mMainHandler.hasMessages(
+                WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED)).isFalse();
+
+        verifyNoMoreInteractions(mockWifiListener);
+    }
 }
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
index 56891f6..fdc42bf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
@@ -27,6 +27,7 @@
 import android.content.res.TypedArray;
 import android.provider.Settings;
 import android.view.MenuItem;
+import com.android.internal.R;
 
 import org.junit.Before;
 import org.junit.Test;
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/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index f809c68..871ed67 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -31,6 +31,7 @@
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
+        android:textDirection="locale"
         android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
 
     <ImageView
diff --git a/packages/SystemUI/res/layout/qs_detail_item.xml b/packages/SystemUI/res/layout/qs_detail_item.xml
index 6544f0d..97e82ff 100644
--- a/packages/SystemUI/res/layout/qs_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_detail_item.xml
@@ -43,6 +43,7 @@
             android:id="@android:id/title"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:textDirection="locale"
             android:ellipsize="end"
             android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" />
 
@@ -50,6 +51,7 @@
             android:id="@android:id/summary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:textDirection="locale"
             android:layout_marginTop="2dp"
             android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" />
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 5766dc1..5df50cd 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -32,6 +32,7 @@
         android:layout_width="wrap_content"
         android:paddingEnd="6dp"
         android:src="@drawable/stat_sys_vpn_ic"
+        android:contentDescription="@string/accessibility_vpn_on"
         />
     <FrameLayout
         android:id="@+id/ethernet_combo"
diff --git a/packages/SystemUI/res/values-sw410dp/config.xml b/packages/SystemUI/res/values-sw410dp/config.xml
index b04b28c..362c1d2 100644
--- a/packages/SystemUI/res/values-sw410dp/config.xml
+++ b/packages/SystemUI/res/values-sw410dp/config.xml
@@ -21,6 +21,7 @@
      for different hardware and product builds. -->
 <resources>
     <integer name="quick_settings_num_rows">2</integer>
+    <integer name="quick_settings_num_rows_portrait">3</integer>
 
     <bool name="quick_settings_show_full_alarm">true</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index e9d6fec..fd7e165 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -100,6 +100,7 @@
 
     <!-- The number of rows in the QuickSettings -->
     <integer name="quick_settings_num_rows">1</integer>
+    <integer name="quick_settings_num_rows_portrait">2</integer>
 
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b70597f..9097c53 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -390,6 +390,9 @@
     <!-- Content description of the airplane mode icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_airplane_mode">Airplane mode.</string>
 
+    <!-- Content description of the VPN icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_vpn_on">VPN on.</string>
+
     <!-- Content description of the no sim icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_no_sims">No SIM card.</string>
 
@@ -1811,10 +1814,14 @@
     <string name="report_rejected_touch" translatable="false">Report rejected touch</string>
 
     <!-- Multi-Window strings -->
-    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed in split-screen and that things might crash/not work properly [CHAR LIMIT=NONE] -->
     <string name="dock_forced_resizable">App may not work with split-screen.</string>
-    <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
+    <!-- Warning message when we try to dock a non-resizeable task and launch it in fullscreen instead. -->
     <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
+    <!-- Text that gets shown on top of current activity to inform the user that the system force-resized the current activity to be displayed on a secondary display and that things might crash/not work properly [CHAR LIMIT=NONE] -->
+    <string name="forced_resizable_secondary_display">App may not work on a secondary display.</string>
+    <!-- Warning message when we try to launch a non-resizeable activity on a secondary display and launch it on the primary instead. -->
+    <string name="activity_launch_on_secondary_display_failed_text">App does not support launch on secondary displays.</string>
 
     <!-- accessibility label for button to open settings [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_settings">Open settings.</string>
@@ -1854,10 +1861,6 @@
         not appear on production builds ever. -->
     <string name="tuner_doze" translatable="false">Ambient Display</string>
 
-    <!-- Ambient display, Sensors wake up device of the tuner. Non-translatable since it should
-        not appear on production builds ever. -->
-    <string name="tuner_doze_sensors_wake_up_fully" translatable="false">Wake up device on double tap or lift</string>
-
     <!-- Ambient display always-on of the tuner. Non-translatable since it should
         not appear on production builds ever. -->
     <string name="tuner_doze_always_on" translatable="false">Always on</string>
@@ -1895,6 +1898,12 @@
     <!-- PiP minimize description. [CHAR LIMIT=NONE] -->
     <string name="pip_minimize_description" translatable="false">Drag or fling the PIP to the edges of the screen to minimize it.</string>
 
+    <!-- PiP fling to dismiss title. [CHAR LIMIT=NONE]-->
+    <string name="pip_fling_dismiss_title" translatable="false">Fling to dismiss</string>
+
+    <!-- PiP fling to dismiss description. [CHAR LIMIT=NONE] -->
+    <string name="pip_fling_dismiss_description" translatable="false">Fling from anywhere on the screen to the bottom of the screen to dismiss the PIP.</string>
+
     <!-- Button to play the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
     <string name="pip_play">Play</string>
 
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index a685c79..24f29c8 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -131,6 +131,12 @@
         android:summary="@string/pip_minimize_description"
         sysui:defValue="false" />
 
+      <com.android.systemui.tuner.TunerSwitch
+        android:key="pip_fling_dismiss"
+        android:title="@string/pip_fling_dismiss_title"
+        android:summary="@string/pip_fling_dismiss_description"
+        sysui:defValue="false" />
+
     </PreferenceScreen>
 
     <PreferenceScreen
@@ -142,11 +148,6 @@
           android:title="@string/tuner_doze_always_on"
           sysui:defValue="false" />
 
-        <com.android.systemui.tuner.TunerSwitch
-          android:key="doze_sensors_wake_up_fully"
-          android:title="@string/tuner_doze_sensors_wake_up_fully"
-          sysui:defValue="false" />
-
     </PreferenceScreen>
 
     <Preference
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index ea55c5f..2096956 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -99,11 +99,7 @@
     }
 
     private void onSensor(int pulseReason, boolean sensorPerformedProxCheck) {
-        if (mDozeParameters.getSensorsWakeUpFully()) {
-            mMachine.wakeUp();
-        } else {
-            requestPulse(pulseReason, sensorPerformedProxCheck);
-        }
+        requestPulse(pulseReason, sensorPerformedProxCheck);
 
         if (pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP) {
             final long timeSinceNotification =
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 67255d3..fc52a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -465,6 +465,26 @@
     }
 
     /**
+     * @return whether the gesture it towards the dismiss area based on the velocity when
+     *         dismissing.
+     */
+    public boolean isGestureToDismissArea(Rect pipBounds, float velX, float velY,
+            boolean isFling) {
+        Point endpoint = getDismissEndPoint(pipBounds, velX, velY, isFling);
+        // Center the point
+        endpoint.x += pipBounds.width() / 2;
+        endpoint.y += pipBounds.height() / 2;
+
+        // The dismiss area is the middle third of the screen, half the PIP's height from the bottom
+        Point size = new Point();
+        mContext.getDisplay().getRealSize(size);
+        final int left = size.x / 3;
+        Rect dismissArea = new Rect(left, size.y - (pipBounds.height() / 2), left * 2,
+                size.y + pipBounds.height());
+        return dismissArea.contains(endpoint.x, endpoint.y);
+    }
+
+    /**
      * @return the distance between points {@param p1} and {@param p2}.
      */
     private float distanceBetweenRectOffsets(Rect r1, Rect r2) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3223f9f..f586ec6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -58,6 +58,7 @@
     private static final String TAG = "PipTouchHandler";
 
     private static final String TUNER_KEY_MINIMIZE = "pip_minimize";
+    private static final String TUNER_KEY_FLING_DISMISS = "pip_fling_dismiss";
 
     // These values are used for metrics and should never change
     private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
@@ -114,6 +115,8 @@
 
     // Allow the PIP to be dragged to the edge of the screen to be minimized.
     private boolean mEnableMinimize = false;
+    // Allow the PIP to be flung from anywhere on the screen to the bottom to be dismissed.
+    private boolean mEnableFlingToDismiss = false;
 
     // Behaviour states
     private int mMenuState;
@@ -195,6 +198,7 @@
 
         // Register any tuner settings changes
         Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_MINIMIZE);
+        Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_FLING_DISMISS);
 
         // Register the listener for input consumer touch events
         inputConsumerController.setTouchListener(this::handleTouchEvent);
@@ -238,14 +242,12 @@
 
     @Override
     public void onTuningChanged(String key, String newValue) {
-        if (newValue == null) {
-            // Reset back to default
-            mEnableMinimize = false;
-            return;
-        }
         switch (key) {
             case TUNER_KEY_MINIMIZE:
-                mEnableMinimize = Integer.parseInt(newValue) != 0;
+                mEnableMinimize = newValue == null ? false : Integer.parseInt(newValue) != 0;
+                break;
+            case TUNER_KEY_FLING_DISMISS:
+                mEnableFlingToDismiss = newValue == null ? false : Integer.parseInt(newValue) != 0;
                 break;
         }
     }
@@ -631,8 +633,12 @@
             final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
             final float velocity = PointF.length(vel.x, vel.y);
             final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond();
-            final boolean isFlingToBot = isFling
-                    && !isHorizontal && mMovementWithinDismiss && vel.y > 0;
+            final boolean isUpWithinDimiss = mEnableFlingToDismiss
+                    && touchState.getLastTouchPosition().y >= mMovementBounds.bottom
+                    && mMotionHelper.isGestureToDismissArea(mMotionHelper.getBounds(), vel.x,
+                            vel.y, isFling);
+            final boolean isFlingToBot = isFling && vel.y > 0 && !isHorizontal
+                    && (mMovementWithinDismiss || isUpWithinDimiss);
             if (ENABLE_DISMISS_DRAG_TO_EDGE) {
                 try {
                     mHandler.removeCallbacks(mShowDismissAffordance);
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/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 9da52d0..f3417dc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -279,8 +279,7 @@
         private int getRows() {
             final Resources res = getContext().getResources();
             if (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
-                // Always have 3 rows in portrait.
-                return 3;
+                return res.getInteger(R.integer.quick_settings_num_rows_portrait);
             }
             return Math.max(1, res.getInteger(R.integer.quick_settings_num_rows));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 2725a32..5512993 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -16,8 +16,14 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.support.v7.app.MediaRouteChooserDialog;
@@ -61,6 +67,7 @@
     private final KeyguardMonitor mKeyguard;
     private final Callback mCallback = new Callback();
     private final ActivityStarter mActivityStarter;
+    private Dialog mDialog;
 
     public CastTile(QSHost host) {
         super(host);
@@ -128,9 +135,7 @@
             Context context = new ContextThemeWrapper(mContext,
                     R.style.Theme_AppCompat_Light_Dialog_Alert);
             if (mState.value) {
-                MediaRouteControllerDialog dialog = new MediaRouteControllerDialog(context);
-                dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
-                dialog.show();
+                mDialog = new MediaRouteControllerDialog(context);
             } else {
                 // Instead of showing detail, show standard media routing UI.
                 MediaRouteChooserDialog dialog = new MediaRouteChooserDialog(context);
@@ -138,13 +143,21 @@
                         .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
                         .build();
                 dialog.setRouteSelector(selector);
-                dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
-                dialog.show();
+                mDialog = dialog;
             }
+            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+            mDialog.show();
+            registerReceiver();
             mHost.collapsePanels();
         });
     }
 
+    private void registerReceiver() {
+        mContext.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
+                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
+        mDialog.setOnDismissListener(dialog -> mContext.unregisterReceiver(mReceiver));
+    }
+
     @Override
     public CharSequence getTileLabel() {
         return mContext.getString(R.string.quick_settings_cast_title);
@@ -210,6 +223,15 @@
         }
     };
 
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mDialog != null) {
+                mDialog.dismiss();
+            }
+        }
+    };
+
     private final class CastDetailAdapter implements DetailAdapter, QSDetailItems.Callback {
         private final LinkedHashMap<String, CastDevice> mVisibleOrder = new LinkedHashMap<>();
 
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 429ace6..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) { }
@@ -156,8 +161,9 @@
         public void onPinnedActivityRestartAttempt() { }
         public void onPinnedStackAnimationStarted() { }
         public void onPinnedStackAnimationEnded() { }
-        public void onActivityForcedResizable(String packageName, int taskId) { }
+        public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
         public void onActivityDismissingDockedStack() { }
+        public void onActivityLaunchOnSecondaryDisplayFailed() { }
         public void onTaskProfileLocked(int taskId, int userId) { }
 
         /**
@@ -186,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);
         }
@@ -224,9 +242,9 @@
         }
 
         @Override
-        public void onActivityForcedResizable(String packageName, int taskId)
+        public void onActivityForcedResizable(String packageName, int taskId, int reason)
                 throws RemoteException {
-            mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, 0, packageName)
+            mHandler.obtainMessage(H.ON_ACTIVITY_FORCED_RESIZABLE, taskId, reason, packageName)
                     .sendToTarget();
         }
 
@@ -236,6 +254,11 @@
         }
 
         @Override
+        public void onActivityLaunchOnSecondaryDisplayFailed() throws RemoteException {
+            mHandler.sendEmptyMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED);
+        }
+
+        @Override
         public void onTaskProfileLocked(int taskId, int userId) {
             mHandler.obtainMessage(H.ON_TASK_PROFILE_LOCKED, taskId, userId).sendToTarget();
         }
@@ -303,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);
         }
@@ -1130,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);
+                }
             }
         }
     }
@@ -1235,71 +1257,84 @@
         private static final int ON_TASK_PROFILE_LOCKED = 8;
         private static final int ON_PINNED_STACK_ANIMATION_STARTED = 9;
         private static final int ON_ACTIVITY_UNPINNED = 10;
+        private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
 
         @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);
+                    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_TASK_PROFILE_LOCKED: {
-                    for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
-                        mTaskStackListeners.get(i).onTaskProfileLocked(msg.arg1, msg.arg2);
+                    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);
+                        }
+                        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/stackdivider/ForcedResizableInfoActivity.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
index 30bf060..4415bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivity.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.stackdivider;
 
+import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
+import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
+
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -34,6 +37,8 @@
  */
 public class ForcedResizableInfoActivity extends Activity implements OnTouchListener {
 
+    public static final String EXTRA_FORCED_RESIZEABLE_REASON = "extra_forced_resizeable_reason";
+
     private static final long DISMISS_DELAY = 2500;
 
     private final Runnable mFinishRunnable = new Runnable() {
@@ -48,8 +53,21 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.forced_resizable_activity);
         TextView tv = (TextView) findViewById(com.android.internal.R.id.message);
-        tv.setText(R.string.dock_forced_resizable);
-        getWindow().setTitle(getString(R.string.dock_forced_resizable));
+        int reason = getIntent().getIntExtra(EXTRA_FORCED_RESIZEABLE_REASON, -1);
+        String text;
+        switch (reason) {
+            case FORCED_RESIZEABLE_REASON_SPLIT_SCREEN:
+                text = getString(R.string.dock_forced_resizable);
+                break;
+            case FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY:
+                text = getString(R.string.forced_resizable_secondary_display);
+                break;
+            default:
+                throw new IllegalArgumentException("Unexpected forced resizeable reason: "
+                        + reason);
+        }
+        tv.setText(text);
+        getWindow().setTitle(text);
         getWindow().getDecorView().setOnTouchListener(this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index 17b494e..a2c782e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.stackdivider;
 
+import static com.android.systemui.stackdivider.ForcedResizableInfoActivity
+        .EXTRA_FORCED_RESIZEABLE_REASON;
+
 import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.Intent;
@@ -43,7 +46,7 @@
     private static final int TIMEOUT = 1000;
     private final Context mContext;
     private final Handler mHandler = new Handler();
-    private final ArraySet<Integer> mPendingTaskIds = new ArraySet<>();
+    private final ArraySet<PendingTaskRecord> mPendingTasks = new ArraySet<>();
     private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
     private boolean mDividerDraging;
 
@@ -54,20 +57,41 @@
         }
     };
 
+    /** Record of force resized task that's pending to be handled. */
+    private class PendingTaskRecord {
+        int taskId;
+        /**
+         * {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SPLIT_SCREEN} or
+         * {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY}
+         */
+        int reason;
+
+        PendingTaskRecord(int taskId, int reason) {
+            this.taskId = taskId;
+            this.reason = reason;
+        }
+    }
+
     public ForcedResizableInfoActivityController(Context context) {
         mContext = context;
         EventBus.getDefault().register(this);
         SystemServicesProxy.getInstance(context).registerTaskStackListener(
                 new TaskStackListener() {
                     @Override
-                    public void onActivityForcedResizable(String packageName, int taskId) {
-                        activityForcedResizable(packageName, taskId);
+                    public void onActivityForcedResizable(String packageName, int taskId,
+                            int reason) {
+                        activityForcedResizable(packageName, taskId, reason);
                     }
 
                     @Override
                     public void onActivityDismissingDockedStack() {
                         activityDismissingDockedStack();
                     }
+
+                    @Override
+                    public void onActivityLaunchOnSecondaryDisplayFailed() {
+                        activityLaunchOnSecondaryDisplayFailed();
+                    }
                 });
     }
 
@@ -93,11 +117,11 @@
         showPending();
     }
 
-    private void activityForcedResizable(String packageName, int taskId) {
+    private void activityForcedResizable(String packageName, int taskId, int reason) {
         if (debounce(packageName)) {
             return;
         }
-        mPendingTaskIds.add(taskId);
+        mPendingTasks.add(new PendingTaskRecord(taskId, reason));
         postTimeout();
     }
 
@@ -106,16 +130,23 @@
                 R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT));
     }
 
+    private void activityLaunchOnSecondaryDisplayFailed() {
+        EventBus.getDefault().send(new ShowUserToastEvent(
+                R.string.activity_launch_on_secondary_display_failed_text, Toast.LENGTH_SHORT));
+    }
+
     private void showPending() {
         mHandler.removeCallbacks(mTimeoutRunnable);
-        for (int i = mPendingTaskIds.size() - 1; i >= 0; i--) {
+        for (int i = mPendingTasks.size() - 1; i >= 0; i--) {
+            PendingTaskRecord pendingRecord = mPendingTasks.valueAt(i);
             Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
             ActivityOptions options = ActivityOptions.makeBasic();
-            options.setLaunchTaskId(mPendingTaskIds.valueAt(i));
+            options.setLaunchTaskId(pendingRecord.taskId);
             options.setTaskOverlay(true, false /* canResume */);
+            intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.reason);
             mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
         }
-        mPendingTaskIds.clear();
+        mPendingTasks.clear();
     }
 
     private void postTimeout() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index f3c7b84..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);
@@ -329,12 +327,14 @@
     private void updateSecondaryText() {
         final boolean disabled = mSingleNotificationChannel != null &&
                 getSelectedImportance() == IMPORTANCE_NONE;
+        final boolean isDefaultChannel = mSingleNotificationChannel != null &&
+                mSingleNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID);
         if (disabled) {
             mChannelDisabledView.setVisibility(View.VISIBLE);
             mNumChannelsView.setVisibility(View.GONE);
         } else {
             mChannelDisabledView.setVisibility(View.GONE);
-            mNumChannelsView.setVisibility(View.VISIBLE);
+            mNumChannelsView.setVisibility(isDefaultChannel ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
@@ -384,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/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index dd99749..4339ade 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -89,7 +89,7 @@
         mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
         Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
         mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
-        mSignalClusterView = reinflateSignalCluster(mStatusBar);
+        mSignalClusterView = mStatusBar.findViewById(R.id.signal_cluster);
         Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView);
         // Default to showing until we know otherwise.
         showSystemIconArea(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 40776ea..e1ca929 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -59,9 +59,6 @@
         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
         pw.print("    getPickupSubtypePerformsProxCheck(): ");pw.println(
                 dumpPickupSubtypePerformsProxCheck());
-        if (mAmbientDisplayConfiguration.alwaysOnAvailable()) {
-            pw.print("    getSensorsWakeUpFully(): "); pw.println(getSensorsWakeUpFully());
-        }
     }
 
     private String dumpPickupSubtypePerformsProxCheck() {
@@ -122,12 +119,6 @@
         return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
     }
 
-    public boolean getSensorsWakeUpFully() {
-        return mAmbientDisplayConfiguration.alwaysOnAvailable()
-                && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                DOZE_SENSORS_WAKE_UP_FULLY, 0, UserHandle.USER_CURRENT) != 0;
-    }
-
     private boolean getBoolean(String propName, int resId) {
         return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index dee15d8..14c1606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -87,6 +87,7 @@
             return mAnimationFilter;
         }
     }.setDuration(200).setDelay(50);
+    public static final int MAX_VISIBLE_ICONS_WHEN_DARK = 5;
 
     private boolean mShowAllIcons = true;
     private final HashMap<View, IconState> mIconStates = new HashMap<>();
@@ -243,6 +244,7 @@
         float translationX = getActualPaddingStart();
         int firstOverflowIndex = -1;
         int childCount = getChildCount();
+        int maxVisibleIcons = mDark ? MAX_VISIBLE_ICONS_WHEN_DARK : childCount;
         float layoutEnd = getLayoutEnd();
         float overflowStart = layoutEnd - mIconSize * (2 + OVERFLOW_EARLY_AMOUNT);
         boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
@@ -251,21 +253,21 @@
             View view = getChildAt(i);
             IconState iconState = mIconStates.get(view);
             iconState.xTranslation = translationX;
-            boolean isAmbient = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
-                    && iconState.iconAppearAmount > 0.0f;
+            boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
+                    && iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
             boolean noOverflowAfter = i == childCount - 1;
             if (mOpenedAmount != 0.0f) {
-                noOverflowAfter = noOverflowAfter && !hasAmbient;
+                noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
             }
             iconState.visibleState = StatusBarIconView.STATE_ICON;
-            if (firstOverflowIndex == -1 && (isAmbient
+            if (firstOverflowIndex == -1 && (forceOverflow
                     || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
-                firstOverflowIndex = noOverflowAfter && !isAmbient ? i - 1 : i;
+                firstOverflowIndex = noOverflowAfter && !forceOverflow ? i - 1 : i;
                 int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
                 visualOverflowStart = overflowStart + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT)
                         - totalDotLength / 2
                         - mIconSize * 0.5f + mStaticDotRadius;
-                if (isAmbient) {
+                if (forceOverflow) {
                     visualOverflowStart = Math.min(translationX, visualOverflowStart
                             + mStaticDotRadius * 2 + mDotPadding);
                 } else {
@@ -318,6 +320,12 @@
         boolean center = mDark;
         if (center && translationX < getLayoutEnd()) {
             float delta = (getLayoutEnd() - translationX) / 2;
+            if (firstOverflowIndex != -1) {
+                // If we have an overflow, only count those half for centering because the dots
+                // don't have a lot of visual weight.
+                float deltaIgnoringOverflow = (getLayoutEnd() - visualOverflowStart) / 2;
+                delta = (deltaIgnoringOverflow + delta) / 2;
+            }
             for (int i = 0; i < childCount; i++) {
                 View view = getChildAt(i);
                 IconState iconState = mIconStates.get(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index c85584e..646f3d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -23,18 +23,25 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewStub;
+import android.view.ViewStub.OnInflateListener;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.statusbar.NotificationData.Entry;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
 /**
  * The container with notification stack scroller and quick settings inside.
  */
 public class NotificationsQuickSettingsContainer extends FrameLayout
-        implements ViewStub.OnInflateListener, FragmentHostManager.FragmentListener {
+        implements OnInflateListener, FragmentListener, OnHeadsUpChangedListener {
 
     private FrameLayout mQsFrame;
     private View mUserSwitcher;
@@ -46,6 +53,8 @@
 
     private int mBottomPadding;
     private int mStackScrollerMargin;
+    private boolean mHeadsUp;
+    private HeadsUpManager mHeadsUpManager;
 
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -67,12 +76,16 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         FragmentHostManager.get(this).addTagListener(QS.TAG, this);
+        mHeadsUpManager = SysUiServiceProvider.getComponent(getContext(), StatusBar.class)
+                .mHeadsUpManager;
+        mHeadsUpManager.addListener(this);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         FragmentHostManager.get(this).removeTagListener(QS.TAG, this);
+        mHeadsUpManager.removeListener(this);
     }
 
     @Override
@@ -101,7 +114,7 @@
         boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
         boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
 
-        final boolean qsBottom = mQsExpanded && !mCustomizerAnimating;
+        final boolean qsBottom = mHeadsUp;
         View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
         View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
         // Invert the order of the scroll view and user switcher such that the notifications receive
@@ -176,4 +189,14 @@
         params.bottomMargin = bottomMargin;
         v.setLayoutParams(params);
     }
+
+    @Override
+    public void onHeadsUpStateChanged(Entry entry, boolean isHeadsUp) {
+        boolean hasHeadsUp = mHeadsUpManager.getAllEntries().size() != 0;
+        if (mHeadsUp == hasHeadsUp) {
+            return;
+        }
+        mHeadsUp = hasHeadsUp;
+        invalidate();
+    }
 }
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/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 96c70c4..5f7ac5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -170,6 +170,10 @@
         mListeners.add(listener);
     }
 
+    public void removeListener(OnHeadsUpChangedListener listener) {
+        mListeners.remove(listener);
+    }
+
     public StatusBar getBar() {
         return mBar;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 3aef247..62d80ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -33,7 +33,6 @@
         DozeParameters params = mock(DozeParameters.class, noDefaultAnswer(doneHolder));
 
         when(params.getPulseOnSigMotion()).thenReturn(false);
-        when(params.getSensorsWakeUpFully()).thenReturn(false);
         when(params.getPickupVibrationThreshold()).thenReturn(0);
         when(params.getProxCheckBeforePulse()).thenReturn(true);
         when(params.getPickupSubtypePerformsProxCheck(anyInt())).thenReturn(true);
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 66385a1..2b14b31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -314,16 +314,14 @@
     }
 
     @Test
-    public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception {
+    public void testBindNotification_NumChannelsTextHiddenWhenDefaultChannel() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
                 mNotificationChannel.getImportance(), mSbn, null, null,
                 null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
-        assertEquals(View.VISIBLE, numChannelsView.getVisibility());
-        assertEquals(mContext.getString(R.string.notification_default_channel_desc),
-                numChannelsView.getText());
+        assertEquals(View.INVISIBLE, numChannelsView.getVisibility());
     }
 
     @Test
@@ -780,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/proto/src/wifi.proto b/proto/src/wifi.proto
index 7eefb7e..debb157 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -238,6 +238,9 @@
 
   // Histogram of the delta between scan result RSSI and RSSI polls
   repeated RssiPollCount rssi_poll_delta_count = 51;
+
+  // List of events
+  repeated StaEvent sta_event_list = 52;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -460,3 +463,202 @@
   // Result of attempt to start SoftAp
   optional SoftApStartResult start_result = 3;
 }
+
+message StaEvent {
+  message ConfigInfo {
+    // The set of key management protocols supported by this configuration.
+    optional uint32 allowed_key_management = 1 [default = 0];
+
+    // The set of security protocols supported by this configuration.
+    optional uint32 allowed_protocols = 2 [default = 0];
+
+    // The set of authentication protocols supported by this configuration.
+    optional uint32 allowed_auth_algorithms = 3 [default = 0];
+
+    // The set of pairwise ciphers for WPA supported by this configuration.
+    optional uint32 allowed_pairwise_ciphers = 4 [default = 0];
+
+    // The set of group ciphers supported by this configuration.
+    optional uint32 allowed_group_ciphers = 5;
+
+    // Is this a 'hidden network'
+    optional bool hidden_ssid = 6;
+
+    // Is this a Hotspot 2.0 / passpoint network
+    optional bool is_passpoint = 7;
+
+    // Is this an 'ephemeral' network (Not in saved network list, recommended externally)
+    optional bool is_ephemeral = 8;
+
+    // Has a successful connection ever been established using this WifiConfiguration
+    optional bool has_ever_connected = 9;
+
+    // RSSI of the scan result candidate associated with this WifiConfiguration
+    optional int32 scan_rssi = 10 [default = -127];
+
+    // Frequency of the scan result candidate associated with this WifiConfiguration
+    optional int32 scan_freq = 11 [default = -1];
+  }
+
+  enum EventType {
+    // Default/Invalid event
+    TYPE_UNKNOWN = 0;
+
+    // Supplicant Association Rejection event. Code contains the 802.11
+    TYPE_ASSOCIATION_REJECTION_EVENT = 1;
+
+    // Supplicant L2 event,
+    TYPE_AUTHENTICATION_FAILURE_EVENT = 2;
+
+    // Supplicant L2 event
+    TYPE_NETWORK_CONNECTION_EVENT = 3;
+
+    // Supplicant L2 event
+    TYPE_NETWORK_DISCONNECTION_EVENT = 4;
+
+    // Supplicant L2 event
+    TYPE_SUPPLICANT_STATE_CHANGE_EVENT = 5;
+
+    // Supplicant L2 event
+    TYPE_CMD_ASSOCIATED_BSSID = 6;
+
+    // IP Manager successfully completed IP Provisioning
+    TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL = 7;
+
+    // IP Manager failed to complete IP Provisioning
+    TYPE_CMD_IP_CONFIGURATION_LOST = 8;
+
+    // IP Manager lost reachability to network neighbors
+    TYPE_CMD_IP_REACHABILITY_LOST = 9;
+
+    // Indicator that Supplicant is targeting a BSSID for roam/connection
+    TYPE_CMD_TARGET_BSSID = 10;
+
+    // Wifi framework is initiating a connection attempt
+    TYPE_CMD_START_CONNECT = 11;
+
+    // Wifi framework is initiating a roaming connection attempt
+    TYPE_CMD_START_ROAM = 12;
+
+    // SystemAPI connect() command, Settings App
+    TYPE_CONNECT_NETWORK = 13;
+
+    // Network Agent has validated the internet connection (Captive Portal Check success, or user
+    // validation)
+    TYPE_NETWORK_AGENT_VALID_NETWORK = 14;
+
+    // Framework initiated disconnect. Sometimes generated to give an extra reason for a disconnect
+    // Should typically be followed by a NETWORK_DISCONNECTION_EVENT with a local_gen = true
+    TYPE_FRAMEWORK_DISCONNECT = 15;
+  }
+
+  enum FrameworkDisconnectReason {
+    // default/none/unknown value
+    DISCONNECT_UNKNOWN = 0;
+
+    // API DISCONNECT
+    DISCONNECT_API = 1;
+
+    // Some framework internal reason (generic)
+    DISCONNECT_GENERIC = 2;
+
+    // Network Agent network validation failed, user signaled network unwanted
+    DISCONNECT_UNWANTED = 3;
+
+    // Roaming timed out
+    DISCONNECT_ROAM_WATCHDOG_TIMER = 4;
+
+    // P2P service requested wifi disconnect
+    DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST = 5;
+
+    // SIM was removed while using a SIM config
+    DISCONNECT_RESET_SIM_NETWORKS = 6;
+  }
+
+  // Authentication Failure reasons as reported through the API.
+  enum AuthFailureReason {
+    // Unknown default
+    AUTH_FAILURE_UNKNOWN = 0;
+
+    // The reason code if there is no error during authentication. It could also imply that there no
+    // authentication in progress,
+    AUTH_FAILURE_NONE = 1;
+
+    // The reason code if there was a timeout authenticating.
+    AUTH_FAILURE_TIMEOUT = 2;
+
+    // The reason code if there was a wrong password while authenticating.
+    AUTH_FAILURE_WRONG_PSWD = 3;
+
+    // The reason code if there was EAP failure while authenticating.
+    AUTH_FAILURE_EAP_FAILURE = 4;
+  }
+
+  // What event was this
+  optional EventType type = 1;
+
+  // 80211 death reason code, relevant to NETWORK_DISCONNECTION_EVENTs
+  optional int32 reason = 2 [default = -1];
+
+  // 80211 Association Status code, relevant to ASSOCIATION_REJECTION_EVENTs
+  optional int32 status = 3 [default = -1];
+
+  // Designates whether a NETWORK_DISCONNECT_EVENT was by the STA or AP
+  optional bool local_gen = 4 [default = false];
+
+  // Network information from the WifiConfiguration of a framework initiated connection attempt
+  optional ConfigInfo config_info = 5;
+
+  // RSSI from the last rssi poll (Only valid for active connections)
+  optional int32 last_rssi = 6 [default = -127];
+
+  // Link speed from the last rssi poll (Only valid for active connections)
+  optional int32 last_link_speed = 7 [default = -1];
+
+  // Frequency from the last rssi poll (Only valid for active connections)
+  optional int32 last_freq = 8 [default = -1];
+
+  // Enum used to define bit positions in the supplicant_state_change_bitmask
+  // See {@code frameworks/base/wifi/java/android/net/wifi/SupplicantState.java} for documentation
+  enum SupplicantState {
+    STATE_DISCONNECTED = 0;
+
+    STATE_INTERFACE_DISABLED = 1;
+
+    STATE_INACTIVE = 2;
+
+    STATE_SCANNING = 3;
+
+    STATE_AUTHENTICATING = 4;
+
+    STATE_ASSOCIATING = 5;
+
+    STATE_ASSOCIATED = 6;
+
+    STATE_FOUR_WAY_HANDSHAKE = 7;
+
+    STATE_GROUP_HANDSHAKE = 8;
+
+    STATE_COMPLETED = 9;
+
+    STATE_DORMANT = 10;
+
+    STATE_UNINITIALIZED = 11;
+
+    STATE_INVALID = 12;
+  }
+
+  // Bit mask of all supplicant state changes that occured since the last event
+  optional uint32 supplicant_state_changes_bitmask = 9 [default = 0];
+
+  // The number of milliseconds that have elapsed since the device booted
+  optional int64 start_time_millis = 10 [default = 0];
+
+  optional FrameworkDisconnectReason framework_disconnect_reason = 11 [default = DISCONNECT_UNKNOWN];
+
+  // Flag which indicates if an association rejection event occured due to a timeout
+  optional bool association_timed_out = 12 [default = false];
+
+  // Authentication failure reason, as reported by WifiManager (calculated from state & deauth code)
+  optional AuthFailureReason auth_failure_reason = 13 [default = AUTH_FAILURE_UNKNOWN];
+}
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
index 7a702e8..a36873e 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -59,6 +59,9 @@
      * @param ain The input allocation
      */
     public void setInput(Allocation ain) {
+        if (ain.getType().getY() == 0) {
+            throw new RSIllegalArgumentException("Input set to a 1D Allocation");
+        }
         mInput = ain;
         setVar(1, ain);
     }
@@ -85,6 +88,9 @@
      *             type.
      */
     public void forEach(Allocation aout) {
+        if (aout.getType().getY() == 0) {
+            throw new RSIllegalArgumentException("Output is a 1D Allocation");
+        }
         forEach(0, (Allocation) null, aout, null);
     }
 
@@ -97,6 +103,9 @@
      * @param opt LaunchOptions for clipping
      */
     public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        if (aout.getType().getY() == 0) {
+            throw new RSIllegalArgumentException("Output is a 1D Allocation");
+        }
         forEach(0, (Allocation) null, aout, null, opt);
     }
 
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..2aeb07e 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.autofill;
 
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
+
 import static com.android.server.autofill.Helper.DEBUG;
 
 import android.annotation.NonNull;
@@ -88,7 +90,7 @@
 
     public interface FillServiceCallbacks {
         void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
-                @NonNull String servicePackageName, int requestId);
+                @NonNull String servicePackageName);
         void onFillRequestFailure(@Nullable CharSequence message,
                 @NonNull String servicePackageName);
         void onSaveRequestSuccess(@NonNull String servicePackageName);
@@ -134,6 +136,33 @@
         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.
+     *
+     * @return the id of the canceled request, or {@link FillRequest#INVALID_REQUEST_ID} if no
+     *         {@link PendingFillRequest} was canceled.
+     */
+    public int cancelCurrentRequest() {
+        if (mDestroyed) {
+            return INVALID_REQUEST_ID;
+        }
+
+        int requestId = INVALID_REQUEST_ID;
+        if (mPendingRequest != null) {
+            if (mPendingRequest instanceof PendingFillRequest) {
+                requestId = ((PendingFillRequest) mPendingRequest).mRequest.getId();
+            }
+
+            mPendingRequest.cancel();
+            mPendingRequest = null;
+        }
+
+        return requestId;
+    }
+
     public void onFillRequest(@NonNull FillRequest request) {
         cancelScheduledUnbind();
         final PendingFillRequest pendingRequest = new PendingFillRequest(request, this);
@@ -252,11 +281,11 @@
     }
 
     private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
-            int callingUid, FillResponse response, int requestId) {
+            int callingUid, FillResponse response) {
         mHandler.getHandler().post(() -> {
             if (handleResponseCallbackCommon(pendingRequest)) {
                 mCallbacks.onFillRequestSuccess(response, callingUid,
-                        mComponentName.getPackageName(), requestId);
+                        mComponentName.getPackageName());
             }
         });
     }
@@ -420,11 +449,11 @@
                 }
 
                 @Override
-                public void onSuccess(FillResponse response, int requestId) {
+                public void onSuccess(FillResponse response) {
                     RemoteFillService remoteService = mWeakService.get();
                     if (remoteService != null) {
                         remoteService.dispatchOnFillRequestSuccess(
-                                PendingFillRequest.this, getCallingUid(), response, requestId);
+                                PendingFillRequest.this, getCallingUid(), response);
                     }
                 }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 4bc3872..ac1f34d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -18,6 +18,9 @@
 package com.android.server.autofill;
 
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
+import static android.service.autofill.FillRequest.INVALID_REQUEST_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.FLAG_VALUE_CHANGED;
 import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
@@ -25,19 +28,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 +70,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 +93,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 +106,8 @@
 
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
+    private static AtomicInteger sIdCounter = new AtomicInteger();
+
     /** Id of the session */
     public final int id;
 
@@ -127,8 +135,7 @@
     @GuardedBy("mLock")
     private IAutoFillManagerClient mClient;
 
-    @GuardedBy("mLock")
-    RemoteFillService mRemoteFillService;
+    private final RemoteFillService mRemoteFillService;
 
     @GuardedBy("mLock")
     private SparseArray<FillResponse> mResponses;
@@ -146,11 +153,11 @@
     private Dataset mDatasetWaitingAuth;
 
     /**
-     * Assist structure sent by the app; it will be updated (sanitized, change values for save)
-     * before sent to {@link AutofillService}.
+     * Contexts read from the app; they will be updated (sanitized, change values for save) before
+     * sent to {@link AutofillService}. Ordered by the time they we read.
      */
     @GuardedBy("mLock")
-    private AssistStructure mStructure;
+    private ArrayList<FillContext> mContexts;
 
     /**
      * Whether the client has an {@link android.view.autofill.AutofillManager.AutofillCallback}.
@@ -167,7 +174,159 @@
     /**
      * 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);
+            }
+
+            final FillRequest request;
+            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);
+
+                if (mContexts == null) {
+                    mContexts = new ArrayList<>(1);
+                }
+                mContexts.add(new FillContext(requestId, structure));
+
+                cancelCurrentRequestLocked();
+
+                final int numContexts = mContexts.size();
+                for (int i = 0; i < numContexts; i++) {
+                    fillStructureWithAllowedValues(mContexts.get(i).getStructure());
+                }
+
+                request = new FillRequest(requestId, mContexts, 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);
+        }
+    }
+
+    /**
+     * Cancels the last request sent to the {@link #mRemoteFillService}.
+     */
+    private void cancelCurrentRequestLocked() {
+        int canceledRequest = mRemoteFillService.cancelCurrentRequest();
+
+        // Remove the FillContext as there will never be a response for the service
+        if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
+            int numContexts = mContexts.size();
+
+            // It is most likely the last context, hence search backwards
+            for (int i = numContexts - 1; i >= 0; i--) {
+                if (mContexts.get(i).getRequestId() == canceledRequest) {
+                    mContexts.remove(i);
+                    break;
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Reads a new structure and then request a new fill response from the fill service.
+     */
+    private void requestNewFillResponseLocked() {
+        int requestId;
+
+        do {
+            requestId = sIdCounter.getAndIncrement();
+        } while (requestId == INVALID_REQUEST_ID);
+
+        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.
+        cancelCurrentRequestLocked();
+
+        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,
@@ -231,7 +390,7 @@
     // FillServiceCallbacks
     @Override
     public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
-            @NonNull String servicePackageName, int requestId) {
+            @NonNull String servicePackageName) {
         if (response == null) {
             if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
                 getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
@@ -251,10 +410,10 @@
         }
         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);
+            processResponseLocked(response);
         }
 
         final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
@@ -310,12 +469,37 @@
         removeSelf();
     }
 
+    /**
+     * Gets the {@link FillContext} for a request.
+     *
+     * @param requestId The id of the request
+     *
+     * @return The context or {@code null} if there is no context
+     */
+    @Nullable private FillContext getFillContextByRequestIdLocked(int requestId) {
+        if (mContexts == null) {
+            return null;
+        }
+
+        int numContexts = mContexts.size();
+        for (int i = 0; i < numContexts; i++) {
+            FillContext context = mContexts.get(i);
+
+            if (context.getRequestId() == requestId) {
+                return context;
+            }
+        }
+
+        return null;
+    }
+
     // FillServiceCallbacks
     @Override
-    public void authenticate(IntentSender intent, Bundle extras) {
+    public void authenticate(int requestId, IntentSender intent, Bundle extras) {
         final Intent fillInIntent;
         synchronized (mLock) {
-            fillInIntent = createAuthFillInIntent(mStructure, extras);
+            fillInIntent = createAuthFillInIntent(
+                    getFillContextByRequestIdLocked(requestId).getStructure(), extras);
         }
 
         mService.setAuthenticationSelected();
@@ -326,13 +510,13 @@
     // FillServiceCallbacks
     @Override
     public void onServiceDied(RemoteFillService service) {
-        // TODO(b/33197203): implement
+        // TODO(b/337565347): implement
     }
 
     // AutoFillUiCallback
     @Override
-    public void fill(Dataset dataset) {
-        mHandlerCaller.getHandler().post(() -> autoFill(dataset));
+    public void fill(int requestId, Dataset dataset) {
+        mHandlerCaller.getHandler().post(() -> autoFill(requestId, dataset));
     }
 
     // AutoFillUiCallback
@@ -407,12 +591,14 @@
             final Parcelable result = data.getParcelable(
                     AutofillManager.EXTRA_AUTHENTICATION_RESULT);
             if (result instanceof FillResponse) {
+                FillResponse response = (FillResponse) result;
+
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
                 final int requestIndex = mResponses.indexOfValue(mResponseWaitingAuth);
                 mResponseWaitingAuth = null;
                 if (requestIndex >= 0) {
-                    final int requestId = mResponses.keyAt(requestIndex);
-                    processResponseLocked((FillResponse) result, requestId);
+                    response.setRequestId(mResponses.keyAt(requestIndex));
+                    processResponseLocked(response);
                 } else {
                     Slog.e(TAG, "Error cannot find id for auth response");
                 }
@@ -424,7 +610,7 @@
                     if (index >= 0) {
                         response.getDatasets().set(index, dataset);
                         mDatasetWaitingAuth = null;
-                        autoFill(dataset);
+                        autoFill(mResponses.keyAt(i), dataset);
                         resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
                         return;
                     }
@@ -437,18 +623,14 @@
         mHasCallback = hasIt;
     }
 
-    public void setStructureLocked(AssistStructure structure) {
-        mStructure = structure;
-    }
-
     /**
      * Shows the save UI, when session can be saved.
      *
      * @return {@code true} if session is done, or {@code false} if it's pending user action.
      */
     public boolean showSaveLocked() {
-        if (mStructure == null) {
-            Slog.d(TAG, "showSaveLocked(): no mStructure");
+        if (mContexts == null) {
+            Slog.d(TAG, "showSaveLocked(): no contexts");
             return true;
         }
         if (mResponses == null) {
@@ -470,7 +652,7 @@
         final FillResponse response = mResponses.valueAt(lastResponseIdx);
         final SaveInfo saveInfo = response.getSaveInfo();
         if (DEBUG) {
-            Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses
+            Slog.d(TAG, "showSaveLocked(): mResponses=" + mResponses + ", mContexts=" + mContexts
                     + ", mViewStates=" + mViewStates);
         }
 
@@ -570,64 +752,107 @@
             Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
         }
 
-        for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
-            final AutofillValue value = entry.getValue().getCurrentValue();
-            if (value == null) {
-                if (VERBOSE) {
-                    Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
-                }
-                continue;
-            }
-            final AutofillId id = entry.getKey();
-            final ViewNode node = findViewNodeByIdLocked(id);
-            if (node == null) {
-                Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
-                continue;
-            }
+        int numContexts = mContexts.size();
+
+        for (int i = 0; i < numContexts; i++) {
+            FillContext context = mContexts.get(i);
+
             if (VERBOSE) {
-                Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
+                Slog.v(TAG, "callSaveLocked(): updating " + context);
             }
 
-            node.updateAutofillValue(value);
+            for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
+                final AutofillValue value = entry.getValue().getCurrentValue();
+                if (value == null) {
+                    if (VERBOSE) {
+                        Slog.v(TAG, "callSaveLocked(): skipping " + entry.getKey());
+                    }
+                    continue;
+                }
+                final AutofillId id = entry.getKey();
+                final ViewNode node = findViewNodeById(context.getStructure(), id);
+                if (node == null) {
+                    Slog.w(TAG, "callSaveLocked(): did not find node with id " + id);
+                    continue;
+                }
+                if (VERBOSE) {
+                    Slog.v(TAG, "callSaveLocked(): updating " + id + " to " + value);
+                }
+
+                node.updateAutofillValue(value);
+            }
+
+            // Sanitize structure before it's sent to service.
+            context.getStructure().sanitizeForParceling(false);
+
+            if (VERBOSE) {
+                Slog.v(TAG, "Dumping structure of " + context + " before calling service.save()");
+                context.getStructure().dump();
+            }
         }
 
-        // Sanitize structure before it's sent to service.
-        mStructure.sanitizeForParceling(false);
+        // Remove pending fill requests as the session is finished.
+        cancelCurrentRequestLocked();
 
-        if (VERBOSE) {
-            Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
-            mStructure.dump();
-        }
-
-        // TODO(b/33197203): Implement partitioning properly
-        final int lastResponseIdx = getLastResponseIndex();
-        final int requestId = mResponses.keyAt(lastResponseIdx);
-        final FillContext fillContext = new FillContext(requestId, mStructure);
-        final ArrayList<FillContext> fillContexts = new ArrayList<>(1);
-        fillContexts.add(fillContext);
-
-        final SaveRequest saveRequest = new SaveRequest(fillContexts, mClientState);
+        final SaveRequest saveRequest = new SaveRequest(mContexts, mClientState);
         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 +864,7 @@
             mCurrentViewId = viewState.id;
             viewState.update(value, virtualBounds);
             viewState.setState(ViewState.STATE_STARTED_SESSION);
+            requestNewFillResponseLocked();
             return;
         }
 
@@ -668,6 +894,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 +930,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 +947,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);
@@ -799,7 +990,7 @@
         }
     }
 
-    private void processResponseLocked(FillResponse response, int requestId) {
+    private void processResponseLocked(@NonNull FillResponse response) {
         if (DEBUG) {
             Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
         }
@@ -807,10 +998,8 @@
         if (mResponses == null) {
             mResponses = new SparseArray<>(4);
         }
-        mResponses.put(requestId, response);
-        if (response != null) {
-            mClientState = response.getClientState();
-        }
+        mResponses.put(response.getRequestId(), response);
+        mClientState = response.getClientState();
 
         setViewStatesLocked(response, ViewState.STATE_FILLABLE);
         updateTrackedIdsLocked();
@@ -822,7 +1011,7 @@
         if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
                 && response.getDatasets().size() == 1) {
             Slog.d(TAG, "autofilling manual request directly");
-            autoFill(response.getDatasets().get(0));
+            autoFill(response.getRequestId(), response.getDatasets().get(0));
             return;
         }
 
@@ -911,7 +1100,7 @@
         }
     }
 
-    void autoFill(Dataset dataset) {
+    void autoFill(int requestId, Dataset dataset) {
         synchronized (mLock) {
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
@@ -922,11 +1111,12 @@
             }
 
             // ...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);
-            final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
+            final Intent fillInIntent = createAuthFillInIntent(
+                    getFillContextByRequestIdLocked(requestId).getStructure(), null);
             startAuthentication(dataset.getAuthentication(), fillInIntent);
         }
     }
@@ -958,23 +1148,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);
@@ -990,16 +1163,25 @@
             pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
             entry.getValue().dump(prefix2, pw);
         }
-        if (VERBOSE) {
-            pw.print(prefix); pw.print("mStructure: " );
-            // TODO(b/33197203): add method do dump AssistStructure on pw
-            if (mStructure != null) {
-                pw.println("look at logcat" );
-                mStructure.dump(); // dumps to logcat
-            } else {
-                pw.println("null");
+
+        pw.print(prefix); pw.print("mContexts: " );
+        if (mContexts != null) {
+            int numContexts = mContexts.size();
+            for (int i = 0; i < numContexts; i++) {
+                FillContext context = mContexts.get(i);
+
+                pw.print(prefix2); pw.print(context);
+                if (VERBOSE) {
+                    pw.println(context.getStructure() + " (look at logcat)");
+
+                    // TODO: add method on AssistStructure to dump on pw
+                    context.getStructure().dump();
+                }
             }
+        } else {
+            pw.println("null");
         }
+
         pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
         pw.print(prefix); pw.print("mClientState: "); pw.println(
                 Helper.bundleToString(mClientState));
@@ -1027,39 +1209,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/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index ab6a3a7..0556c67 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -60,8 +60,8 @@
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
-        void authenticate(@NonNull IntentSender intent, @Nullable Bundle extras);
-        void fill(@NonNull Dataset dataset);
+        void authenticate(int requestId, @NonNull IntentSender intent, @Nullable Bundle extras);
+        void fill(int requestId, @NonNull Dataset dataset);
         void save();
         void cancelSave();
         void requestShowFillUi(AutofillId id, int width, int height,
@@ -161,8 +161,8 @@
                     log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
                     hideFillUiUiThread();
                     if (mCallback != null) {
-                        mCallback.authenticate(response.getAuthentication(),
-                                response.getClientState());
+                        mCallback.authenticate(response.getRequestId(),
+                                response.getAuthentication(), response.getClientState());
                     }
                 }
 
@@ -171,7 +171,7 @@
                     log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
                     hideFillUiUiThread();
                     if (mCallback != null) {
-                        mCallback.fill(dataset);
+                        mCallback.fill(response.getRequestId(), dataset);
                     }
                 }
 
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/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index f94d456..cbaaef7 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -24,6 +24,7 @@
 import android.content.IntentSender;
 import android.os.Handler;
 import android.service.autofill.SaveInfo;
+import android.text.Html;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.view.Gravity;
@@ -125,23 +126,24 @@
             types.add(context.getString(R.string.autofill_save_type_email_address));
         }
 
-        final String title;
+        final CharSequence title;
         switch (types.size()) {
             case 1:
-                title = context.getString(R.string.autofill_save_title_with_type,
-                        types.valueAt(0), providerLabel);
+                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_type,
+                        types.valueAt(0), providerLabel), 0);
                 break;
             case 2:
-                title = context.getString(R.string.autofill_save_title_with_2types,
-                        types.valueAt(0), types.valueAt(1), providerLabel);
+                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_2types,
+                        types.valueAt(0), types.valueAt(1), providerLabel), 0);
                 break;
             case 3:
-                title = context.getString(R.string.autofill_save_title_with_3types,
-                        types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel);
+                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_3types,
+                        types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel), 0);
                 break;
             default:
                 // Use generic if more than 3 or invalid type (size 0).
-                title = context.getString(R.string.autofill_save_title, providerLabel);
+                title = Html.fromHtml(
+                        context.getString(R.string.autofill_save_title, providerLabel), 0);
         }
 
         titleView.setText(title);
@@ -157,19 +159,20 @@
         }
 
         final TextView noButton = view.findViewById(R.id.autofill_save_no);
-        if (info.getNegativeActionTitle() != null) {
-            noButton.setText(info.getNegativeActionTitle());
-            noButton.setOnClickListener((v) -> mListener.onCancel(
-                    info.getNegativeActionListener()));
+        if (info.getNegativeActionStyle() == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT) {
+            noButton.setText(R.string.save_password_notnow);
         } else {
-            noButton.setOnClickListener((v) -> mListener.onCancel(null));
+            noButton.setText(R.string.autofill_save_no);
         }
+        noButton.setOnClickListener((v) -> mListener.onCancel(
+                info.getNegativeActionListener()));
 
         final View yesButton = view.findViewById(R.id.autofill_save_yes);
         yesButton.setOnClickListener((v) -> mListener.onSave());
 
         final View closeButton = view.findViewById(R.id.autofill_save_close);
-        closeButton.setOnClickListener((v) -> mListener.onCancel(null));
+        closeButton.setOnClickListener((v) -> mListener.onCancel(
+                info.getNegativeActionListener()));
 
         mDialog = new Dialog(context, R.style.Theme_Material_Panel);
         mDialog.setContentView(view);
@@ -183,7 +186,9 @@
         window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
         window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
         window.setCloseOnTouchOutside(true);
-        window.getAttributes().width = WindowManager.LayoutParams.MATCH_PARENT;
+        final WindowManager.LayoutParams params = window.getAttributes();
+        params.width = WindowManager.LayoutParams.MATCH_PARENT;
+        params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
 
         mDialog.show();
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index aa5083d..1b970e5 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2625,8 +2625,12 @@
                 // Can't delete op from mCurrentOperations here. waitUntilOperationComplete may be
                 // called after we receive cancel here. We need this op's state there.
 
-                // Remove all pending timeout messages for this operation type.
-                mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+                // Remove all pending timeout messages of types OP_TYPE_BACKUP_WAIT and
+                // OP_TYPE_RESTORE_WAIT. On the other hand, OP_TYPE_BACKUP cannot time out and
+                // doesn't require cancellation.
+                if (op.type == OP_TYPE_BACKUP_WAIT || op.type == OP_TYPE_RESTORE_WAIT) {
+                    mBackupHandler.removeMessages(getMessageIdForOperationType(op.type));
+                }
             }
             mCurrentOpLock.notifyAll();
         }
@@ -5637,14 +5641,24 @@
     // The job scheduler says our constraints don't hold any more,
     // so tear down any ongoing backup task right away.
     void endFullBackup() {
-        synchronized (mQueueLock) {
-            if (mRunningFullBackupTask != null) {
-                if (DEBUG_SCHEDULING) {
-                    Slog.i(TAG, "Telling running backup to stop");
+        // offload the mRunningFullBackupTask.handleCancel() call to another thread,
+        // as we might have to wait for mCancelLock
+        Runnable endFullBackupRunnable = new Runnable() {
+            @Override
+            public void run() {
+                PerformFullTransportBackupTask pftbt = null;
+                synchronized (mQueueLock) {
+                    if (mRunningFullBackupTask != null) {
+                        if (DEBUG_SCHEDULING) {
+                            Slog.i(TAG, "Telling running backup to stop");
+                        }
+                        pftbt = mRunningFullBackupTask;
+                    }
                 }
-                mRunningFullBackupTask.handleCancel(true);
+                pftbt.handleCancel(true);
             }
-        }
+        };
+        new Thread(endFullBackupRunnable, "end-full-backup").start();
     }
 
     // ----- Restore infrastructure -----
@@ -9187,6 +9201,9 @@
 
         // state RESTORE_FINISHED : provide the "no more data" signpost callback at the end
         private void restoreFinished() {
+            if (DEBUG) {
+                Slog.d(TAG, "restoreFinished packageName=" + mCurrentPackage.packageName);
+            }
             try {
                 prepareOperationTimeout(mEphemeralOpToken, TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
                         OP_TYPE_RESTORE_WAIT);
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/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 21dae4f..05ffcf0 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1239,6 +1239,11 @@
                     mAllowWhileIdleDispatches.add(ent);
                 }
             }
+            if ((mPendingIdleUntil != a) && (mPendingIdleUntil != null)) {
+                Slog.wtfStack(TAG, "setImplLocked: idle until changed from " + mPendingIdleUntil
+                        + " to " + a);
+            }
+
             mPendingIdleUntil = a;
             mConstants.updateAllowWhileIdleMinTimeLocked();
             needRebatch = true;
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 6c4895c..6c18b26 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -308,6 +308,14 @@
                 if (newName != null) {
                     storeNameAndAddress(newName, null);
                 }
+            } else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
+                String newAddress = intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
+                if (newAddress != null) {
+                    if (DBG) Slog.d(TAG, "Bluetooth Adapter address changed to " + newAddress);
+                    storeNameAndAddress(null, newAddress);
+                } else {
+                    if (DBG) Slog.e(TAG, "No Bluetooth Adapter address parameter found");
+                }
             }
         }
     };
@@ -343,6 +351,9 @@
         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
         filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         mContext.registerReceiver(mReceiver, filter);
+        filter = new IntentFilter(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
+        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiver(mReceiver, filter);
         loadStoredNameAndAddress();
         if (isBluetoothPersistedStateOn()) {
             if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON.");
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 3a24091..a184d70 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -961,8 +961,7 @@
                     if (pi.isManagedProfile()
                             && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
                             && mStorage.hasChildProfileLock(pi.id)
-                            && mUserManager.isUserRunning(pi.id)
-                            && !mUserManager.isUserUnlocked(pi.id)) {
+                            && mUserManager.isUserRunning(pi.id)) {
                         unlockChildProfile(pi.id);
                     }
                 }
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/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index dd4d906..4ce76f4 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1531,6 +1531,9 @@
             intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
         }
 
+        // Wakeup apps for the (SUBSCRIPTION_)PHONE_STATE broadcast.
+        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+
         // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those
         // that have the runtime one
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 80f89fc..feb9ce4 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -83,6 +83,7 @@
         "android.hardware.audio@2.0::IDevicesFactory",
         "android.hardware.bluetooth@1.0::IBluetoothHci",
         "android.hardware.camera.provider@2.4::ICameraProvider",
+        "android.hardware.graphics.composer@2.1::IComposer",
         "android.hardware.vr@1.0::IVr",
         "android.hardware.media.omx@1.0::IOmx"
     );
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index eb58e4c..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);
@@ -5006,7 +5080,7 @@
             INotificationManager notificationManager = mInjector.getNotificationManager();
             try {
                 notificationManager.enqueueNotificationWithTag(packageName, packageName,
-                        id.mTag, id.mId, notification, new int[1], userId);
+                        id.mTag, id.mId, notification, userId);
             } catch (RemoteException e) {
                 /* ignore - local call */
             }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3fe8a1e..c6e44e0 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1728,7 +1728,7 @@
             return null;
         }
 
-        if (!whileRestarting && r.restartDelay > 0) {
+        if (!whileRestarting && mRestartingServices.contains(r)) {
             // If waiting for a restart, then do nothing.
             return null;
         }
@@ -1740,7 +1740,6 @@
         // We are now bringing the service up, so no longer in the
         // restarting state.
         if (mRestartingServices.remove(r)) {
-            r.resetRestartCounter();
             clearRestartingIfNeededLocked(r);
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 98b31c0..01ef01b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -358,6 +358,7 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.server.job.JobSchedulerInternal;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
@@ -410,6 +411,7 @@
 import com.android.server.pm.Installer.InstallerException;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.vr.VrManagerInternal;
+import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -2114,10 +2116,9 @@
                                     new UserHandle(root.userId)))
                             .build();
                     try {
-                        int[] outId = new int[1];
                         inm.enqueueNotificationWithTag("android", "android", null,
                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
-                                notification, outId, root.userId);
+                                notification, root.userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error showing notification for heavy-weight app", e);
@@ -2369,10 +2370,9 @@
                         .build();
 
                 try {
-                    int[] outId = new int[1];
                     inm.enqueueNotificationWithTag("android", "android", null,
                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
-                            notification, outId, userId);
+                            notification, userId);
                 } catch (RuntimeException e) {
                     Slog.w(ActivityManagerService.TAG,
                             "Error showing notification for dump heap", e);
@@ -7819,10 +7819,15 @@
         try {
             synchronized(this) {
                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
-                if (stack == null) {
+                if (stack == null || stack.mStackId != PINNED_STACK_ID) {
                     return false;
                 }
-                return stack.mStackId == PINNED_STACK_ID;
+
+                // If we are animating to fullscreen then we have already dispatched the PIP mode
+                // changed, so we should reflect that check here as well.
+                final PinnedStackWindowController windowController =
+                        ((PinnedActivityStack) stack).getWindowContainerController();
+                return !windowController.isAnimatingBoundsToFullscreen();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -11256,9 +11261,13 @@
                     holder.provider = null;
                     return holder;
                 }
-                // Don't expose instant app providers
-                if (cpr.appInfo.isInstantApp()) {
-                    return null;
+                // Don't expose providers between normal apps and instant apps
+                try {
+                    if (AppGlobals.getPackageManager()
+                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
+                        return null;
+                    }
+                } catch (RemoteException e) {
                 }
 
                 final long origId = Binder.clearCallingIdentity();
@@ -18181,6 +18190,9 @@
             return false;
         }
 
+        int oldBackupUid;
+        int newBackupUid;
+
         synchronized(this) {
             // !!! TODO: currently no check here that we're already bound
             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
@@ -18221,6 +18233,8 @@
                 proc.inFullBackup = true;
             }
             r.app = proc;
+            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
+            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
             mBackupTarget = r;
             mBackupAppName = app.packageName;
 
@@ -18246,6 +18260,14 @@
             // know that it's scheduled for a backup-agent operation.
         }
 
+        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
+        if (oldBackupUid != -1) {
+            js.removeBackingUpUid(oldBackupUid);
+        }
+        if (newBackupUid != -1) {
+            js.addBackingUpUid(newBackupUid);
+        }
+
         return true;
     }
 
@@ -18258,6 +18280,9 @@
             mBackupTarget = null;
             mBackupAppName = null;
         }
+
+        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
+        js.clearAllBackingUpUids();
     }
 
     // A backup agent has just come up
@@ -18295,6 +18320,8 @@
             return;
         }
 
+        int oldBackupUid;
+
         synchronized(this) {
             try {
                 if (mBackupAppName == null) {
@@ -18312,6 +18339,8 @@
                 updateOomAdjLocked(proc);
                 proc.inFullBackup = false;
 
+                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
+
                 // If the app crashed during backup, 'thread' will be null here
                 if (proc.thread != null) {
                     try {
@@ -18327,7 +18356,13 @@
                 mBackupAppName = null;
             }
         }
+
+        if (oldBackupUid != -1) {
+            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
+            js.removeBackingUpUid(oldBackupUid);
+        }
     }
+
     // =========================================================
     // BROADCASTS
     // =========================================================
@@ -19121,6 +19156,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/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 494aaa7..2dd3b74 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -133,7 +133,7 @@
      */
     void notifyActivityLaunching() {
         if (!isAnyTransitionActive()) {
-            mCurrentTransitionStartTime = System.currentTimeMillis();
+            mCurrentTransitionStartTime = SystemClock.uptimeMillis();
         }
     }
 
@@ -254,8 +254,7 @@
      *                       ActivityManagerInternal.APP_TRANSITION_* reasons.
      */
     void notifyTransitionStarting(SparseIntArray stackIdReasons) {
-        // TODO (b/36339388): Figure out why stackIdReasons can be null
-        if (stackIdReasons == null || !isAnyTransitionActive() || mLoggedTransitionStarting) {
+        if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
             return;
         }
         mCurrentTransitionDelayMs = calculateCurrentDelay();
@@ -300,7 +299,7 @@
     private int calculateCurrentDelay() {
 
         // Shouldn't take more than 25 days to launch an app, so int is fine here.
-        return (int) (System.currentTimeMillis() - mCurrentTransitionStartTime);
+        return (int) (SystemClock.uptimeMillis() - mCurrentTransitionStartTime);
     }
 
     private void logAppTransitionMultiEvents() {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 43904d6..5f55411 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -62,12 +62,15 @@
 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;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SCREENSHOTS;
@@ -138,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;
@@ -239,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
@@ -273,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?
@@ -343,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) {
@@ -397,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());
@@ -522,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=");
@@ -798,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;
@@ -1163,6 +1162,17 @@
     }
 
     /**
+     * Check whether this activity can be launched on the specified display.
+     * @param displayId Target display id.
+     * @return {@code true} if either it is the default display or this activity is resizeable and
+     *         can be put a secondary screen.
+     */
+    boolean canBeLaunchedOnDisplay(int displayId) {
+        return service.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
+                supportsResizeableMultiWindow());
+    }
+
+    /**
      * @param beforeStopping Whether this check is for an auto-enter-pip operation, that is to say
      *         the activity has requested to enter PiP when it would otherwise be stopped.
      *
@@ -1555,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);
@@ -2179,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. */
@@ -2195,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
@@ -2211,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);
     }
 
     /**
@@ -2250,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);
         }
 
@@ -2325,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;
@@ -2338,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,
@@ -2383,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 824ec68..728a3b9 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -23,6 +23,7 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
@@ -800,6 +801,10 @@
         return mStackId == HOME_STACK_ID;
     }
 
+    final boolean isRecentsStack() {
+        return mStackId == RECENTS_STACK_ID;
+    }
+
     final boolean isHomeOrRecentsStack() {
         return StackId.isHomeOrRecentsStack(mStackId);
     }
@@ -1401,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 */);
@@ -2019,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:
@@ -2048,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 */);
                     }
@@ -2338,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 ab70340..bff3ce3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -33,6 +33,8 @@
 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
+import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
+import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -108,6 +110,7 @@
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
 import android.app.IActivityContainerCallback;
+import android.app.ITaskStackListener;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.StatusBarManager;
@@ -159,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;
@@ -485,6 +489,33 @@
         activityDisplay.onOverrideConfigurationChanged(overrideConfiguration);
     }
 
+    /** Check if placing task or activity on specified display is allowed. */
+    boolean canPlaceEntityOnDisplay(int displayId, boolean resizeable) {
+        return displayId == DEFAULT_DISPLAY || (mService.mSupportsMultiDisplay
+                && (resizeable || displayConfigMatchesGlobal(displayId)));
+    }
+
+    /**
+     * Check if configuration of specified display matches current global config.
+     * Used to check if we can put a non-resizeable activity on a secondary display and it will get
+     * the same config as on the default display.
+     * @param displayId Id of the display to check.
+     * @return {@code true} if configuration matches.
+     */
+    private boolean displayConfigMatchesGlobal(int displayId) {
+        if (displayId == DEFAULT_DISPLAY) {
+            return true;
+        }
+        if (displayId == INVALID_DISPLAY) {
+            return false;
+        }
+        final ActivityDisplay targetDisplay = mActivityDisplays.get(displayId);
+        if (targetDisplay == null) {
+            throw new IllegalArgumentException("No display found with id: " + displayId);
+        }
+        return getConfiguration().equals(targetDisplay.getConfiguration());
+    }
+
     static class FindTaskResult {
         ActivityRecord r;
         boolean matchedByRootAffinity;
@@ -1413,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);
@@ -2104,8 +2134,8 @@
         if (DEBUG_STACK) Slog.d(TAG_STACK,
                 "findTaskToMoveToFront: moved to front of stack=" + currentStack);
 
-        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, currentStack.mStackId,
-                forceNonResizeable);
+        handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY,
+                currentStack.mStackId, forceNonResizeable);
     }
 
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options, int launchStackId) {
@@ -2156,7 +2186,7 @@
         // Return the topmost valid stack on the display.
         for (int i = activityDisplay.mStacks.size() - 1; i >= 0; --i) {
             final ActivityStack stack = activityDisplay.mStacks.get(i);
-            if (mService.mActivityStarter.isValidLaunchStackId(stack.mStackId, r)) {
+            if (mService.mActivityStarter.isValidLaunchStackId(stack.mStackId, displayId, r)) {
                 return stack;
             }
         }
@@ -2164,7 +2194,7 @@
         // If there is no valid stack on the external display - check if new dynamic stack will do.
         if (displayId != Display.DEFAULT_DISPLAY) {
             final int newDynamicStackId = getNextStackId();
-            if (mService.mActivityStarter.isValidLaunchStackId(newDynamicStackId, r)) {
+            if (mService.mActivityStarter.isValidLaunchStackId(newDynamicStackId, displayId, r)) {
                 return createStackOnDisplay(newDynamicStackId, displayId, true /*onTop*/);
             }
         }
@@ -2995,8 +3025,9 @@
             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = stacks.get(stackNdx);
-                if (!r.isApplicationActivity() && !stack.isHomeOrRecentsStack()) {
-                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
+                if (!checkActivityBelongsInStack(r, stack)) {
+                    if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) "
+                            + stack);
                     continue;
                 }
                 if (!stack.mActivityContainer.isEligibleForNewTasks()) {
@@ -3023,6 +3054,21 @@
         return affinityMatch;
     }
 
+    /**
+     * Checks that for the given activity {@param r}, its activity type matches the {@param stack}
+     * type.
+     */
+    private boolean checkActivityBelongsInStack(ActivityRecord r, ActivityStack stack) {
+        if (r.isHomeActivity()) {
+            return stack.isHomeStack();
+        } else if (r.isRecentsActivity()) {
+            return stack.isRecentsStack();
+        } else if (r.isAssistantActivity()) {
+            return stack.isAssistantStack();
+        }
+        return true;
+    }
+
     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
                                       boolean compareIntentFilters) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -3987,31 +4033,68 @@
         }
     }
 
-    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId, int actualStackId) {
-        handleNonResizableTaskIfNeeded(task, preferredStackId, actualStackId,
+    void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId,
+            int preferredDisplayId, int actualStackId) {
+        handleNonResizableTaskIfNeeded(task, preferredStackId, preferredDisplayId, actualStackId,
                 false /* forceNonResizable */);
     }
 
-    void handleNonResizableTaskIfNeeded(
-            TaskRecord task, int preferredStackId, int actualStackId, boolean forceNonResizable) {
-        if ((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
-                || task.isHomeTask()) {
+    private void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredStackId,
+            int preferredDisplayId, int actualStackId, boolean forceNonResizable) {
+        final boolean isSecondaryDisplayPreferred =
+                (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY)
+                || StackId.isDynamicStack(preferredStackId);
+        if (((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
+                && !isSecondaryDisplayPreferred) || task.isHomeTask()) {
             return;
         }
 
+        // Handle incorrect launch/move to secondary display if needed.
+        final boolean launchOnSecondaryDisplayFailed;
+        if (isSecondaryDisplayPreferred) {
+            final int actualDisplayId = task.getStack().mDisplayId;
+            if (!task.canBeLaunchedOnDisplay(actualDisplayId)) {
+                // The task landed on an inappropriate display somehow, move it to the default
+                // display.
+                // TODO(multi-display): Find proper stack for the task on the default display.
+                mService.moveTaskToStack(task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
+                        true /* toTop */);
+                launchOnSecondaryDisplayFailed = true;
+            } else {
+                // The task might have landed on a display different from requested.
+                launchOnSecondaryDisplayFailed = actualDisplayId == DEFAULT_DISPLAY
+                        || (preferredDisplayId != INVALID_DISPLAY
+                            && preferredDisplayId != actualDisplayId);
+            }
+        } else {
+            // The task wasn't requested to be on a secondary display.
+            launchOnSecondaryDisplayFailed = false;
+        }
+
         final ActivityRecord topActivity = task.getTopActivity();
-        if (!task.supportsSplitScreen() || forceNonResizable) {
-            // Display a warning toast that we tried to put a non-dockable task in the docked stack.
-            mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack();
+        if (launchOnSecondaryDisplayFailed || !task.supportsSplitScreen() || forceNonResizable) {
+            if (launchOnSecondaryDisplayFailed) {
+                // Display a warning toast that we tried to put a non-resizeable task on a secondary
+                // display with config different from global config.
+                mService.mTaskChangeNotificationController
+                        .notifyActivityLaunchOnSecondaryDisplayFailed();
+            } else {
+                // Display a warning toast that we tried to put a non-dockable task in the docked
+                // stack.
+                mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack();
+            }
 
             // Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
             // we need to move it to top of fullscreen stack, otherwise it will be covered.
             moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID);
         } else if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
                 && !topActivity.noDisplay) {
-            String packageName = topActivity.appInfo.packageName;
+            final String packageName = topActivity.appInfo.packageName;
+            final int reason = isSecondaryDisplayPreferred
+                    ? FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY
+                    : FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
             mService.mTaskChangeNotificationController.notifyActivityForcedResizable(
-                    task.taskId, packageName);
+                    task.taskId, reason, packageName);
         }
     }
 
@@ -4084,8 +4167,8 @@
             resumeFocusedStackTopActivityLocked();
             mWindowManager.executeAppTransition();
         } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
-            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, task.getStackId(),
-                    true /* forceNonResizable */);
+            handleNonResizableTaskIfNeeded(task, INVALID_STACK_ID, DEFAULT_DISPLAY,
+                    task.getStackId(), true /* forceNonResizable */);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 56594d3..1f4b21b1 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -979,6 +979,8 @@
 
         final int preferredLaunchStackId =
                 (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
+        final int preferredLaunchDisplayId =
+                (mOptions != null) ? mOptions.getLaunchDisplayId() : DEFAULT_DISPLAY;
 
         if (reusedActivity != null) {
             // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
@@ -1100,8 +1102,8 @@
 
             // Don't use mStartActivity.task to show the toast. We're not starting a new activity
             // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
-            mSupervisor.handleNonResizableTaskIfNeeded(
-                    top.getTask(), preferredLaunchStackId, topStack.mStackId);
+            mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
+                    preferredLaunchDisplayId, topStack.mStackId);
 
             return START_DELIVERED_TO_TOP;
         }
@@ -1183,8 +1185,8 @@
         }
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
 
-        mSupervisor.handleNonResizableTaskIfNeeded(
-                mStartActivity.getTask(), preferredLaunchStackId, mTargetStack.mStackId);
+        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
+                preferredLaunchDisplayId, mTargetStack.mStackId);
 
         return START_SUCCESS;
     }
@@ -1580,7 +1582,7 @@
         }
 
         mSupervisor.handleNonResizableTaskIfNeeded(intentActivity.getTask(), INVALID_STACK_ID,
-                mTargetStack.mStackId);
+                DEFAULT_DISPLAY, mTargetStack.mStackId);
 
         // If the caller has requested that the target task be reset, then do so.
         if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
@@ -2033,16 +2035,19 @@
                 canUseFocusedStack = r.isAssistantActivity();
                 break;
             case DOCKED_STACK_ID:
-                // Any activty which supports split screen can go in the docked stack.
+                // Any activity which supports split screen can go in the docked stack.
                 canUseFocusedStack = r.supportsSplitScreen();
                 break;
             case FREEFORM_WORKSPACE_STACK_ID:
-                // Any activty which supports freeform can go in the freeform stack.
+                // Any activity which supports freeform can go in the freeform stack.
                 canUseFocusedStack = r.supportsFreeform();
                 break;
             default:
-                // Dynamic stacks behave similarly to the fullscreen stack and can contain any task.
-                canUseFocusedStack = isDynamicStack(focusedStackId);
+                // Dynamic stacks behave similarly to the fullscreen stack and can contain any
+                // resizeable task.
+                // TODO: Check ActivityView after fixing b/35349678.
+                canUseFocusedStack = isDynamicStack(focusedStackId)
+                        && r.canBeLaunchedOnDisplay(focusedStack.mDisplayId);
         }
 
         return canUseFocusedStack
@@ -2082,7 +2087,7 @@
                     "Stack and display id can't be set at the same time.");
         }
 
-        if (isValidLaunchStackId(launchStackId, r)) {
+        if (isValidLaunchStackId(launchStackId, launchDisplayId, r)) {
             return mSupervisor.getStack(launchStackId, CREATE_IF_NEEDED, ON_TOP);
         }
         if (launchStackId == DOCKED_STACK_ID) {
@@ -2148,7 +2153,7 @@
         }
     }
 
-    boolean isValidLaunchStackId(int stackId, ActivityRecord r) {
+    boolean isValidLaunchStackId(int stackId, int displayId, ActivityRecord r) {
         switch (stackId) {
             case INVALID_STACK_ID:
             case HOME_STACK_ID:
@@ -2167,8 +2172,8 @@
                 return r.isAssistantActivity();
             default:
                 // TODO: Check ActivityView after fixing b/35349678.
-                if (StackId.isDynamicStack(stackId) && mService.mSupportsMultiDisplay) {
-                    return true;
+                if (StackId.isDynamicStack(stackId)) {
+                    return r.canBeLaunchedOnDisplay(displayId);
                 }
                 Slog.e(TAG, "isValidLaunchStackId: Unexpected stackId=" + stackId);
                 return false;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 349180f..d08298b 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1180,7 +1180,7 @@
                 skip = true;
             }
             if (!skip && r.callerInstantApp
-                    && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0
+                    && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
                     && r.callingUid != info.activityInfo.applicationInfo.uid) {
                 Slog.w(TAG, "Instant App Denial: receiving "
                         + r.intent
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 2bd119e..dd16e22 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -204,12 +204,11 @@
         mOccluded = false;
         mDismissingKeyguardActivity = null;
         final ArrayList<ActivityStack> stacks = mStackSupervisor.getStacksOnDefaultDisplay();
-        final int topStackNdx = stacks.size() - 1;
-        for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
+        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
             final ActivityStack stack = stacks.get(stackNdx);
 
-            // Only the very top activity may control occluded state
-            if (stackNdx == topStackNdx) {
+            // Only the focused stack top activity may control occluded state
+            if (mStackSupervisor.isFocusedStack(stack)) {
 
                 // A dismissing activity occludes Keyguard in the insecure case for legacy reasons.
                 final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index b57f6c3..cffa475 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -524,10 +524,9 @@
                             throw new RuntimeException("invalid service notification: "
                                     + foregroundNoti);
                         }
-                        int[] outId = new int[1];
                         nm.enqueueNotification(localPackageName, localPackageName,
                                 appUid, appPid, null, localForegroundId, localForegroundNoti,
-                                outId, userId);
+                                userId);
 
                         foregroundNoti = localForegroundNoti; // save it for amending next time
                     } catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 94cf092..7d2bc5b 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -48,6 +48,7 @@
     static final int NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG = 15;
     static final int NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG = 16;
     static final int NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG = 17;
+    static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG = 18;
 
     // Delay in notifying task stack change listeners (in millis)
     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -115,13 +116,17 @@
     };
 
     private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
-        l.onActivityForcedResizable((String) m.obj, m.arg1);
+        l.onActivityForcedResizable((String) m.obj, m.arg1, m.arg2);
     };
 
     private final TaskStackConsumer mNotifyActivityDismissingDockedStack = (l, m) -> {
         l.onActivityDismissingDockedStack();
     };
 
+    private final TaskStackConsumer mNotifyActivityLaunchOnSecondaryDisplayFailed = (l, m) -> {
+        l.onActivityLaunchOnSecondaryDisplayFailed();
+    };
+
     private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
         l.onTaskProfileLocked(m.arg1, m.arg2);
     };
@@ -191,6 +196,9 @@
                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
                     forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
                     break;
+                case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG:
+                    forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
+                    break;
                 case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
                     forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
                     break;
@@ -324,14 +332,22 @@
         forAllLocalListeners(mNotifyActivityDismissingDockedStack, message);
     }
 
-    void notifyActivityForcedResizable(int taskId, String packageName) {
+    void notifyActivityForcedResizable(int taskId, int reason, String packageName) {
         mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
-        final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId,
-                0 /* unused */, packageName);
+        final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, reason,
+                packageName);
         forAllLocalListeners(mNotifyActivityForcedResizable, msg);
         msg.sendToTarget();
     }
 
+    void notifyActivityLaunchOnSecondaryDisplayFailed() {
+        mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
+        final Message msg = mHandler.obtainMessage(
+                NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
+        forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
+        msg.sendToTarget();
+    }
+
     void notifyTaskCreated(int taskId, ComponentName componentName) {
         final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
                 taskId, 0 /* unused */, componentName);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index d42b6a7..056fec5 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -97,6 +97,8 @@
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
@@ -748,7 +750,8 @@
             supervisor.resumeFocusedStackTopActivityLocked();
         }
 
-        supervisor.handleNonResizableTaskIfNeeded(this, preferredStackId, stackId);
+        // TODO: Handle incorrect request to move before the actual move, not after.
+        supervisor.handleNonResizableTaskIfNeeded(this, preferredStackId, DEFAULT_DISPLAY, stackId);
 
         boolean successful = (preferredStackId == stackId);
         if (successful && stackId == DOCKED_STACK_ID) {
@@ -1561,6 +1564,17 @@
     }
 
     /**
+     * Check whether this task can be launched on the specified display.
+     * @param displayId Target display id.
+     * @return {@code true} if either it is the default display or this activity is resizeable and
+     *         can be put a secondary screen.
+     */
+    boolean canBeLaunchedOnDisplay(int displayId) {
+        return mService.mStackSupervisor.canPlaceEntityOnDisplay(displayId,
+                isResizeable(false /* checkSupportsPip */));
+    }
+
+    /**
      * Check that a given bounds matches the application requested orientation.
      *
      * @param bounds The bounds to be tested.
@@ -2198,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 d2d69cb..742ee35 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5189,7 +5189,9 @@
     }
 
     // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only
-    // sent if none of these devices is connected.
+    // sent if:
+    // - none of these devices are connected anymore after one is disconnected AND
+    // - the device being disconnected is actually used for music.
     // Access synchronized on mConnectedDevices
     int mBecomingNoisyIntentDevices =
             AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
@@ -5210,7 +5212,8 @@
                     devices |= dev;
                 }
             }
-            if (devices == device) {
+            int musicDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC);
+            if ((device == musicDevice) && (device == devices)) {
                 sendMsg(mAudioHandler,
                         MSG_BROADCAST_AUDIO_BECOMING_NOISY,
                         SENDMSG_REPLACE,
@@ -5666,7 +5669,7 @@
     //==========================================================================================
     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
             IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
-            IAudioPolicyCallback pcb) {
+            IAudioPolicyCallback pcb, int sdk) {
         // permission checks
         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
@@ -5687,7 +5690,7 @@
         }
 
         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
-                clientId, callingPackageName, flags);
+                clientId, callingPackageName, flags, sdk);
     }
 
     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
@@ -5829,25 +5832,9 @@
 
     // Must be called synchronized on mConnectedDevices
     private void setForceUseInt_SyncDevices(int usage, int config) {
-        switch (usage) {
-            case AudioSystem.FOR_MEDIA:
-                if (config == AudioSystem.FORCE_NO_BT_A2DP) {
-                    mBecomingNoisyIntentDevices &= ~AudioSystem.DEVICE_OUT_ALL_A2DP;
-                } else { // config == AudioSystem.FORCE_NONE
-                    mBecomingNoisyIntentDevices |= AudioSystem.DEVICE_OUT_ALL_A2DP;
-                }
-                sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
-                        SENDMSG_NOOP, 0, 0, null, 0);
-                break;
-            case AudioSystem.FOR_DOCK:
-                if (config == AudioSystem.FORCE_ANALOG_DOCK) {
-                    mBecomingNoisyIntentDevices |= AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
-                } else { // config == AudioSystem.FORCE_NONE
-                    mBecomingNoisyIntentDevices &= ~AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
-                }
-                break;
-            default:
-                // usage doesn't affect the broadcast of ACTION_AUDIO_BECOMING_NOISY
+        if (usage == AudioSystem.FOR_MEDIA) {
+            sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                    SENDMSG_NOOP, 0, 0, null, 0);
         }
         AudioSystem.setForceUse(usage, config);
     }
@@ -6057,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/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java
index bcaa295..3bc603f 100644
--- a/services/core/java/com/android/server/audio/FocusRequester.java
+++ b/services/core/java/com/android/server/audio/FocusRequester.java
@@ -48,6 +48,7 @@
     private final String mPackageName;
     private final int mCallingUid;
     private final MediaFocusControl mFocusController; // never null
+    private final int mSdkTarget;
 
     /**
      * the audio focus gain request that caused the addition of this object in the focus stack.
@@ -87,7 +88,7 @@
      */
     FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags,
             IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
-            String pn, int uid, @NonNull MediaFocusControl ctlr) {
+            String pn, int uid, @NonNull MediaFocusControl ctlr, int sdk) {
         mAttributes = aa;
         mFocusDispatcher = afl;
         mSourceRef = source;
@@ -99,6 +100,7 @@
         mGrantFlags = grantFlags;
         mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
         mFocusController = ctlr;
+        mSdkTarget = sdk;
     }
 
     FocusRequester(AudioFocusInfo afi, IAudioFocusDispatcher afl,
@@ -110,6 +112,7 @@
         mFocusGainRequest = afi.getGainRequest();
         mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
         mGrantFlags = afi.getFlags();
+        mSdkTarget = afi.getSdkTarget();
 
         mFocusDispatcher = afl;
         mSourceRef = source;
@@ -169,6 +172,9 @@
         return mAttributes;
     }
 
+    int getSdkTarget() {
+        return mSdkTarget;
+    }
 
     private static String focusChangeToString(int focus) {
         switch(focus) {
@@ -226,7 +232,8 @@
                 + " -- loss: " + focusLossToString()
                 + " -- notified: " + mFocusLossWasNotified
                 + " -- uid: " + mCallingUid
-                + " -- attr: " + mAttributes);
+                + " -- attr: " + mAttributes
+                + " -- sdk:" + mSdkTarget);
     }
 
 
@@ -419,6 +426,6 @@
 
     AudioFocusInfo toAudioFocusInfo() {
         return new AudioFocusInfo(mAttributes, mCallingUid, mClientId, mPackageName,
-                mFocusGainRequest, mFocusLossReceived, mGrantFlags);
+                mFocusGainRequest, mFocusLossReceived, mGrantFlags, mSdkTarget);
     }
 }
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 821e78a..f5c13c1 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -27,6 +27,7 @@
 import android.media.audiopolicy.AudioPolicy;
 import android.media.audiopolicy.IAudioPolicyCallback;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -56,6 +57,17 @@
      */
     static final boolean ENFORCE_DUCKING = true;
     /**
+     * set to true to the framework enforces ducking itself only with apps above a given SDK
+     * target level. Is ignored if ENFORCE_DUCKING is false.
+     */
+    static final boolean ENFORCE_DUCKING_FOR_NEW = true;
+    /**
+     * the SDK level (included) up to which the framework doesn't enforce ducking itself. Is ignored
+     * if ENFORCE_DUCKING_FOR_NEW is false;
+     */
+    // automatic ducking was introduced for Android O
+    static final int DUCKING_IN_APP_SDK_LEVEL = Build.VERSION_CODES.N_MR1;
+    /**
      * set to true so the framework enforces muting media/game itself when the device is ringing
      * or in a call.
      */
@@ -629,7 +641,8 @@
 
     /** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int, int) */
     protected int requestAudioFocus(AudioAttributes aa, int focusChangeHint, IBinder cb,
-            IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags) {
+            IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
+            int sdk) {
         Log.i(TAG, " AudioFocus  requestAudioFocus() from uid/pid " + Binder.getCallingUid()
                 + "/" + Binder.getCallingPid()
                 + " clientId=" + clientId
@@ -656,7 +669,7 @@
                 // construct AudioFocusInfo as it will be communicated to audio focus policy
                 afiForExtPolicy = new AudioFocusInfo(aa, Binder.getCallingUid(),
                         clientId, callingPackageName, focusChangeHint, 0 /*lossReceived*/,
-                        flags);
+                        flags, sdk);
             } else {
                 afiForExtPolicy = null;
             }
@@ -722,7 +735,7 @@
             removeFocusStackEntry(clientId, false /* signal */, false /*notifyFocusFollowers*/);
 
             final FocusRequester nfr = new FocusRequester(aa, focusChangeHint, flags, fd, cb,
-                    clientId, afdh, callingPackageName, Binder.getCallingUid(), this);
+                    clientId, afdh, callingPackageName, Binder.getCallingUid(), this, sdk);
             if (focusGrantDelayed) {
                 // focusGrantDelayed being true implies we can't reassign focus right now
                 // which implies the focus stack is not empty.
@@ -767,7 +780,7 @@
                 if (mFocusPolicy != null) {
                     final AudioFocusInfo afi = new AudioFocusInfo(aa, Binder.getCallingUid(),
                             clientId, callingPackageName, 0 /*gainRequest*/, 0 /*lossReceived*/,
-                            0 /*flags*/);
+                            0 /*flags*/, 0 /* sdk n/a here*/);
                     if (notifyExtFocusPolicyFocusAbandon_syncAf(afi)) {
                         return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
                     }
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 9eda929..d35104f 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);
@@ -319,10 +308,17 @@
                 {
                     if (mDuckedPlayers.contains(new Integer(piid))) {
                         if (DEBUG) { Log.v(TAG, "player " + piid + " already ducked"); }
+                    } else if (MediaFocusControl.ENFORCE_DUCKING
+                            && MediaFocusControl.ENFORCE_DUCKING_FOR_NEW
+                            && loser.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL) {
+                        // legacy behavior, apps used to be notified when they should be ducking
+                        if (DEBUG) { Log.v(TAG, "not ducking player " + piid + ": old SDK"); }
+                        return false;
                     } else if (apc.getAudioAttributes().getContentType() ==
                             AudioAttributes.CONTENT_TYPE_SPEECH) {
                         // the player is speaking, ducking will make the speech unintelligible
                         // so let the app handle it instead
+                        if (DEBUG) { Log.v(TAG, "not ducking player " + piid + ": SPEECH"); }
                         return false;
                     } else if (apc.getPlayerType()
                             == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
@@ -509,7 +505,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/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 9d8b3d4..ac5fb43 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -138,7 +138,7 @@
         public boolean isCurrentlyServing() {
             switch (lastState) {
                 case IControlsTethering.STATE_TETHERED:
-                case IControlsTethering.STATE_LOCAL_HOTSPOT:
+                case IControlsTethering.STATE_LOCAL_ONLY:
                     return true;
                 default:
                     return false;
@@ -617,7 +617,7 @@
                     erroredList.add(iface);
                 } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
                     availableList.add(iface);
-                } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_HOTSPOT) {
+                } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_ONLY) {
                     localOnlyList.add(iface);
                 } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
                     if (cfg.isUsb(iface)) {
@@ -795,7 +795,7 @@
                         // Otherwise, assume it's a local-only hotspot request.
                         final int state = mWifiTetherRequested
                                 ? IControlsTethering.STATE_TETHERED
-                                : IControlsTethering.STATE_LOCAL_HOTSPOT;
+                                : IControlsTethering.STATE_LOCAL_ONLY;
                         tetherMatchingInterfaces(state, ConnectivityManager.TETHERING_WIFI);
                         break;
                     case WifiManager.WIFI_AP_STATE_DISABLED:
@@ -865,7 +865,7 @@
                 result = untether(chosenIface);
                 break;
             case IControlsTethering.STATE_TETHERED:
-            case IControlsTethering.STATE_LOCAL_HOTSPOT:
+            case IControlsTethering.STATE_LOCAL_ONLY:
                 result = tether(chosenIface, requestedState);
                 break;
             default:
@@ -1723,7 +1723,7 @@
                     case IControlsTethering.STATE_TETHERED:
                         pw.print("TetheredState");
                         break;
-                    case IControlsTethering.STATE_LOCAL_HOTSPOT:
+                    case IControlsTethering.STATE_LOCAL_ONLY:
                         pw.print("LocalHotspotState");
                         break;
                     default:
@@ -1778,7 +1778,7 @@
                 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE;
                 break;
             case IControlsTethering.STATE_TETHERED:
-            case IControlsTethering.STATE_LOCAL_HOTSPOT:
+            case IControlsTethering.STATE_LOCAL_ONLY:
                 which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE;
                 break;
             default:
diff --git a/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java b/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java
index f3914b7..c5c86bd 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java
@@ -23,9 +23,9 @@
  */
 public interface IControlsTethering {
     public final int STATE_UNAVAILABLE = 0;
-    public final int STATE_AVAILABLE = 1;
-    public final int STATE_TETHERED = 2;
-    public final int STATE_LOCAL_HOTSPOT = 3;
+    public final int STATE_AVAILABLE   = 1;
+    public final int STATE_TETHERED    = 2;
+    public final int STATE_LOCAL_ONLY  = 3;
 
     /**
      * Notify that |who| has changed its tethering state.  This may be called from any thread.
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
index 5f496ca..2485654 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
@@ -172,7 +172,7 @@
         final Downstream ds = findDownstream(sm);
         if (ds == null) return null;
 
-        if (ds.mode == IControlsTethering.STATE_LOCAL_HOTSPOT) {
+        if (ds.mode == IControlsTethering.STATE_LOCAL_ONLY) {
             // Build a Unique Locally-assigned Prefix configuration.
             return getUniqueLocalConfig(mUniqueLocalPrefix, ds.subnetId);
         }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 601ed01..e21349a 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -194,7 +194,7 @@
                 case CMD_TETHER_REQUESTED:
                     mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
                     switch (message.arg1) {
-                        case IControlsTethering.STATE_LOCAL_HOTSPOT:
+                        case IControlsTethering.STATE_LOCAL_ONLY:
                             transitionTo(mLocalHotspotState);
                             break;
                         case IControlsTethering.STATE_TETHERED:
@@ -304,7 +304,7 @@
             }
 
             if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName);
-            sendInterfaceState(IControlsTethering.STATE_LOCAL_HOTSPOT);
+            sendInterfaceState(IControlsTethering.STATE_LOCAL_ONLY);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/job/JobSchedulerInternal.java b/services/core/java/com/android/server/job/JobSchedulerInternal.java
index 75170ec..bc6bd50 100644
--- a/services/core/java/com/android/server/job/JobSchedulerInternal.java
+++ b/services/core/java/com/android/server/job/JobSchedulerInternal.java
@@ -30,4 +30,11 @@
      * Returns a list of pending jobs scheduled by the system service.
      */
     List<JobInfo> getSystemScheduledPendingJobs();
+
+    /**
+     * These are for activity manager to communicate to use what is currently performing backups.
+     */
+    void addBackingUpUid(int uid);
+    void removeBackingUpUid(int uid);
+    void clearAllBackingUpUids();
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index c8bfa34..abb2b55 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -174,6 +174,11 @@
      */
     final SparseIntArray mUidPriorityOverride = new SparseIntArray();
 
+    /**
+     * Which uids are currently performing backups, so we shouldn't allow their jobs to run.
+     */
+    final SparseIntArray mBackingUpUids = new SparseIntArray();
+
     // -- Pre-allocated temporaries only for use in assignJobsToContextsLocked --
 
     /**
@@ -621,14 +626,30 @@
             jobStatus.prepareLocked(ActivityManager.getService());
 
             if (toCancel != null) {
-                cancelJobImpl(toCancel, jobStatus);
+                cancelJobImplLocked(toCancel, jobStatus);
             }
             if (work != null) {
                 // If work has been supplied, enqueue it into the new job.
                 jobStatus.enqueueWorkLocked(ActivityManager.getService(), work);
             }
             startTrackingJobLocked(jobStatus, toCancel);
-            mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+
+            // If the job is immediately ready to run, then we can just immediately
+            // put it in the pending list and try to schedule it.  This is especially
+            // important for jobs with a 0 deadline constraint, since they will happen a fair
+            // amount, we want to handle them as quickly as possible, and semantically we want to
+            // make sure we have started holding the wake lock for the job before returning to
+            // the caller.
+            // If the job is not yet ready to run, there is nothing more to do -- we are
+            // now just waiting for one of its controllers to change state and schedule
+            // the job appropriately.
+            if (isReadyToBeExecutedLocked(jobStatus)) {
+                // This is a new job, we can just immediately put it on the pending
+                // list and try to run it.
+                mJobPackageTracker.notePending(jobStatus);
+                mPendingJobs.add(jobStatus);
+                maybeRunPendingJobsLocked();
+            }
         }
         return JobScheduler.RESULT_SUCCESS;
     }
@@ -659,25 +680,23 @@
     }
 
     void cancelJobsForUser(int userHandle) {
-        List<JobStatus> jobsForUser;
         synchronized (mLock) {
-            jobsForUser = mJobs.getJobsByUser(userHandle);
-        }
-        for (int i=0; i<jobsForUser.size(); i++) {
-            JobStatus toRemove = jobsForUser.get(i);
-            cancelJobImpl(toRemove, null);
+            final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
+            for (int i=0; i<jobsForUser.size(); i++) {
+                JobStatus toRemove = jobsForUser.get(i);
+                cancelJobImplLocked(toRemove, null);
+            }
         }
     }
 
     void cancelJobsForPackageAndUid(String pkgName, int uid) {
-        List<JobStatus> jobsForUid;
         synchronized (mLock) {
-            jobsForUid = mJobs.getJobsByUid(uid);
-        }
-        for (int i = jobsForUid.size() - 1; i >= 0; i--) {
-            final JobStatus job = jobsForUid.get(i);
-            if (job.getSourcePackageName().equals(pkgName)) {
-                cancelJobImpl(job, null);
+            final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
+            for (int i = jobsForUid.size() - 1; i >= 0; i--) {
+                final JobStatus job = jobsForUid.get(i);
+                if (job.getSourcePackageName().equals(pkgName)) {
+                    cancelJobImplLocked(job, null);
+                }
             }
         }
     }
@@ -690,13 +709,12 @@
      *
      */
     public void cancelJobsForUid(int uid) {
-        List<JobStatus> jobsForUid;
         synchronized (mLock) {
-            jobsForUid = mJobs.getJobsByUid(uid);
-        }
-        for (int i=0; i<jobsForUid.size(); i++) {
-            JobStatus toRemove = jobsForUid.get(i);
-            cancelJobImpl(toRemove, null);
+            final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
+            for (int i=0; i<jobsForUid.size(); i++) {
+                JobStatus toRemove = jobsForUid.get(i);
+                cancelJobImplLocked(toRemove, null);
+            }
         }
     }
 
@@ -711,25 +729,23 @@
         JobStatus toCancel;
         synchronized (mLock) {
             toCancel = mJobs.getJobByUidAndJobId(uid, jobId);
-        }
-        if (toCancel != null) {
-            cancelJobImpl(toCancel, null);
+            if (toCancel != null) {
+                cancelJobImplLocked(toCancel, null);
+            }
         }
     }
 
-    private void cancelJobImpl(JobStatus cancelled, JobStatus incomingJob) {
-        synchronized (mLock) {
-            if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
-            cancelled.unprepareLocked(ActivityManager.getService());
-            stopTrackingJobLocked(cancelled, incomingJob, true /* writeBack */);
-            // Remove from pending queue.
-            if (mPendingJobs.remove(cancelled)) {
-                mJobPackageTracker.noteNonpending(cancelled);
-            }
-            // Cancel if running.
-            stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED);
-            reportActiveLocked();
+    private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob) {
+        if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
+        cancelled.unprepareLocked(ActivityManager.getService());
+        stopTrackingJobLocked(cancelled, incomingJob, true /* writeBack */);
+        // Remove from pending queue.
+        if (mPendingJobs.remove(cancelled)) {
+            mJobPackageTracker.noteNonpending(cancelled);
         }
+        // Cancel if running.
+        stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED);
+        reportActiveLocked();
     }
 
     void updateUidState(int uid, int procState) {
@@ -770,8 +786,8 @@
                             mLocalDeviceIdleController.setJobsActive(true);
                         }
                     }
+                    mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
                 }
-                mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
             }
         }
     }
@@ -990,7 +1006,7 @@
      * @return A newly instantiated JobStatus with the same constraints as the last job except
      * with adjusted timing constraints.
      *
-     * @see JobHandler#maybeQueueReadyJobsForExecutionLockedH
+     * @see #maybeQueueReadyJobsForExecutionLocked
      */
     private JobStatus getRescheduleJobForFailureLocked(JobStatus failureToReschedule) {
         final long elapsedNowMillis = SystemClock.elapsedRealtime();
@@ -1128,7 +1144,7 @@
         mHandler.obtainMessage(MSG_JOB_EXPIRED, jobStatus).sendToTarget();
     }
 
-    private class JobHandler extends Handler {
+    final private class JobHandler extends Handler {
 
         public JobHandler(Looper looper) {
             super(looper);
@@ -1140,283 +1156,300 @@
                 if (!mReadyToRock) {
                     return;
                 }
-            }
-            switch (message.what) {
-                case MSG_JOB_EXPIRED:
-                    synchronized (mLock) {
+                switch (message.what) {
+                    case MSG_JOB_EXPIRED: {
                         JobStatus runNow = (JobStatus) message.obj;
                         // runNow can be null, which is a controller's way of indicating that its
                         // state is such that all ready jobs should be run immediately.
                         if (runNow != null && isReadyToBeExecutedLocked(runNow)) {
                             mJobPackageTracker.notePending(runNow);
                             mPendingJobs.add(runNow);
+                        } else {
+                            queueReadyJobsForExecutionLocked();
                         }
-                        queueReadyJobsForExecutionLockedH();
-                    }
-                    break;
-                case MSG_CHECK_JOB:
-                    synchronized (mLock) {
+                    } break;
+                    case MSG_CHECK_JOB:
                         if (mReportedActive) {
                             // if jobs are currently being run, queue all ready jobs for execution.
-                            queueReadyJobsForExecutionLockedH();
+                            queueReadyJobsForExecutionLocked();
                         } else {
                             // Check the list of jobs and run some of them if we feel inclined.
-                            maybeQueueReadyJobsForExecutionLockedH();
+                            maybeQueueReadyJobsForExecutionLocked();
                         }
-                    }
-                    break;
-                case MSG_CHECK_JOB_GREEDY:
-                    synchronized (mLock) {
-                        queueReadyJobsForExecutionLockedH();
-                    }
-                    break;
-                case MSG_STOP_JOB:
-                    cancelJobImpl((JobStatus)message.obj, null);
-                    break;
-            }
-            maybeRunPendingJobsH();
-            // Don't remove JOB_EXPIRED in case one came along while processing the queue.
-            removeMessages(MSG_CHECK_JOB);
-        }
-
-        /**
-         * Run through list of jobs and execute all possible - at least one is expired so we do
-         * as many as we can.
-         */
-        private void queueReadyJobsForExecutionLockedH() {
-            if (DEBUG) {
-                Slog.d(TAG, "queuing all ready jobs for execution:");
-            }
-            noteJobsNonpending(mPendingJobs);
-            mPendingJobs.clear();
-            mJobs.forEachJob(mReadyQueueFunctor);
-            mReadyQueueFunctor.postProcess();
-
-            if (DEBUG) {
-                final int queuedJobs = mPendingJobs.size();
-                if (queuedJobs == 0) {
-                    Slog.d(TAG, "No jobs pending.");
-                } else {
-                    Slog.d(TAG, queuedJobs + " jobs queued.");
+                        break;
+                    case MSG_CHECK_JOB_GREEDY:
+                        queueReadyJobsForExecutionLocked();
+                        break;
+                    case MSG_STOP_JOB:
+                        cancelJobImplLocked((JobStatus) message.obj, null);
+                        break;
                 }
+                maybeRunPendingJobsLocked();
+                // Don't remove JOB_EXPIRED in case one came along while processing the queue.
+                removeMessages(MSG_CHECK_JOB);
             }
         }
+    }
 
-        class ReadyJobQueueFunctor implements JobStatusFunctor {
-            ArrayList<JobStatus> newReadyJobs;
+    /**
+     * Run through list of jobs and execute all possible - at least one is expired so we do
+     * as many as we can.
+     */
+    private void queueReadyJobsForExecutionLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "queuing all ready jobs for execution:");
+        }
+        noteJobsNonpending(mPendingJobs);
+        mPendingJobs.clear();
+        mJobs.forEachJob(mReadyQueueFunctor);
+        mReadyQueueFunctor.postProcess();
 
-            @Override
-            public void process(JobStatus job) {
-                if (isReadyToBeExecutedLocked(job)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "    queued " + job.toShortString());
-                    }
-                    if (newReadyJobs == null) {
-                        newReadyJobs = new ArrayList<JobStatus>();
-                    }
-                    newReadyJobs.add(job);
-                } else if (areJobConstraintsNotSatisfiedLocked(job)) {
-                    stopJobOnServiceContextLocked(job,
-                            JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
-                }
-            }
-
-            public void postProcess() {
-                if (newReadyJobs != null) {
-                    noteJobsPending(newReadyJobs);
-                    mPendingJobs.addAll(newReadyJobs);
-                }
-                newReadyJobs = null;
+        if (DEBUG) {
+            final int queuedJobs = mPendingJobs.size();
+            if (queuedJobs == 0) {
+                Slog.d(TAG, "No jobs pending.");
+            } else {
+                Slog.d(TAG, queuedJobs + " jobs queued.");
             }
         }
-        private final ReadyJobQueueFunctor mReadyQueueFunctor = new ReadyJobQueueFunctor();
+    }
 
-        /**
-         * The state of at least one job has changed. Here is where we could enforce various
-         * policies on when we want to execute jobs.
-         * Right now the policy is such:
-         * If >1 of the ready jobs is idle mode we send all of them off
-         * if more than 2 network connectivity jobs are ready we send them all off.
-         * If more than 4 jobs total are ready we send them all off.
-         * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
-         */
-        class MaybeReadyJobQueueFunctor implements JobStatusFunctor {
-            int chargingCount;
-            int batteryNotLowCount;
-            int storageNotLowCount;
-            int idleCount;
-            int backoffCount;
-            int connectivityCount;
-            int contentCount;
-            List<JobStatus> runnableJobs;
+    final class ReadyJobQueueFunctor implements JobStatusFunctor {
+        ArrayList<JobStatus> newReadyJobs;
 
-            public MaybeReadyJobQueueFunctor() {
-                reset();
-            }
-
-            // Functor method invoked for each job via JobStore.forEachJob()
-            @Override
-            public void process(JobStatus job) {
-                if (isReadyToBeExecutedLocked(job)) {
-                    try {
-                        if (ActivityManager.getService().isAppStartModeDisabled(job.getUid(),
-                                job.getJob().getService().getPackageName())) {
-                            Slog.w(TAG, "Aborting job " + job.getUid() + ":"
-                                    + job.getJob().toString() + " -- package not allowed to start");
-                            mHandler.obtainMessage(MSG_STOP_JOB, job).sendToTarget();
-                            return;
-                        }
-                    } catch (RemoteException e) {
-                    }
-                    if (job.getNumFailures() > 0) {
-                        backoffCount++;
-                    }
-                    if (job.hasIdleConstraint()) {
-                        idleCount++;
-                    }
-                    if (job.hasConnectivityConstraint()) {
-                        connectivityCount++;
-                    }
-                    if (job.hasChargingConstraint()) {
-                        chargingCount++;
-                    }
-                    if (job.hasBatteryNotLowConstraint()) {
-                        batteryNotLowCount++;
-                    }
-                    if (job.hasStorageNotLowConstraint()) {
-                        storageNotLowCount++;
-                    }
-                    if (job.hasContentTriggerConstraint()) {
-                        contentCount++;
-                    }
-                    if (runnableJobs == null) {
-                        runnableJobs = new ArrayList<>();
-                    }
-                    runnableJobs.add(job);
-                } else if (areJobConstraintsNotSatisfiedLocked(job)) {
-                    stopJobOnServiceContextLocked(job,
-                            JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
-                }
-            }
-
-            public void postProcess() {
-                if (backoffCount > 0 ||
-                        idleCount >= mConstants.MIN_IDLE_COUNT ||
-                        connectivityCount >= mConstants.MIN_CONNECTIVITY_COUNT ||
-                        chargingCount >= mConstants.MIN_CHARGING_COUNT ||
-                        batteryNotLowCount >= mConstants.MIN_BATTERY_NOT_LOW_COUNT ||
-                        storageNotLowCount >= mConstants.MIN_STORAGE_NOT_LOW_COUNT ||
-                        contentCount >= mConstants.MIN_CONTENT_COUNT ||
-                        (runnableJobs != null
-                                && runnableJobs.size() >= mConstants.MIN_READY_JOBS_COUNT)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Running jobs.");
-                    }
-                    noteJobsPending(runnableJobs);
-                    mPendingJobs.addAll(runnableJobs);
-                } else {
-                    if (DEBUG) {
-                        Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Not running anything.");
-                    }
-                }
-
-                // Be ready for next time
-                reset();
-            }
-
-            private void reset() {
-                chargingCount = 0;
-                idleCount =  0;
-                backoffCount = 0;
-                connectivityCount = 0;
-                batteryNotLowCount = 0;
-                storageNotLowCount = 0;
-                contentCount = 0;
-                runnableJobs = null;
-            }
-        }
-        private final MaybeReadyJobQueueFunctor mMaybeQueueFunctor = new MaybeReadyJobQueueFunctor();
-
-        private void maybeQueueReadyJobsForExecutionLockedH() {
-            if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs...");
-
-            noteJobsNonpending(mPendingJobs);
-            mPendingJobs.clear();
-            mJobs.forEachJob(mMaybeQueueFunctor);
-            mMaybeQueueFunctor.postProcess();
-        }
-
-        /**
-         * Criteria for moving a job into the pending queue:
-         *      - It's ready.
-         *      - It's not pending.
-         *      - It's not already running on a JSC.
-         *      - The user that requested the job is running.
-         *      - The component is enabled and runnable.
-         */
-        private boolean isReadyToBeExecutedLocked(JobStatus job) {
-            final boolean jobExists = mJobs.containsJob(job);
-            final boolean jobReady = job.isReady();
-            final boolean jobPending = mPendingJobs.contains(job);
-            final boolean jobActive = isCurrentlyActiveLocked(job);
-
-            final int userId = job.getUserId();
-            final boolean userStarted = ArrayUtils.contains(mStartedUsers, userId);
-
-            if (DEBUG) {
-                Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
-                        + " exists=" + jobExists
-                        + " ready=" + jobReady + " pending=" + jobPending
-                        + " active=" + jobActive + " userStarted=" + userStarted);
-            }
-
-            // Short circuit: don't do the expensive PM check unless we really think
-            // we might need to run this job now.
-            if (!jobExists || !userStarted || !jobReady || jobPending || jobActive) {
-                return false;
-            }
-
-            final boolean componentPresent;
-            try {
-                componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
-                        job.getServiceComponent(), PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                        userId) != null);
-            } catch (RemoteException e) {
-                throw e.rethrowAsRuntimeException();
-            }
-
-            if (DEBUG) {
-                Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
-                        + " componentPresent=" + componentPresent);
-            }
-
-            // Everything else checked out so far, so this is the final yes/no check
-            return componentPresent;
-        }
-
-        /**
-         * Criteria for cancelling an active job:
-         *      - It's not ready
-         *      - It's running on a JSC.
-         */
-        private boolean areJobConstraintsNotSatisfiedLocked(JobStatus job) {
-            return !job.isReady() && isCurrentlyActiveLocked(job);
-        }
-
-        /**
-         * Reconcile jobs in the pending queue against available execution contexts.
-         * A controller can force a job into the pending queue even if it's already running, but
-         * here is where we decide whether to actually execute it.
-         */
-        private void maybeRunPendingJobsH() {
-            synchronized (mLock) {
+        @Override
+        public void process(JobStatus job) {
+            if (isReadyToBeExecutedLocked(job)) {
                 if (DEBUG) {
-                    Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
+                    Slog.d(TAG, "    queued " + job.toShortString());
                 }
-                assignJobsToContextsLocked();
-                reportActiveLocked();
+                if (newReadyJobs == null) {
+                    newReadyJobs = new ArrayList<JobStatus>();
+                }
+                newReadyJobs.add(job);
+            } else if (areJobConstraintsNotSatisfiedLocked(job)) {
+                stopJobOnServiceContextLocked(job,
+                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
             }
         }
+
+        public void postProcess() {
+            if (newReadyJobs != null) {
+                noteJobsPending(newReadyJobs);
+                mPendingJobs.addAll(newReadyJobs);
+            }
+            newReadyJobs = null;
+        }
+    }
+    private final ReadyJobQueueFunctor mReadyQueueFunctor = new ReadyJobQueueFunctor();
+
+    /**
+     * The state of at least one job has changed. Here is where we could enforce various
+     * policies on when we want to execute jobs.
+     * Right now the policy is such:
+     * If >1 of the ready jobs is idle mode we send all of them off
+     * if more than 2 network connectivity jobs are ready we send them all off.
+     * If more than 4 jobs total are ready we send them all off.
+     * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
+     */
+    final class MaybeReadyJobQueueFunctor implements JobStatusFunctor {
+        int chargingCount;
+        int batteryNotLowCount;
+        int storageNotLowCount;
+        int idleCount;
+        int backoffCount;
+        int connectivityCount;
+        int contentCount;
+        List<JobStatus> runnableJobs;
+
+        public MaybeReadyJobQueueFunctor() {
+            reset();
+        }
+
+        // Functor method invoked for each job via JobStore.forEachJob()
+        @Override
+        public void process(JobStatus job) {
+            if (isReadyToBeExecutedLocked(job)) {
+                try {
+                    if (ActivityManager.getService().isAppStartModeDisabled(job.getUid(),
+                            job.getJob().getService().getPackageName())) {
+                        Slog.w(TAG, "Aborting job " + job.getUid() + ":"
+                                + job.getJob().toString() + " -- package not allowed to start");
+                        mHandler.obtainMessage(MSG_STOP_JOB, job).sendToTarget();
+                        return;
+                    }
+                } catch (RemoteException e) {
+                }
+                if (job.getNumFailures() > 0) {
+                    backoffCount++;
+                }
+                if (job.hasIdleConstraint()) {
+                    idleCount++;
+                }
+                if (job.hasConnectivityConstraint()) {
+                    connectivityCount++;
+                }
+                if (job.hasChargingConstraint()) {
+                    chargingCount++;
+                }
+                if (job.hasBatteryNotLowConstraint()) {
+                    batteryNotLowCount++;
+                }
+                if (job.hasStorageNotLowConstraint()) {
+                    storageNotLowCount++;
+                }
+                if (job.hasContentTriggerConstraint()) {
+                    contentCount++;
+                }
+                if (runnableJobs == null) {
+                    runnableJobs = new ArrayList<>();
+                }
+                runnableJobs.add(job);
+            } else if (areJobConstraintsNotSatisfiedLocked(job)) {
+                stopJobOnServiceContextLocked(job,
+                        JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED);
+            }
+        }
+
+        public void postProcess() {
+            if (backoffCount > 0 ||
+                    idleCount >= mConstants.MIN_IDLE_COUNT ||
+                    connectivityCount >= mConstants.MIN_CONNECTIVITY_COUNT ||
+                    chargingCount >= mConstants.MIN_CHARGING_COUNT ||
+                    batteryNotLowCount >= mConstants.MIN_BATTERY_NOT_LOW_COUNT ||
+                    storageNotLowCount >= mConstants.MIN_STORAGE_NOT_LOW_COUNT ||
+                    contentCount >= mConstants.MIN_CONTENT_COUNT ||
+                    (runnableJobs != null
+                            && runnableJobs.size() >= mConstants.MIN_READY_JOBS_COUNT)) {
+                if (DEBUG) {
+                    Slog.d(TAG, "maybeQueueReadyJobsForExecutionLocked: Running jobs.");
+                }
+                noteJobsPending(runnableJobs);
+                mPendingJobs.addAll(runnableJobs);
+            } else {
+                if (DEBUG) {
+                    Slog.d(TAG, "maybeQueueReadyJobsForExecutionLocked: Not running anything.");
+                }
+            }
+
+            // Be ready for next time
+            reset();
+        }
+
+        private void reset() {
+            chargingCount = 0;
+            idleCount =  0;
+            backoffCount = 0;
+            connectivityCount = 0;
+            batteryNotLowCount = 0;
+            storageNotLowCount = 0;
+            contentCount = 0;
+            runnableJobs = null;
+        }
+    }
+    private final MaybeReadyJobQueueFunctor mMaybeQueueFunctor = new MaybeReadyJobQueueFunctor();
+
+    private void maybeQueueReadyJobsForExecutionLocked() {
+        if (DEBUG) Slog.d(TAG, "Maybe queuing ready jobs...");
+
+        noteJobsNonpending(mPendingJobs);
+        mPendingJobs.clear();
+        mJobs.forEachJob(mMaybeQueueFunctor);
+        mMaybeQueueFunctor.postProcess();
+    }
+
+    /**
+     * Criteria for moving a job into the pending queue:
+     *      - It's ready.
+     *      - It's not pending.
+     *      - It's not already running on a JSC.
+     *      - The user that requested the job is running.
+     *      - The component is enabled and runnable.
+     */
+    private boolean isReadyToBeExecutedLocked(JobStatus job) {
+        final boolean jobReady = job.isReady();
+
+        if (DEBUG) {
+            Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+                    + " ready=" + jobReady);
+        }
+
+        // This is a condition that is very likely to be false (most jobs that are
+        // scheduled are sitting there, not ready yet) and very cheap to check (just
+        // a few conditions on data in JobStatus).
+        if (!jobReady) {
+            return false;
+        }
+
+        final boolean jobExists = mJobs.containsJob(job);
+
+        final int userId = job.getUserId();
+        final boolean userStarted = ArrayUtils.contains(mStartedUsers, userId);
+
+        if (DEBUG) {
+            Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+                    + " exists=" + jobExists + " userStarted=" + userStarted);
+        }
+
+        // These are also fairly cheap to check, though they typically will not
+        // be conditions we fail.
+        if (!jobExists || !userStarted) {
+            return false;
+        }
+
+        final boolean jobPending = mPendingJobs.contains(job);
+        final boolean jobActive = isCurrentlyActiveLocked(job);
+
+        if (DEBUG) {
+            Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+                    + " pending=" + jobPending + " active=" + jobActive);
+        }
+
+        // These can be a little more expensive (especially jobActive, since we need to
+        // go through the array of all potentially active jobs), so we are doing them
+        // later...  but still before checking with the package manager!
+        if (jobPending || jobActive) {
+            return false;
+        }
+
+        final boolean componentPresent;
+        try {
+            componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
+                    job.getServiceComponent(), PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                    userId) != null);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        if (DEBUG) {
+            Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+                    + " componentPresent=" + componentPresent);
+        }
+
+        // Everything else checked out so far, so this is the final yes/no check
+        return componentPresent;
+    }
+
+    /**
+     * Criteria for cancelling an active job:
+     *      - It's not ready
+     *      - It's running on a JSC.
+     */
+    private boolean areJobConstraintsNotSatisfiedLocked(JobStatus job) {
+        return !job.isReady() && isCurrentlyActiveLocked(job);
+    }
+
+    /**
+     * Reconcile jobs in the pending queue against available execution contexts.
+     * A controller can force a job into the pending queue even if it's already running, but
+     * here is where we decide whether to actually execute it.
+     */
+    private void maybeRunPendingJobsLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "pending queue: " + mPendingJobs.size() + " jobs.");
+        }
+        assignJobsToContextsLocked();
+        reportActiveLocked();
     }
 
     private int adjustJobPriority(int curPriority, JobStatus job) {
@@ -1619,6 +1652,38 @@
                 return pendingJobs;
             }
         }
+
+        @Override
+        public void addBackingUpUid(int uid) {
+            synchronized (mLock) {
+                // No need to actually do anything here, since for a full backup the
+                // activity manager will kill the process which will kill the job (and
+                // cause it to restart, but now it can't run).
+                mBackingUpUids.put(uid, uid);
+            }
+        }
+
+        @Override
+        public void removeBackingUpUid(int uid) {
+            synchronized (mLock) {
+                mBackingUpUids.delete(uid);
+                // If there are any jobs for this uid, we need to rebuild the pending list
+                // in case they are now ready to run.
+                if (mJobs.countJobsForUid(uid) > 0) {
+                    mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+                }
+            }
+        }
+
+        @Override
+        public void clearAllBackingUpUids() {
+            synchronized (mLock) {
+                if (mBackingUpUids.size() > 0) {
+                    mBackingUpUids.clear();
+                    mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+                }
+            }
+        }
     }
 
     /**
@@ -1868,7 +1933,8 @@
                     return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS;
                 }
 
-                mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
+                queueReadyJobsForExecutionLocked();
+                maybeRunPendingJobsLocked();
             }
         } catch (RemoteException e) {
             // can't happen
@@ -2015,7 +2081,7 @@
 
                     job.dump(pw, "    ", true);
                     pw.print("    Ready: ");
-                    pw.print(mHandler.isReadyToBeExecutedLocked(job));
+                    pw.print(isReadyToBeExecutedLocked(job));
                     pw.print(" (job=");
                     pw.print(job.isReady());
                     pw.print(" user=");
@@ -2024,6 +2090,8 @@
                     pw.print(!mPendingJobs.contains(job));
                     pw.print(" !active=");
                     pw.print(!isCurrentlyActiveLocked(job));
+                    pw.print(" !backingup=");
+                    pw.print(!(mBackingUpUids.indexOfKey(job.getSourceUid()) >= 0));
                     pw.print(" comp=");
                     boolean componentPresent = false;
                     try {
@@ -2052,6 +2120,24 @@
                     pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i));
                 }
             }
+            if (mBackingUpUids.size() > 0) {
+                pw.println();
+                pw.println("Backing up uids:");
+                boolean first = true;
+                for (int i = 0; i < mBackingUpUids.size(); i++) {
+                    int uid = mBackingUpUids.keyAt(i);
+                    if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+                        if (first) {
+                            pw.print("  ");
+                            first = false;
+                        } else {
+                            pw.print(", ");
+                        }
+                        pw.print(UserHandle.formatUid(uid));
+                    }
+                }
+                pw.println();
+            }
             pw.println();
             mJobPackageTracker.dump(pw, "", filterUidFinal);
             pw.println();
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 2dbecbd..68dd00f 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -123,7 +123,8 @@
     }
 
     @Override
-    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) {
+    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
+            boolean forUpdate) {
     }
 
     @Override
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index 91a962d..b1f8f6b 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -24,6 +24,7 @@
 import android.os.BatteryManagerInternal;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -32,9 +33,6 @@
 import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
 
 /**
  * Simple controller that tracks whether the phone is charging or not. The phone is considered to
@@ -47,7 +45,7 @@
     private static final Object sCreationLock = new Object();
     private static volatile BatteryController sController;
 
-    private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
+    private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     private ChargingTracker mChargeTracker;
 
     public static BatteryController get(JobSchedulerService taskManagerService) {
@@ -82,6 +80,7 @@
     public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasPowerConstraint()) {
             mTrackedTasks.add(taskStatus);
+            taskStatus.setTrackingController(JobStatus.TRACKING_BATTERY);
             taskStatus.setChargingConstraintSatisfied(mChargeTracker.isOnStablePower());
             taskStatus.setBatteryNotLowConstraintSatisfied(mChargeTracker.isBatteryNotLow());
         }
@@ -89,7 +88,7 @@
 
     @Override
     public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) {
-        if (taskStatus.hasPowerConstraint()) {
+        if (taskStatus.clearTrackingController(JobStatus.TRACKING_BATTERY)) {
             mTrackedTasks.remove(taskStatus);
         }
     }
@@ -103,7 +102,7 @@
         boolean reportChange = false;
         synchronized (mLock) {
             for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
-                final JobStatus ts = mTrackedTasks.get(i);
+                final JobStatus ts = mTrackedTasks.valueAt(i);
                 boolean previous = ts.setChargingConstraintSatisfied(stablePower);
                 if (previous != stablePower) {
                     reportChange = true;
@@ -251,7 +250,7 @@
         pw.print(mTrackedTasks.size());
         pw.println(":");
         for (int i = 0; i < mTrackedTasks.size(); i++) {
-            final JobStatus js = mTrackedTasks.get(i);
+            final JobStatus js = mTrackedTasks.valueAt(i);
             if (!js.shouldDump(filterUid)) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 5ebcc93..f426818 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -27,6 +27,7 @@
 import android.net.NetworkPolicyManager;
 import android.os.Process;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -34,7 +35,6 @@
 import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Handles changes in connectivity.
@@ -54,7 +54,7 @@
     private boolean mValidated;
 
     @GuardedBy("mLock")
-    private final ArrayList<JobStatus> mTrackedJobs = new ArrayList<JobStatus>();
+    private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
 
     /** Singleton. */
     private static ConnectivityController mSingleton;
@@ -87,13 +87,14 @@
         if (jobStatus.hasConnectivityConstraint()) {
             updateConstraintsSatisfied(jobStatus, null);
             mTrackedJobs.add(jobStatus);
+            jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
         }
     }
 
     @Override
     public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
             boolean forUpdate) {
-        if (jobStatus.hasConnectivityConstraint()) {
+        if (jobStatus.clearTrackingController(JobStatus.TRACKING_CONNECTIVITY)) {
             mTrackedJobs.remove(jobStatus);
         }
     }
@@ -150,8 +151,8 @@
     private void updateTrackedJobs(int uid, NetworkCapabilities capabilities) {
         synchronized (mLock) {
             boolean changed = false;
-            for (int i = 0; i < mTrackedJobs.size(); i++) {
-                final JobStatus js = mTrackedJobs.get(i);
+            for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
+                final JobStatus js = mTrackedJobs.valueAt(i);
                 if (uid == -1 || uid == js.getSourceUid()) {
                     changed |= updateConstraintsSatisfied(js, capabilities);
                 }
@@ -168,8 +169,8 @@
     @Override
     public void onNetworkActive() {
         synchronized (mLock) {
-            for (int i = 0; i < mTrackedJobs.size(); i++) {
-                final JobStatus js = mTrackedJobs.get(i);
+            for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
+                final JobStatus js = mTrackedJobs.valueAt(i);
                 if (js.isReady()) {
                     if (DEBUG) {
                         Slog.d(TAG, "Running " + js + " due to network activity.");
@@ -239,7 +240,7 @@
         pw.print(mTrackedJobs.size());
         pw.println(":");
         for (int i = 0; i < mTrackedJobs.size(); i++) {
-            final JobStatus js = mTrackedJobs.get(i);
+            final JobStatus js = mTrackedJobs.valueAt(i);
             if (js.shouldDump(filterUid)) {
                 pw.print("  #");
                 js.printUniqueId(pw);
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index 29f0e2c..cfafc38 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -35,9 +35,6 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
 
 /**
  * Controller for monitoring changes to content URIs through a ContentObserver.
@@ -61,11 +58,11 @@
     private static final Object sCreationLock = new Object();
     private static volatile ContentObserverController sController;
 
-    final private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
+    final private ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     /**
      * Per-userid {@link JobInfo.TriggerContentUri} keyed ContentObserver cache.
      */
-    SparseArray<ArrayMap<JobInfo.TriggerContentUri, ObserverInstance>> mObservers =
+    final SparseArray<ArrayMap<JobInfo.TriggerContentUri, ObserverInstance>> mObservers =
             new SparseArray<>();
     final Handler mHandler;
 
@@ -101,6 +98,7 @@
                 Slog.i(TAG, "Tracking content-trigger job " + taskStatus);
             }
             mTrackedTasks.add(taskStatus);
+            taskStatus.setTrackingController(JobStatus.TRACKING_CONTENT);
             boolean havePendingUris = false;
             // If there is a previous job associated with the new job, propagate over
             // any pending content URI trigger reports.
@@ -156,7 +154,8 @@
     @Override
     public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob,
             boolean forUpdate) {
-        if (taskStatus.hasContentTriggerConstraint()) {
+        if (taskStatus.clearTrackingController(JobStatus.TRACKING_CONTENT)) {
+            mTrackedTasks.remove(taskStatus);
             if (taskStatus.contentObserverJobInstance != null) {
                 taskStatus.contentObserverJobInstance.unscheduleLocked();
                 if (incomingJob != null) {
@@ -190,7 +189,6 @@
             if (DEBUG) {
                 Slog.i(TAG, "No longer tracking job " + taskStatus);
             }
-            mTrackedTasks.remove(taskStatus);
         }
     }
 
@@ -374,9 +372,8 @@
     @Override
     public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.println("Content:");
-        Iterator<JobStatus> it = mTrackedTasks.iterator();
-        while (it.hasNext()) {
-            JobStatus js = it.next();
+        for (int i = 0; i < mTrackedTasks.size(); i++) {
+            JobStatus js = mTrackedTasks.valueAt(i);
             if (!js.shouldDump(filterUid)) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index f7706d7..5ccf812 100644
--- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -164,13 +164,12 @@
 
     @Override
     public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
-        synchronized (mLock) {
-            updateTaskStateLocked(jobStatus);
-        }
+        updateTaskStateLocked(jobStatus);
     }
 
     @Override
-    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) {
+    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
+            boolean forUpdate) {
     }
 
     @Override
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 0e04d24..7e92293 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -17,7 +17,6 @@
 package com.android.server.job.controllers;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -27,6 +26,7 @@
 import android.content.IntentFilter;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.server.am.ActivityManagerService;
@@ -40,7 +40,7 @@
     // screen off or dreaming for at least this long
     private long mInactivityIdleThreshold;
     private long mIdleWindowSlop;
-    final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
+    final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
     IdlenessTracker mIdleTracker;
 
     // Singleton factory
@@ -69,13 +69,17 @@
     public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasIdleConstraint()) {
             mTrackedTasks.add(taskStatus);
+            taskStatus.setTrackingController(JobStatus.TRACKING_IDLE);
             taskStatus.setIdleConstraintSatisfied(mIdleTracker.isIdle());
         }
     }
 
     @Override
-    public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) {
-        mTrackedTasks.remove(taskStatus);
+    public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob,
+            boolean forUpdate) {
+        if (taskStatus.clearTrackingController(JobStatus.TRACKING_IDLE)) {
+            mTrackedTasks.remove(taskStatus);
+        }
     }
 
     /**
@@ -83,8 +87,8 @@
      */
     void reportNewIdleState(boolean isIdle) {
         synchronized (mLock) {
-            for (JobStatus task : mTrackedTasks) {
-                task.setIdleConstraintSatisfied(isIdle);
+            for (int i = mTrackedTasks.size()-1; i >= 0; i--) {
+                mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(isIdle);
             }
         }
         mStateChangedListener.onControllerStateChanged();
@@ -200,7 +204,7 @@
         pw.print(mTrackedTasks.size());
         pw.println(":");
         for (int i = 0; i < mTrackedTasks.size(); i++) {
-            final JobStatus js = mTrackedTasks.get(i);
+            final JobStatus js = mTrackedTasks.valueAt(i);
             if (!js.shouldDump(filterUid)) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 1ab66b9..7fdb08a 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -128,6 +128,38 @@
     // Set to true if doze constraint was satisfied due to app being whitelisted.
     public boolean dozeWhitelisted;
 
+    /**
+     * Flag for {@link #trackingControllers}: the battery controller is currently tracking this job.
+     */
+    public static final int TRACKING_BATTERY = 1<<0;
+    /**
+     * Flag for {@link #trackingControllers}: the network connectivity controller is currently
+     * tracking this job.
+     */
+    public static final int TRACKING_CONNECTIVITY = 1<<1;
+    /**
+     * Flag for {@link #trackingControllers}: the content observer controller is currently
+     * tracking this job.
+     */
+    public static final int TRACKING_CONTENT = 1<<2;
+    /**
+     * Flag for {@link #trackingControllers}: the idle controller is currently tracking this job.
+     */
+    public static final int TRACKING_IDLE = 1<<3;
+    /**
+     * Flag for {@link #trackingControllers}: the storage controller is currently tracking this job.
+     */
+    public static final int TRACKING_STORAGE = 1<<4;
+    /**
+     * Flag for {@link #trackingControllers}: the time controller is currently tracking this job.
+     */
+    public static final int TRACKING_TIME = 1<<5;
+
+    /**
+     * Bit mask of controllers that are currently tracking the job.
+     */
+    private int trackingControllers;
+
     // These are filled in by controllers when preparing for execution.
     public ArraySet<Uri> changedUris;
     public ArraySet<String> changedAuthorities;
@@ -307,6 +339,7 @@
                     executingWork = new ArrayList<>();
                 }
                 executingWork.add(work);
+                work.bumpDeliveryCount();
             }
             return work;
         }
@@ -609,6 +642,18 @@
         return (satisfiedConstraints&constraint) != 0;
     }
 
+    boolean clearTrackingController(int which) {
+        if ((trackingControllers&which) != 0) {
+            trackingControllers &= ~which;
+            return true;
+        }
+        return false;
+    }
+
+    void setTrackingController(int which) {
+        trackingControllers |= which;
+    }
+
     public boolean shouldDump(int filterUid) {
         return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
                 || UserHandle.getAppId(getSourceUid()) == filterUid;
@@ -617,6 +662,9 @@
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
+     * TODO: This function is called a *lot*.  We should probably just have it check an
+     * already-computed boolean, which we updated whenever we see one of the states it depends
+     * on here change.
      */
     public boolean isReady() {
         // Deadline constraint trumps other constraints (except for periodic jobs where deadline
@@ -812,7 +860,8 @@
 
     private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) {
         pw.print(prefix); pw.print("  #"); pw.print(index); pw.print(": #");
-        pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+        pw.print(work.getWorkId()); pw.print(" "); pw.print(work.getDeliveryCount());
+        pw.print("x "); pw.println(work.getIntent());
         if (work.getGrants() != null) {
             pw.print(prefix); pw.println("  URI grants:");
             ((GrantedUriPermissions)work.getGrants()).dump(pw, prefix + "    ");
@@ -925,6 +974,16 @@
                 pw.print(prefix); pw.println("Doze whitelisted: true");
             }
         }
+        if (trackingControllers != 0) {
+            pw.print(prefix); pw.print("Tracking:");
+            if ((trackingControllers&TRACKING_BATTERY) != 0) pw.print(" BATTERY");
+            if ((trackingControllers&TRACKING_CONNECTIVITY) != 0) pw.print(" CONNECTIVITY");
+            if ((trackingControllers&TRACKING_CONTENT) != 0) pw.print(" CONTENT");
+            if ((trackingControllers&TRACKING_IDLE) != 0) pw.print(" IDLE");
+            if ((trackingControllers&TRACKING_STORAGE) != 0) pw.print(" STORAGE");
+            if ((trackingControllers&TRACKING_TIME) != 0) pw.print(" TIME");
+            pw.println();
+        }
         if (changedAuthorities != null) {
             pw.print(prefix); pw.println("Changed authorities:");
             for (int i=0; i<changedAuthorities.size(); i++) {
diff --git a/services/core/java/com/android/server/job/controllers/StorageController.java b/services/core/java/com/android/server/job/controllers/StorageController.java
index 60ae5a7..4fe8eca 100644
--- a/services/core/java/com/android/server/job/controllers/StorageController.java
+++ b/services/core/java/com/android/server/job/controllers/StorageController.java
@@ -20,9 +20,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.os.BatteryManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -31,8 +31,6 @@
 import com.android.server.storage.DeviceStorageMonitorService;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Simple controller that tracks the status of the device's storage.
@@ -43,7 +41,7 @@
     private static final Object sCreationLock = new Object();
     private static volatile StorageController sController;
 
-    private List<JobStatus> mTrackedTasks = new ArrayList<JobStatus>();
+    private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<JobStatus>();
     private StorageTracker mStorageTracker;
 
     public static StorageController get(JobSchedulerService taskManagerService) {
@@ -78,13 +76,15 @@
     public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
         if (taskStatus.hasStorageNotLowConstraint()) {
             mTrackedTasks.add(taskStatus);
+            taskStatus.setTrackingController(JobStatus.TRACKING_STORAGE);
             taskStatus.setStorageNotLowConstraintSatisfied(mStorageTracker.isStorageNotLow());
         }
     }
 
     @Override
-    public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) {
-        if (taskStatus.hasPowerConstraint()) {
+    public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob,
+            boolean forUpdate) {
+        if (taskStatus.clearTrackingController(JobStatus.TRACKING_STORAGE)) {
             mTrackedTasks.remove(taskStatus);
         }
     }
@@ -94,7 +94,7 @@
         boolean reportChange = false;
         synchronized (mLock) {
             for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
-                final JobStatus ts = mTrackedTasks.get(i);
+                final JobStatus ts = mTrackedTasks.valueAt(i);
                 boolean previous = ts.setStorageNotLowConstraintSatisfied(storageNotLow);
                 if (previous != storageNotLow) {
                     reportChange = true;
@@ -178,7 +178,7 @@
         pw.print(mTrackedTasks.size());
         pw.println(":");
         for (int i = 0; i < mTrackedTasks.size(); i++) {
-            final JobStatus js = mTrackedTasks.get(i);
+            final JobStatus js = mTrackedTasks.valueAt(i);
             if (!js.shouldDump(filterUid)) {
                 continue;
             }
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 0b3b00f..01c841e 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -51,7 +51,7 @@
 
     private AlarmManager mAlarmService = null;
     /** List of tracked jobs, sorted asc. by deadline */
-    private final List<JobStatus> mTrackedJobs = new LinkedList<JobStatus>();
+    private final List<JobStatus> mTrackedJobs = new LinkedList<>();
     /** Singleton. */
     private static TimeController mSingleton;
 
@@ -78,6 +78,20 @@
     public void maybeStartTrackingJobLocked(JobStatus job, JobStatus lastJob) {
         if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) {
             maybeStopTrackingJobLocked(job, null, false);
+
+            // First: check the constraints now, because if they are already satisfied
+            // then there is no need to track it.  This gives us a fast path for a common
+            // pattern of having a job with a 0 deadline constraint ("run immediately").
+            // Unlike most controllers, once one of our constraints has been satisfied, it
+            // will never be unsatisfied (our time base can not go backwards).
+            final long nowElapsedMillis = SystemClock.elapsedRealtime();
+            if (job.hasDeadlineConstraint() && evaluateDeadlineConstraint(job, nowElapsedMillis)) {
+                return;
+            } else if (job.hasTimingDelayConstraint() && evaluateTimingDelayConstraint(job,
+                    nowElapsedMillis)) {
+                return;
+            }
+
             boolean isInsert = false;
             ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size());
             while (it.hasPrevious()) {
@@ -92,6 +106,7 @@
                 it.next();
             }
             it.add(job);
+            job.setTrackingController(JobStatus.TRACKING_TIME);
             maybeUpdateAlarmsLocked(
                     job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
                     job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE,
@@ -102,13 +117,15 @@
     /**
      * When we stop tracking a job, we only need to update our alarms if the job we're no longer
      * tracking was the one our alarms were based off of.
-     * Really an == comparison should be enough, but why play with fate? We'll do <=.
      */
     @Override
-    public void maybeStopTrackingJobLocked(JobStatus job, JobStatus incomingJob, boolean forUpdate) {
-        if (mTrackedJobs.remove(job)) {
-            checkExpiredDelaysAndResetAlarm();
-            checkExpiredDeadlinesAndResetAlarm();
+    public void maybeStopTrackingJobLocked(JobStatus job, JobStatus incomingJob,
+            boolean forUpdate) {
+        if (job.clearTrackingController(JobStatus.TRACKING_TIME)) {
+            if (mTrackedJobs.remove(job)) {
+                checkExpiredDelaysAndResetAlarm();
+                checkExpiredDeadlinesAndResetAlarm();
+            }
         }
     }
 
@@ -147,17 +164,12 @@
                 if (!job.hasDeadlineConstraint()) {
                     continue;
                 }
-                final long jobDeadline = job.getLatestRunTimeElapsed();
 
-                if (jobDeadline <= nowElapsedMillis) {
-                    if (job.hasTimingDelayConstraint()) {
-                        job.setTimingDelayConstraintSatisfied(true);
-                    }
-                    job.setDeadlineConstraintSatisfied(true);
+                if (evaluateDeadlineConstraint(job, nowElapsedMillis)) {
                     mStateChangedListener.onRunJobNow(job);
                     it.remove();
                 } else {  // Sorted by expiry time, so take the next one and stop.
-                    nextExpiryTime = jobDeadline;
+                    nextExpiryTime = job.getLatestRunTimeElapsed();
                     nextExpiryUid = job.getSourceUid();
                     break;
                 }
@@ -166,6 +178,19 @@
         }
     }
 
+    private boolean evaluateDeadlineConstraint(JobStatus job, long nowElapsedMillis) {
+        final long jobDeadline = job.getLatestRunTimeElapsed();
+
+        if (jobDeadline <= nowElapsedMillis) {
+            if (job.hasTimingDelayConstraint()) {
+                job.setTimingDelayConstraintSatisfied(true);
+            }
+            job.setDeadlineConstraintSatisfied(true);
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Handles alarm that notifies us that a job's delay has expired. Iterates through the list of
      * tracked jobs and marks them as ready as appropriate.
@@ -182,9 +207,7 @@
                 if (!job.hasTimingDelayConstraint()) {
                     continue;
                 }
-                final long jobDelayTime = job.getEarliestRunTime();
-                if (jobDelayTime <= nowElapsedMillis) {
-                    job.setTimingDelayConstraintSatisfied(true);
+                if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) {
                     if (canStopTrackingJobLocked(job)) {
                         it.remove();
                     }
@@ -194,6 +217,7 @@
                 } else if (!job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY)) {
                     // If this job still doesn't have its delay constraint satisfied,
                     // then see if it is the next upcoming delay time for the alarm.
+                    final long jobDelayTime = job.getEarliestRunTime();
                     if (nextDelayTime > jobDelayTime) {
                         nextDelayTime = jobDelayTime;
                         nextDelayUid = job.getSourceUid();
@@ -207,6 +231,15 @@
         }
     }
 
+    private boolean evaluateTimingDelayConstraint(JobStatus job, long nowElapsedMillis) {
+        final long jobDelayTime = job.getEarliestRunTime();
+        if (jobDelayTime <= nowElapsedMillis) {
+            job.setTimingDelayConstraintSatisfied(true);
+            return true;
+        }
+        return false;
+    }
+
     private void maybeUpdateAlarmsLocked(long delayExpiredElapsed, long deadlineExpiredElapsed,
             int uid) {
         if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 64ab848..0db1b5d 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -965,7 +965,7 @@
             final int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
-                if (uid != Process.BLUETOOTH_UID) {
+                if (!UserHandle.isSameApp(uid, Process.BLUETOOTH_UID)) {
                     throw new SecurityException("Only Bluetooth service processes can set"
                             + " Callback");
                 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 9157c4e..39585a1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1254,14 +1254,13 @@
         // TODO: move to NotificationManager once we can mock it
         try {
             final String packageName = mContext.getPackageName();
-            final int[] idReceived = new int[1];
             if (!TextUtils.isEmpty(body)) {
                 builder.setStyle(new Notification.BigTextStyle()
                         .bigText(body));
             }
             mNotifManager.enqueueNotificationWithTag(
                     packageName, packageName, notificationId.getTag(), notificationId.getId(),
-                    builder.build(), idReceived, UserHandle.USER_ALL);
+                    builder.build(), UserHandle.USER_ALL);
             mActiveNotifs.add(notificationId);
         } catch (RemoteException e) {
             // ignored; service lives in system_server
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index c6b0d36..4923b06 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -20,7 +20,7 @@
 
 public interface NotificationManagerInternal {
     void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid,
-            String tag, int id, Notification notification, int[] idReceived, int userId);
+            String tag, int id, Notification notification, int userId);
 
     void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId);
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 81a8e68b3..1e7d076 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1080,7 +1080,7 @@
                     }
                     enqueueNotificationInternal(r.sbn.getPackageName(), r.sbn.getOpPkg(),
                             r.sbn.getUid(), r.sbn.getInitialPid(), r.sbn.getTag(), r.sbn.getId(),
-                            r.sbn.getNotification(), new int[1], userId);
+                            r.sbn.getNotification(), userId);
                 } catch (Exception e) {
                     Slog.e(TAG, "Cannot un-snooze notification", e);
                 }
@@ -1558,9 +1558,9 @@
 
         @Override
         public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
-                Notification notification, int[] idOut, int userId) throws RemoteException {
+                Notification notification, int userId) throws RemoteException {
             enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
-                    Binder.getCallingPid(), tag, id, notification, idOut, userId);
+                    Binder.getCallingPid(), tag, id, notification, userId);
         }
 
         @Override
@@ -3095,9 +3095,9 @@
     private final NotificationManagerInternal mInternalService = new NotificationManagerInternal() {
         @Override
         public void enqueueNotification(String pkg, String opPkg, int callingUid, int callingPid,
-                String tag, int id, Notification notification, int[] idReceived, int userId) {
+                String tag, int id, Notification notification, int userId) {
             enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
-                    idReceived, userId);
+                    userId);
         }
 
         @Override
@@ -3139,7 +3139,7 @@
 
     void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
             final int callingPid, final String tag, final int id, final Notification notification,
-            int[] idOut, int incomingUserId) {
+            int incomingUserId) {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                     + " notification=" + notification);
@@ -3236,8 +3236,6 @@
         }
 
         mHandler.post(new EnqueueNotificationRunnable(userId, r));
-
-        idOut[0] = id;
     }
 
     private void doDebugOnlyToast(CharSequence toastText) {
@@ -3650,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
@@ -3661,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) {
@@ -3718,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..6d18c83 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -33,7 +33,6 @@
 import android.metrics.LogMaker;
 import android.os.Build;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -508,6 +507,14 @@
         updateConfig();
     }
 
+    int getPackagePriority(String pkg, int uid) {
+        return getOrCreateRecord(pkg, uid).priority;
+    }
+
+    int getPackageVisibility(String pkg, int uid) {
+        return getOrCreateRecord(pkg, uid).visibility;
+    }
+
     @Override
     public void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
             boolean fromTargetApp) {
@@ -561,7 +568,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");
         }
@@ -608,6 +615,16 @@
         }
         r.channels.put(updatedChannel.getId(), updatedChannel);
 
+        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(updatedChannel.getId())) {
+            // copy settings to app level so they are inherited by new channels
+            // when the app migrates
+            r.importance = updatedChannel.getImportance();
+            r.priority = updatedChannel.canBypassDnd()
+                    ? Notification.PRIORITY_MAX : Notification.PRIORITY_DEFAULT;
+            r.visibility = updatedChannel.getLockscreenVisibility();
+            r.showBadge = updatedChannel.canShowBadge();
+        }
+
         MetricsLogger.action(getChannelLog(updatedChannel, pkg));
         updateConfig();
     }
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/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 21d78ee..9d08004 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -35,6 +35,7 @@
 import android.util.Slog;
 import android.util.TimedRemoteCaller;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.TransferPipe;
 
 import java.io.FileDescriptor;
@@ -53,7 +54,9 @@
     private static final String TAG = "PackageManager";
     // This is running in a critical section and the timeout must be sufficiently low
     private static final long BIND_SERVICE_TIMEOUT_MS =
-            ("eng".equals(Build.TYPE)) ? 300 : 200;
+            ("eng".equals(Build.TYPE)) ? 500 : 300;
+    private static final long CALL_SERVICE_TIMEOUT_MS =
+            ("eng".equals(Build.TYPE)) ? 200 : 100;
     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
 
     private final Object mLock = new Object();
@@ -64,7 +67,9 @@
     /** Intent used to bind to the service */
     private final Intent mIntent;
 
-    private volatile boolean mBindRequested;
+    @GuardedBy("mLock")
+    private volatile boolean mIsBinding;
+    @GuardedBy("mLock")
     private IInstantAppResolver mRemoteInstance;
 
     public EphemeralResolverConnection(
@@ -76,11 +81,18 @@
     public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[],
             String token) {
         throwIfCalledOnMainThread();
+        IInstantAppResolver target = null;
         try {
-            return mGetEphemeralResolveInfoCaller.getEphemeralResolveInfoList(
-                    getRemoteInstanceLazy(), hashPrefix, token);
-        } catch (RemoteException re) {
-        } catch (TimeoutException te) {
+            target = getRemoteInstanceLazy(token);
+            return mGetEphemeralResolveInfoCaller
+                    .getEphemeralResolveInfoList(target, hashPrefix, token);
+        } catch (RemoteException e) {
+        } catch (InterruptedException | TimeoutException e) {
+            if (target == null) {
+                Slog.w(TAG, "[" + token + "] Timeout! Phase1 binding to instant app resolver");
+            } else {
+                Slog.w(TAG, "[" + token + "] Timeout! Phase1 resolving instant app");
+            }
         } finally {
             synchronized (mLock) {
                 mLock.notifyAll();
@@ -107,70 +119,73 @@
             }
         };
         try {
-            getRemoteInstanceLazy()
+            getRemoteInstanceLazy(token)
                     .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback);
-        } catch (RemoteException re) {
-        } catch (TimeoutException te) {
+        } catch (RemoteException e) {
+        } catch (InterruptedException | TimeoutException e) {
+            Slog.w(TAG, "[" + token + "] Timeout! Phase2 binding to instant app resolver");
         }
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
-        synchronized (mLock) {
-            pw.append(prefix).append("bound=")
-                    .append((mRemoteInstance != null) ? "true" : "false").println();
-
-            pw.flush();
-            try {
-                TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
-                        new String[] { prefix });
-            } catch (IOException | TimeoutException | RemoteException e) {
-                pw.println("Failed to dump remote instance: " + e);
-            }
-        }
-    }
-
-    private IInstantAppResolver getRemoteInstanceLazy() throws TimeoutException {
+    private IInstantAppResolver getRemoteInstanceLazy(String token)
+            throws TimeoutException, InterruptedException {
         synchronized (mLock) {
             if (mRemoteInstance != null) {
                 return mRemoteInstance;
             }
-            bindLocked();
+            bindLocked(token);
             return mRemoteInstance;
         }
     }
 
-    private void bindLocked() throws TimeoutException {
-        if (mRemoteInstance != null) {
-            return;
-        }
-
-        if (!mBindRequested) {
-            mBindRequested = true;
-            if (DEBUG_EPHEMERAL) {
-                Slog.d(TAG, "Binding to resolver service");
-            }
-            mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM);
-        }
-
+    private void waitForBind(String token) throws TimeoutException, InterruptedException {
         final long startMillis = SystemClock.uptimeMillis();
-        while (true) {
+        while (mIsBinding) {
             if (mRemoteInstance != null) {
                 break;
             }
             final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
             final long remainingMillis = BIND_SERVICE_TIMEOUT_MS - elapsedMillis;
             if (remainingMillis <= 0) {
-                throw new TimeoutException("Didn't bind to resolver in time.");
+                throw new TimeoutException("[" + token + "] Didn't bind to resolver in time!");
             }
-            try {
-                mLock.wait(remainingMillis);
-            } catch (InterruptedException ie) {
-                /* ignore */
-            }
+            mLock.wait(remainingMillis);
         }
+    }
 
-        mLock.notifyAll();
+    private void bindLocked(String token) throws TimeoutException, InterruptedException {
+        if (DEBUG_EPHEMERAL && mIsBinding && mRemoteInstance == null) {
+            Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
+        }
+        try {
+            waitForBind(token);
+        } catch (TimeoutException e) {
+            if (DEBUG_EPHEMERAL) {
+                Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
+            }
+            mContext.unbindService(mServiceConnection);
+        }
+        if (mRemoteInstance != null) {
+            return;
+        }
+        mIsBinding = true;
+        if (DEBUG_EPHEMERAL) {
+            Slog.v(TAG, "[" + token + "] Binding to instant app resolver");
+        }
+        boolean wasBound = false;
+        try {
+            final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+            wasBound = mContext
+                    .bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM);
+            if (wasBound) {
+                waitForBind(token);
+            } else {
+                Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent);
+            }
+        } finally {
+            mIsBinding = wasBound && mRemoteInstance == null;
+            mLock.notifyAll();
+        }
     }
 
     private void throwIfCalledOnMainThread() {
@@ -182,13 +197,18 @@
     @Override
     public void binderDied() {
         if (DEBUG_EPHEMERAL) {
-            Slog.d(TAG, "Binder died");
+            Slog.d(TAG, "Binder to instant app resolver died");
         }
+        synchronized (mLock) {
+            handleBinderDiedLocked();
+        }
+    }
+
+    private void handleBinderDiedLocked() {
         if (mRemoteInstance != null) {
             mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/);
         }
         mRemoteInstance = null;
-        mBindRequested = false;
     }
 
     /**
@@ -203,13 +223,15 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DEBUG_EPHEMERAL) {
-                Slog.d(TAG, "Service connected");
+                Slog.d(TAG, "Connected to instant app resolver");
             }
             synchronized (mLock) {
+                mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
+                mIsBinding = false;
                 try {
                     service.linkToDeath(EphemeralResolverConnection.this, 0 /*flags*/);
-                    mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
                 } catch (RemoteException e) {
+                    handleBinderDiedLocked();
                 }
                 mLock.notifyAll();
             }
@@ -218,10 +240,10 @@
         @Override
         public void onServiceDisconnected(ComponentName name) {
             if (DEBUG_EPHEMERAL) {
-                Slog.d(TAG, "Service disconnected");
+                Slog.d(TAG, "Disconnected from instant app resolver");
             }
             synchronized (mLock) {
-                mRemoteInstance = null;
+                handleBinderDiedLocked();
             }
         }
     }
@@ -231,7 +253,7 @@
         private final IRemoteCallback mCallback;
 
         public GetEphemeralResolveInfoCaller() {
-            super(BIND_SERVICE_TIMEOUT_MS);
+            super(CALL_SERVICE_TIMEOUT_MS);
             mCallback = new IRemoteCallback.Stub() {
                     @Override
                     public void sendResult(Bundle data) throws RemoteException {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 1e2b743..c5cefc8 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -258,10 +258,11 @@
         }
     }
 
-    public long[] getExternalSize(String uuid, int userId, int flags) throws InstallerException {
+    public long[] getExternalSize(String uuid, int userId, int flags, int[] appIds)
+            throws InstallerException {
         if (!checkBeforeRemote()) return new long[4];
         try {
-            return mInstalld.getExternalSize(uuid, userId, flags);
+            return mInstalld.getExternalSize(uuid, userId, flags, appIds);
         } catch (Exception e) {
             throw InstallerException.from(e);
         }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 6f593b0..b56db04 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -74,11 +74,11 @@
 
     public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(Context context,
             EphemeralResolverConnection connection, InstantAppRequest requestObj) {
-        if (DEBUG_EPHEMERAL) {
-            Log.d(TAG, "Resolving phase 1");
-        }
         final long startTime = System.currentTimeMillis();
         final String token = UUID.randomUUID().toString();
+        if (DEBUG_EPHEMERAL) {
+            Log.d(TAG, "[" + token + "] Resolving phase 1");
+        }
         final Intent intent = requestObj.origIntent;
         final InstantAppDigest digest =
                 new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/);
@@ -89,7 +89,7 @@
         if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) {
             // No hash prefix match; there are no instant apps for this domain.
             if (DEBUG_EPHEMERAL) {
-                Log.d(TAG, "No results returned");
+                Log.d(TAG, "[" + token + "] No results returned");
             }
             return null;
         }
@@ -98,21 +98,24 @@
                 intent.getPackage(), digest, token);
         logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token,
                 RESOLUTION_SUCCESS);
+        if (DEBUG_EPHEMERAL && resolveInfo == null) {
+            Log.d(TAG, "[" + token + "] No results matched");
+        }
         return resolveInfo;
     }
 
     public static void doInstantAppResolutionPhaseTwo(Context context,
             EphemeralResolverConnection connection, InstantAppRequest requestObj,
             ActivityInfo instantAppInstaller, Handler callbackHandler) {
-        if (DEBUG_EPHEMERAL) {
-            Log.d(TAG, "Resolving phase 2");
-        }
         final long startTime = System.currentTimeMillis();
+        final String token = requestObj.responseObj.token;
+        if (DEBUG_EPHEMERAL) {
+            Log.d(TAG, "[" + token + "] Resolving phase 2");
+        }
         final Intent intent = requestObj.origIntent;
         final String hostName = intent.getData().getHost();
         final InstantAppDigest digest = new InstantAppDigest(hostName, 5 /*maxDigests*/);
         final int[] shaPrefix = digest.getDigestPrefix();
-        final String token = requestObj.responseObj.token;
 
         final PhaseTwoCallback callback = new PhaseTwoCallback() {
             @Override
@@ -285,12 +288,16 @@
                 if (!matchedResolveInfoList.isEmpty()) {
                     if (DEBUG_EPHEMERAL) {
                         final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0);
-                        Log.d(TAG, "Found match;"
+                        Log.d(TAG, "[" + token + "] Found match;"
                                 + " package: " + info.packageName
                                 + ", split: " + info.splitName
                                 + ", versionCode: " + info.versionCode);
                     }
                     return matchedResolveInfoList.get(0);
+                } else if (DEBUG_EPHEMERAL) {
+                    Log.d(TAG, "[" + token + "] No matches found"
+                            + " package: " + instantAppInfo.getPackageName()
+                            + ", versionCode: " + instantAppInfo.getVersionCode());
                 }
             }
         }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 8413491..254bc2a 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -28,6 +28,7 @@
 import android.os.WorkSource;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
@@ -141,7 +142,7 @@
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
-        final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
+        final List<String> paths = pkg.getAllCodePaths();
         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
 
         final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
@@ -149,18 +150,32 @@
         final boolean profileUpdated = checkForProfileUpdates &&
                 isProfileUpdated(pkg, sharedGid, compilerFilter);
 
-        String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
+        final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
         // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
         final int dexoptFlags = getDexFlags(pkg, compilerFilter);
+        // Get the dependencies of each split in the package. For each code path in the package,
+        // this array contains the relative paths of each split it depends on, separated by colons.
+        String[] splitDependencies = getSplitDependencies(pkg);
 
         int result = DEX_OPT_SKIPPED;
-        // TODO: Iterate based on dependency hierarchy (currently alphabetically by name)
-        // (b/37480811).
-        String basePathCheck = null;
-        for (String path : paths) {
+        for (int i = 0; i < paths.size(); i++) {
+            // Skip paths that have no code.
+            if ((i == 0 && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) ||
+                    (i != 0 && (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) == 0)) {
+                continue;
+            }
+            // Append shared libraries with split dependencies for this split.
+            String path = paths.get(i);
+            String sharedLibrariesPathWithSplits;
+            if (sharedLibrariesPath != null && splitDependencies[i] != null) {
+                sharedLibrariesPathWithSplits = sharedLibrariesPath + ":" + splitDependencies[i];
+            } else {
+                sharedLibrariesPathWithSplits =
+                        splitDependencies[i] != null ? splitDependencies[i] : sharedLibrariesPath;
+            }
             for (String dexCodeIsa : dexCodeInstructionSets) {
                 int newResult = dexOptPath(pkg, path, dexCodeIsa, compilerFilter, profileUpdated,
-                        sharedLibrariesPath, dexoptFlags, sharedGid, packageStats);
+                        sharedLibrariesPathWithSplits, dexoptFlags, sharedGid, packageStats);
                 // The end result is:
                 //  - FAILED if any path failed,
                 //  - PERFORMED if at least one path needed compilation,
@@ -168,22 +183,6 @@
                 if ((result != DEX_OPT_FAILED) && (newResult != DEX_OPT_SKIPPED)) {
                     result = newResult;
                 }
-                // Add the relative path of code we just compiled to the shared libraries.
-                int slashIndex = path.lastIndexOf('/') + 1;
-                String relativePath = path.substring(slashIndex);
-                if (sharedLibrariesPath == null) {
-                    sharedLibrariesPath = relativePath;
-                } else {
-                    sharedLibrariesPath += ":" + relativePath;
-                }
-                // Sanity check that the base paths are all the same.
-                String basePath = path.substring(0, slashIndex);
-                if (basePathCheck == null) {
-                    basePathCheck = basePath;
-                } else if (!basePath.equals(basePathCheck)) {
-                    Slog.wtf(TAG, "Split paths have different base paths: " + basePath + " and " +
-                        basePathCheck);
-                }
             }
         }
         return result;
@@ -437,6 +436,69 @@
     }
 
     /**
+     * Walks dependency tree and gathers the dependencies for each split in a split apk.
+     * The split paths are stored as relative paths, separated by colons.
+     */
+    private String[] getSplitDependencies(PackageParser.Package pkg) {
+        // Convert all the code paths to relative paths.
+        String baseCodePath = new File(pkg.baseCodePath).getParent();
+        List<String> paths = pkg.getAllCodePaths();
+        String[] splitDependencies = new String[paths.size()];
+        for (int i = 0; i < paths.size(); i++) {
+            File pathFile = new File(paths.get(i));
+            String fileName = pathFile.getName();
+            paths.set(i, fileName);
+
+            // Sanity check that the base paths of the splits are all the same.
+            String basePath = pathFile.getParent();
+            if (!basePath.equals(baseCodePath)) {
+                Slog.wtf(TAG, "Split paths have different base paths: " + basePath + " and " +
+                        baseCodePath);
+            }
+        }
+
+        // If there are no other dependencies, fill in the implicit dependency on the base apk.
+        SparseArray<int[]> dependencies = pkg.applicationInfo.splitDependencies;
+        if (dependencies == null) {
+            for (int i = 1; i < paths.size(); i++) {
+                splitDependencies[i] = paths.get(0);
+            }
+            return splitDependencies;
+        }
+
+        // Fill in the dependencies, skipping the base apk which has no dependencies.
+        for (int i = 1; i < dependencies.size(); i++) {
+            getParentDependencies(dependencies.keyAt(i), paths, dependencies, splitDependencies);
+        }
+
+        return splitDependencies;
+    }
+
+    /**
+     * Recursive method to generate dependencies for a particular split.
+     * The index is a key from the package's splitDependencies.
+     */
+    private String getParentDependencies(int index, List<String> paths,
+            SparseArray<int[]> dependencies, String[] splitDependencies) {
+        // The base apk is always first, and has no dependencies.
+        if (index == 0) {
+            return null;
+        }
+        // Return the result if we've computed the dependencies for this index already.
+        if (splitDependencies[index] != null) {
+            return splitDependencies[index];
+        }
+        // Get the dependencies for the parent of this index and append its path to it.
+        int parent = dependencies.get(index)[0];
+        String parentDependencies =
+                getParentDependencies(parent, paths, dependencies, splitDependencies);
+        String path = parentDependencies == null ? paths.get(parent) :
+                parentDependencies + ":" + paths.get(parent);
+        splitDependencies[index] = path;
+        return path;
+    }
+
+    /**
      * Checks if there is an update on the profile information of the {@code pkg}.
      * If the compiler filter is not profile guided the method returns false.
      *
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4d026e3d..7bbb1fe 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -96,7 +96,7 @@
 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
-import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
+import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
@@ -536,9 +536,8 @@
     public static final int REASON_INSTALL = 2;
     public static final int REASON_BACKGROUND_DEXOPT = 3;
     public static final int REASON_AB_OTA = 4;
-    public static final int REASON_FORCED_DEXOPT = 5;
 
-    public static final int REASON_LAST = REASON_FORCED_DEXOPT;
+    public static final int REASON_LAST = REASON_AB_OTA;
 
     /** All dangerous permission names in the same order as the events in MetricsEvent */
     private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
@@ -1780,6 +1779,8 @@
 
             final boolean update = res.removedInfo != null
                     && res.removedInfo.removedPackage != null;
+            final String origInstallerPackageName = res.removedInfo != null
+                    ? res.removedInfo.installerPackageName : null;
 
             // If this is the first time we have child packages for a disabled privileged
             // app that had no children, we grant requested runtime permissions to the new
@@ -1841,8 +1842,13 @@
                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
                 }
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                        extras, 0 /*flags*/, null /*targetPackage*/,
-                        null /*finishedReceiver*/, updateUsers);
+                        extras, 0 /*flags*/,
+                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
+                if (origInstallerPackageName != null) {
+                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+                            extras, 0 /*flags*/,
+                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
+                }
 
                 // Send replaced for users that don't see the package for the first time
                 if (update) {
@@ -1850,6 +1856,11 @@
                             packageName, extras, 0 /*flags*/,
                             null /*targetPackage*/, null /*finishedReceiver*/,
                             updateUsers);
+                    if (origInstallerPackageName != null) {
+                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+                                extras, 0 /*flags*/,
+                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
+                    }
                     sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                             null /*package*/, null /*extras*/, 0 /*flags*/,
                             packageName /*targetPackage*/,
@@ -4063,14 +4074,26 @@
      * action and a {@code android.intent.category.BROWSABLE} category</li>
      * </ul>
      */
+    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
+        return updateFlagsForResolve(flags, userId, intent, callingUid,
+                false /*includeInstantApps*/, false /*onlyExposedExplicitly*/);
+    }
     int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
             boolean includeInstantApps) {
+        return updateFlagsForResolve(flags, userId, intent, callingUid,
+                includeInstantApps, false /*onlyExposedExplicitly*/);
+    }
+    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
+            boolean includeInstantApps, boolean onlyExposedExplicitly) {
         // Safe mode means we shouldn't match any third-party components
         if (mSafeMode) {
             flags |= PackageManager.MATCH_SYSTEM_ONLY;
         }
         if (getInstantAppPackageName(callingUid) != null) {
             // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
+            if (onlyExposedExplicitly) {
+                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
+            }
             flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
             flags |= PackageManager.MATCH_INSTANT;
         } else {
@@ -4087,7 +4110,8 @@
                     || isSpecialProcess
                     || mContext.checkCallingOrSelfPermission(
                             android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
-            flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
+            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
+                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
             if (!allowMatchInstant) {
                 flags &= ~PackageManager.MATCH_INSTANT;
             }
@@ -5648,19 +5672,19 @@
     }
 
     private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
-            int flags, int userId, boolean includeInstantApps) {
+            int flags, int userId, boolean resolveForStart) {
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
 
             if (!sUserManager.exists(userId)) return null;
             final int callingUid = Binder.getCallingUid();
-            flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
+            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
             enforceCrossUserPermission(callingUid, userId,
                     false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
 
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
             final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
-                    flags, userId, includeInstantApps);
+                    flags, userId, resolveForStart);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             final ResolveInfo bestChoice =
@@ -6197,14 +6221,14 @@
     }
 
     private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, int flags, int userId, boolean includeInstantApps) {
+            String resolvedType, int flags, int userId, boolean resolveForStart) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
         final int callingUid = Binder.getCallingUid();
         final String instantAppPkgName = getInstantAppPackageName(callingUid);
-        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
         enforceCrossUserPermission(callingUid, userId,
                 false /* requireFullPermission */, false /* checkShell */,
                 "query intent activities");
+        final String pkgName = intent.getPackage();
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -6213,6 +6237,8 @@
             }
         }
 
+        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
+                comp != null || pkgName != null /*onlyExposedExplicitly*/);
         if (comp != null) {
             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
@@ -6225,6 +6251,8 @@
                         (flags & PackageManager.MATCH_INSTANT) != 0;
                 final boolean matchVisibleToInstantAppOnly =
                         (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+                final boolean matchExplicitlyVisibleOnly =
+                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
                 final boolean isCallerInstantApp =
                         instantAppPkgName != null;
                 final boolean isTargetSameInstantApp =
@@ -6232,8 +6260,14 @@
                 final boolean isTargetInstantApp =
                         (ai.applicationInfo.privateFlags
                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
+                final boolean isTargetVisibleToInstantApp =
+                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+                final boolean isTargetExplicitlyVisibleToInstantApp =
+                        isTargetVisibleToInstantApp
+                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
                 final boolean isTargetHiddenFromInstantApp =
-                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
+                        !isTargetVisibleToInstantApp
+                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
                 final boolean blockResolution =
                         !isTargetSameInstantApp
                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
@@ -6252,7 +6286,6 @@
         boolean sortResult = false;
         boolean addEphemeral = false;
         List<ResolveInfo> result;
-        final String pkgName = intent.getPackage();
         final boolean ephemeralDisabled = isEphemeralDisabled();
         synchronized (mPackages) {
             if (pkgName == null) {
@@ -6518,7 +6551,7 @@
             }
             // allow activities that have been explicitly exposed to ephemeral apps
             if (!isEphemeralApp
-                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
+                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                 continue;
             }
             resolveInfos.remove(i);
@@ -7058,16 +7091,16 @@
     @Override
     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
         final int callingUid = Binder.getCallingUid();
-        return resolveServiceInternal(
-                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
+        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
     }
 
     private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
-            int userId, int callingUid, boolean includeInstantApps) {
+            int userId, int callingUid) {
         if (!sUserManager.exists(userId)) return null;
-        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
+        flags = updateFlagsForResolve(
+                flags, userId, intent, callingUid, false /*includeInstantApps*/);
         List<ResolveInfo> query = queryIntentServicesInternal(
-                intent, resolvedType, flags, userId, callingUid, includeInstantApps);
+                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
         if (query != null) {
             if (query.size() >= 1) {
                 // If there is more than one service with the same priority,
@@ -7119,7 +7152,7 @@
                         (si.applicationInfo.privateFlags
                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                 final boolean isTargetHiddenFromInstantApp =
-                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
+                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
                 final boolean blockResolution =
                         !isTargetSameInstantApp
                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
@@ -7191,7 +7224,7 @@
             }
             // allow services that have been explicitly exposed to ephemeral apps
             if (!isEphemeralApp
-                    && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
+                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                 continue;
             }
             resolveInfos.remove(i);
@@ -7240,7 +7273,7 @@
                         (pi.applicationInfo.privateFlags
                                 & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                 final boolean isTargetHiddenFromInstantApp =
-                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
+                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
                 final boolean blockResolution =
                         !isTargetSameInstantApp
                         && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
@@ -7312,7 +7345,7 @@
             }
             // allow providers that have been explicitly exposed to instant applications
             if (!isEphemeralApp
-                    && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
+                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                 continue;
             }
             resolveInfos.remove(i);
@@ -7672,7 +7705,8 @@
                 }
                 // instant application; filter out non-exposed provider
                 if (instantAppPkgName != null
-                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
+                        && !isInstantApp
+                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
                     return null;
                 }
                 // provider not enabled
@@ -8580,14 +8614,6 @@
         mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
     }
 
-    // TODO: this is not used nor needed. Delete it.
-    @Override
-    public boolean performDexOptIfNeeded(String packageName) {
-        int dexOptStatus = performDexOptTraced(packageName,
-                false /* checkProfiles */, getFullCompilerFilter(), false /* force */);
-        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
-    }
-
     @Override
     public boolean performDexOpt(String packageName,
             boolean checkProfiles, int compileReason, boolean force) {
@@ -8864,10 +8890,10 @@
         synchronized (mInstallLock) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 
-            // Whoever is calling forceDexOpt wants a fully compiled package.
+            // Whoever is calling forceDexOpt wants a compiled package.
             // Don't use profiles since that may cause compilation to be skipped.
             final int res = performDexOptInternalWithDependenciesLI(pkg,
-                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
+                    false /* checkProfiles */, getDefaultCompilerFilter(),
                     true /* force */);
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -12426,16 +12452,21 @@
             if (ai == null) {
                 return null;
             }
+            final boolean matchExplicitlyVisibleOnly =
+                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
             final boolean matchVisibleToInstantApp =
                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
-            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+            final boolean componentVisible =
+                    matchVisibleToInstantApp
+                    && info.isVisibleToInstantApp()
+                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
+            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
             // throw out filters that aren't visible to ephemeral apps
-            if (matchVisibleToInstantApp
-                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
                 return null;
             }
-            // throw out ephemeral filters if we're not explicitly requesting them
-            if (!isInstantApp && userState.instantApp) {
+            // throw out instant app filters if we're not explicitly requesting them
+            if (!matchInstantApp && userState.instantApp) {
                 return null;
             }
             // throw out instant app filters if updates are available; will trigger
@@ -13521,6 +13552,7 @@
             int userId) {
         final PackageRemovedInfo info = new PackageRemovedInfo(this);
         info.removedPackage = packageName;
+        info.installerPackageName = pkgSetting.installerPackageName;
         info.removedUsers = new int[] {userId};
         info.broadcastUsers = new int[] {userId};
         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
@@ -14113,9 +14145,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);
             }
@@ -16052,6 +16081,7 @@
         final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
 
         final PackageParser.Package oldPackage;
+        final PackageSetting ps;
         final String pkgName = pkg.packageName;
         final int[] allUsers;
         final int[] installedUsers;
@@ -16073,7 +16103,7 @@
                 return;
             }
 
-            final PackageSetting ps = mSettings.mPackages.get(pkgName);
+            ps = mSettings.mPackages.get(pkgName);
 
             // verify signatures are valid
             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
@@ -16159,10 +16189,10 @@
         res.removedInfo = new PackageRemovedInfo(this);
         res.removedInfo.uid = oldPackage.applicationInfo.uid;
         res.removedInfo.removedPackage = oldPackage.packageName;
+        res.removedInfo.installerPackageName = ps.installerPackageName;
         res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
         res.removedInfo.isUpdate = true;
         res.removedInfo.origUsers = installedUsers;
-        final PackageSetting ps = mSettings.getPackageLPr(pkgName);
         res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
         for (int i = 0; i < installedUsers.length; i++) {
             final int userId = installedUsers[i];
@@ -16180,6 +16210,9 @@
                 if (childRes != null) {
                     childRes.removedInfo.uid = childPkg.applicationInfo.uid;
                     childRes.removedInfo.removedPackage = childPkg.packageName;
+                    if (childPs != null) {
+                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
+                    }
                     childRes.removedInfo.isUpdate = true;
                     childRes.removedInfo.installReasons = res.removedInfo.installReasons;
                     childPackageUpdated = true;
@@ -16188,6 +16221,9 @@
             if (!childPackageUpdated) {
                 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
                 childRemovedRes.removedPackage = childPkg.packageName;
+                if (childPs != null) {
+                    childRemovedRes.installerPackageName = childPs.installerPackageName;
+                }
                 childRemovedRes.isUpdate = false;
                 childRemovedRes.dataRemoved = true;
                 synchronized (mPackages) {
@@ -16878,6 +16914,7 @@
                     if ((mPackages.containsKey(childPkg.packageName))) {
                         childRes.removedInfo = new PackageRemovedInfo(this);
                         childRes.removedInfo.removedPackage = childPkg.packageName;
+                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
                     }
                     if (res.addedChildPackages == null) {
                         res.addedChildPackages = new ArrayMap<>();
@@ -17826,6 +17863,7 @@
     static class PackageRemovedInfo {
         final PackageSender packageSender;
         String removedPackage;
+        String installerPackageName;
         int uid = -1;
         int removedAppId = -1;
         int[] origUsers;
@@ -17885,11 +17923,19 @@
             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
             extras.putBoolean(Intent.EXTRA_REPLACING, true);
             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                removedPackage, extras, 0, null, null, null);
+                removedPackage, extras, 0, null /*targetPackage*/, null, null);
             packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
-                removedPackage, extras, 0, null, null, null);
+                removedPackage, extras, 0, null /*targetPackage*/, null, null);
             packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                 null, null, 0, removedPackage, null, null);
+            if (installerPackageName != null) {
+                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+                        removedPackage, extras, 0 /*flags*/,
+                        installerPackageName, null, null);
+                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
+                        removedPackage, extras, 0 /*flags*/,
+                        installerPackageName, null, null);
+            }
         }
 
         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
@@ -17909,7 +17955,12 @@
             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
             if (removedPackage != null) {
                 packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
-                    removedPackage, extras, 0, null, null, broadcastUsers);
+                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
+                if (installerPackageName != null) {
+                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
+                            removedPackage, extras, 0 /*flags*/,
+                            installerPackageName, null, broadcastUsers);
+                }
                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
                     packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
                         removedPackage, extras,
@@ -17960,6 +18011,7 @@
             deletedPs = mSettings.mPackages.get(packageName);
             if (outInfo != null) {
                 outInfo.removedPackage = packageName;
+                outInfo.installerPackageName = ps.installerPackageName;
                 outInfo.isStaticSharedLib = deletedPkg != null
                         && deletedPkg.staticSharedLibName != null;
                 outInfo.populateUsers(deletedPs == null ? null
@@ -18448,6 +18500,7 @@
                     String childPackageName = ps.childPackageNames.get(i);
                     PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
                     childInfo.removedPackage = childPackageName;
+                    childInfo.installerPackageName = ps.installerPackageName;
                     outInfo.removedChildPackages.put(childPackageName, childInfo);
                     PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
                     if (childPs != null) {
@@ -18560,6 +18613,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) {
@@ -18572,6 +18626,7 @@
 
         if (outInfo != null) {
             outInfo.removedPackage = ps.name;
+            outInfo.installerPackageName = ps.installerPackageName;
             outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
             outInfo.removedAppId = ps.appId;
             outInfo.removedUsers = userIds;
@@ -19280,12 +19335,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);
             }
         }
     }
@@ -23487,14 +23548,13 @@
         public ResolveInfo resolveIntent(Intent intent, String resolvedType,
                 int flags, int userId) {
             return resolveIntentInternal(
-                    intent, resolvedType, flags, userId, true /*includeInstantApps*/);
+                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
         }
 
         @Override
         public ResolveInfo resolveService(Intent intent, String resolvedType,
                 int flags, int userId, int callingUid) {
-            return resolveServiceInternal(
-                    intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
+            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index f6872e4..284bb3f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,7 +26,7 @@
 public class PackageManagerServiceCompilerMapping {
     // Names for compilation reasons.
     static final String REASON_STRINGS[] = {
-            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "forced-dexopt"
+            "first-boot", "boot", "install", "bg-dexopt", "ab-ota"
     };
 
     // Static block to ensure the strings array is of the right length.
@@ -54,16 +54,6 @@
                     + "(reason " + REASON_STRINGS[reason] + ")");
         }
 
-        // Ensure that some reasons are not mapped to profile-guided filters.
-        switch (reason) {
-            case PackageManagerService.REASON_FORCED_DEXOPT:
-                if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
-                    throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
-                            + "but not allowed for " + REASON_STRINGS[reason]);
-                }
-                break;
-        }
-
         return sysPropValue;
     }
 
@@ -103,12 +93,12 @@
     }
 
     /**
-     * Return the compiler filter for "full" compilation.
+     * Return the default compiler filter for compilation.
      *
      * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
      * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
      */
-    public static String getFullCompilerFilter() {
+    public static String getDefaultCompilerFilter() {
         String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
         if (value == null || value.isEmpty()) {
             return "speed";
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/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 886fd9a..1d064de 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5493,9 +5493,10 @@
      */
     private boolean setKeyguardOccludedLw(boolean isOccluded, boolean force) {
         if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
-        boolean wasOccluded = mKeyguardOccluded;
-        boolean showing = mKeyguardDelegate.isShowing();
-        if (wasOccluded && !isOccluded && showing) {
+        final boolean wasOccluded = mKeyguardOccluded;
+        final boolean showing = mKeyguardDelegate.isShowing();
+        final boolean changed = wasOccluded != isOccluded || force;
+        if (!isOccluded && changed && showing) {
             mKeyguardOccluded = false;
             mKeyguardDelegate.setOccluded(false, true /* animate */);
             if (mStatusBar != null) {
@@ -5505,7 +5506,7 @@
                 }
             }
             return true;
-        } else if (!wasOccluded && isOccluded && showing) {
+        } else if (isOccluded && changed && showing) {
             mKeyguardOccluded = true;
             mKeyguardDelegate.setOccluded(true, false /* animate */);
             if (mStatusBar != null) {
@@ -5513,7 +5514,7 @@
                 mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
             }
             return true;
-        } else if (wasOccluded != isOccluded) {
+        } else if (changed) {
             mKeyguardOccluded = isOccluded;
             mKeyguardDelegate.setOccluded(isOccluded, false /* animate */);
             return false;
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 7634644..3c2dfa5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -95,6 +95,9 @@
     // change.
     private boolean mReparenting;
 
+    // True if we are current in the process of removing this app token from the display
+    private boolean mRemovingFromDisplay = false;
+
     // The input dispatching timeout for this application token in nanoseconds.
     long mInputDispatchingTimeoutNanos;
 
@@ -126,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;
@@ -175,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,
@@ -307,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
@@ -465,6 +483,12 @@
     }
 
     @Override
+    void removeImmediately() {
+        onRemovedFromDisplay();
+        super.removeImmediately();
+    }
+
+    @Override
     void removeIfPossible() {
         mIsExiting = false;
         removeAllWindowsIfPossible();
@@ -480,6 +504,11 @@
     }
 
     void onRemovedFromDisplay() {
+        if (mRemovingFromDisplay) {
+            return;
+        }
+        mRemovingFromDisplay = true;
+
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
 
         boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
@@ -512,12 +541,14 @@
             mService.mNoAnimationNotifyOnTransitionFinished.add(token);
         }
 
-        final TaskStack stack = getTask().mStack;
+        final TaskStack stack = getStack();
         if (delayed && !isEmpty()) {
             // set the token aside because it has an active animation to be finished
             if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
                     "removeAppToken make exiting: " + this);
-            stack.mExitingAppTokens.add(this);
+            if (stack != null) {
+                stack.mExitingAppTokens.add(this);
+            }
             mIsExiting = true;
         } else {
             // Make sure there is no animation running on this token, so any windows associated
@@ -540,6 +571,8 @@
         if (!delayed) {
             updateReportedVisibilityLocked();
         }
+
+        mRemovingFromDisplay = false;
     }
 
     void clearAnimatingFlags() {
@@ -725,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) {
@@ -1143,10 +1178,7 @@
                 hidden = false;
                 hiddenRequested = false;
             }
-            if (clientHidden != fromToken.clientHidden) {
-                clientHidden = fromToken.clientHidden;
-                sendAppVisibilityToClients();
-            }
+            setClientHidden(fromToken.mClientHidden);
             fromToken.mAppAnimator.transferCurrentAnimation(
                     mAppAnimator, tStartingWindow.mWinAnimator);
 
@@ -1511,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);
         }
@@ -1558,6 +1589,9 @@
         if (getController() != null) {
             pw.print(prefix); pw.print("controller="); pw.println(getController());
         }
+        if (mRemovingFromDisplay) {
+            pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index 3a6e328..4100446 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -200,8 +200,9 @@
                 // TODO: This is a work around for b/34395537 as the dim user should have cleaned-up
                 // it self when it was detached from the display. Need to investigate how the dim
                 // user is leaking...
-                Slog.wtfStack(TAG_WM, "Leaked dim user=" + user.toShortString()
-                        + " state=" + state);
+                //Slog.wtfStack(TAG_WM, "Leaked dim user=" + user.toShortString()
+                //        + " state=" + state);
+                Slog.w(TAG_WM, "Leaked dim user=" + user.toShortString() + " state=" + state);
                 removeDimLayerUser(user);
                 continue;
             }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1823610..b7a268c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -666,8 +666,9 @@
                     }
                 }
             }
-            if ((!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) ||
-                    winAnimator.isDummyAnimation()) {
+            final TaskStack stack = w.getStack();
+            if ((!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening())
+                    || (stack != null && stack.isAnimatingBounds())) {
                 // Updates the shown frame before we set up the surface. This is needed
                 // because the resizing could change the top-left position (in addition to
                 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
@@ -675,7 +676,10 @@
                 //
                 // If an animation is being started, we can't call this method because the
                 // animation hasn't processed its initial transformation yet, but in general
-                // we do want to update the position if the window is animating.
+                // we do want to update the position if the window is animating. We make an exception
+                // for the bounds animating state, where an application may have been waiting
+                // for an exit animation to start, but instead enters PiP. We need to ensure
+                // we always recompute the top-left in this case.
                 winAnimator.computeShownFrameLocked();
             }
             winAnimator.setSurfaceBoundariesLocked(mTmpRecoveringMemory /* recoveringMemory */);
@@ -2245,7 +2249,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 252b4d4..05ec479 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) {
@@ -4313,7 +4318,10 @@
                     if (mWaitingForConfig) {
                         mWaitingForConfig = false;
                         mLastFinishedFreezeSource = "config-unchanged";
-                        mRoot.getDisplayContent(displayId).setLayoutNeeded();
+                        final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                        if (dc != null) {
+                            dc.setLayoutNeeded();
+                        }
                         mWindowPlacerLocked.performSurfacePlacement();
                     }
                 }
@@ -5035,6 +5043,7 @@
                     if (callback != null) {
                         callback.run();
                     }
+                    break;
                 }
                 case NEW_ANIMATOR_SCALE: {
                     float scale = getCurrentAnimatorScale();
@@ -5087,6 +5096,7 @@
                         }
                     }
                 }
+                break;
                 case UPDATE_DOCKED_STACK_DIVIDER: {
                     synchronized (mWindowMap) {
                         final DisplayContent displayContent = getDefaultDisplayContentLocked();
@@ -5104,6 +5114,7 @@
                         mWindowReplacementTimeouts.clear();
                     }
                 }
+                break;
                 case NOTIFY_APP_TRANSITION_STARTING: {
                     mAmInternal.notifyAppTransitionStarting((SparseIntArray) msg.obj);
                 }
@@ -5606,22 +5617,19 @@
         WindowState win = mWindowMap.get(client);
         if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
         if (win == null) {
-            RuntimeException ex = new IllegalArgumentException(
-                    "Requested window " + client + " does not exist");
             if (throwOnError) {
-                throw ex;
+                throw new IllegalArgumentException(
+                        "Requested window " + client + " does not exist");
             }
-            Slog.w(TAG_WM, "Failed looking up window", ex);
+            Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
             return null;
         }
         if (session != null && win.mSession != session) {
-            RuntimeException ex = new IllegalArgumentException(
-                    "Requested window " + client + " is in session " +
-                    win.mSession + ", not " + session);
             if (throwOnError) {
-                throw ex;
+                throw new IllegalArgumentException("Requested window " + client + " is in session "
+                        + win.mSession + ", not " + session);
             }
-            Slog.w(TAG_WM, "Failed looking up window", ex);
+            Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
             return null;
         }
 
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/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
index 97fa9d5..c7b8f02 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.devicepolicy;
 
+import android.Manifest.permission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.admin.DevicePolicyManager;
@@ -115,10 +116,12 @@
                 return null;
             }
             final ServiceInfo si = list.get(0).serviceInfo;
-            if (si.exported) {
-                Log.e(TAG, "DeviceAdminService must not be exported: '"
+
+            if (!permission.BIND_DEVICE_ADMIN.equals(si.permission)) {
+                Log.e(TAG, "DeviceAdminService "
                         + si.getComponentName().flattenToShortString()
-                        + "' will be ignored.");
+                        + " must be protected with " + permission.BIND_DEVICE_ADMIN
+                        + ".");
                 return null;
             }
             return si;
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 57ee928..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,10 +272,9 @@
     }
 
     @Test
-    @UiThreadTest
     public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null).getNotification(), new int[1], 0);
+                generateNotificationRecord(null).getNotification(), 0);
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
@@ -288,10 +282,9 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null).getNotification(), new int[1], 0);
+                generateNotificationRecord(null).getNotification(), 0);
         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -300,13 +293,12 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null).getNotification(), new int[1], 0);
+                generateNotificationRecord(null).getNotification(), 0);
         waitForIdle();
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null).getNotification(), new int[1], 0);
+                generateNotificationRecord(null).getNotification(), 0);
         mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -315,11 +307,10 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelNotificationsFromListener(null, null);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -328,11 +319,10 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -341,12 +331,11 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -355,12 +344,11 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -369,11 +357,10 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications(null, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -382,11 +369,10 @@
     }
 
     @Test
-    @UiThreadTest
     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
-                sbn.getId(), sbn.getNotification(), new int[1], UserHandle.USER_ALL);
+                sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
         // Null pkg is how we signal a user switch.
         mBinderService.cancelAllNotifications(null, sbn.getUserId());
         waitForIdle();
@@ -396,12 +382,11 @@
     }
 
     @Test
-    @UiThreadTest
     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
-                sbn.getId(), sbn.getNotification(), new int[1], sbn.getUserId());
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
@@ -411,7 +396,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testTvExtenderChannelOverride_onTv() throws Exception {
         mNotificationManagerService.setIsTelevision(true);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
@@ -421,13 +405,12 @@
 
         Notification.TvExtender tv = new Notification.TvExtender().setChannel("foo");
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null, tv).getNotification(), new int[1], 0);
+                generateNotificationRecord(null, tv).getNotification(), 0);
         verify(mRankingHelper, times(1)).getNotificationChannel(
                 anyString(), anyInt(), eq("foo"), anyBoolean());
     }
 
     @Test
-    @UiThreadTest
     public void testTvExtenderChannelOverride_notOnTv() throws Exception {
         mNotificationManagerService.setIsTelevision(false);
         mNotificationManagerService.setRankingHelper(mRankingHelper);
@@ -437,13 +420,12 @@
 
         Notification.TvExtender tv = new Notification.TvExtender().setChannel("foo");
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
-                generateNotificationRecord(null, tv).getNotification(), new int[1], 0);
+                generateNotificationRecord(null, tv).getNotification(), 0);
         verify(mRankingHelper, times(1)).getNotificationChannel(
                 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), anyBoolean());
     }
 
     @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..ce899e3 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,8 @@
 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 android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.fail;
@@ -47,6 +49,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.UserHandle;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -504,12 +507,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 {
@@ -538,6 +552,56 @@
     }
 
     @Test
+    public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
+        mHelper.setImportance(PKG, UID, IMPORTANCE_UNSPECIFIED);
+        assertTrue(mHelper.canShowBadge(PKG, UID));
+        assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
+        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+                mHelper.getPackageVisibility(PKG, UID));
+
+        NotificationChannel defaultChannel = mHelper.getNotificationChannel(
+                PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false);
+
+        defaultChannel.setShowBadge(false);
+        defaultChannel.setImportance(IMPORTANCE_NONE);
+        defaultChannel.setBypassDnd(true);
+        defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+
+        mHelper.updateNotificationChannel(PKG, UID, defaultChannel);
+
+        // ensure app level fields are changed
+        assertFalse(mHelper.canShowBadge(PKG, UID));
+        assertEquals(Notification.PRIORITY_MAX, mHelper.getPackagePriority(PKG, UID));
+        assertEquals(Notification.VISIBILITY_SECRET, mHelper.getPackageVisibility(PKG, UID));
+        assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG, UID));
+    }
+
+    @Test
+    public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
+        final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+
+        mHelper.createNotificationChannel(PKG, UID, channel, false);
+        assertTrue(mHelper.canShowBadge(PKG, UID));
+        assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
+        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+                mHelper.getPackageVisibility(PKG, UID));
+
+        channel.setShowBadge(false);
+        channel.setImportance(IMPORTANCE_NONE);
+        channel.setBypassDnd(true);
+        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+
+        mHelper.updateNotificationChannel(PKG, UID, channel);
+
+        // ensure app level fields are not changed
+        assertTrue(mHelper.canShowBadge(PKG, UID));
+        assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
+        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
+                mHelper.getPackageVisibility(PKG, UID));
+        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG, UID));
+    }
+
+    @Test
     public void testGetNotificationChannel_ReturnsNullForUnknownChannel() throws Exception {
         assertEquals(null, mHelper.getNotificationChannel(PKG, UID, "garbage", false));
     }
diff --git a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
index 9343449..ca77528 100644
--- a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
@@ -20,40 +20,27 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.IActivityManager;
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.pm.UserInfo;
-import android.database.sqlite.SQLiteDatabase;
 import android.os.FileUtils;
-import android.os.Handler;
 import android.os.IProgressListener;
-import android.os.RemoteException;
 import android.os.UserManager;
-import android.os.storage.IStorageManager;
 import android.security.KeyStore;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
 import android.test.AndroidTestCase;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsService.SynchronizedStrongAuthTracker;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.MockGateKeeperService.AuthToken;
-import com.android.server.MockGateKeeperService.VerifyHandle;
 
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.io.File;
-import java.util.Arrays;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 
 public class BaseLockSettingsServiceTests extends AndroidTestCase {
@@ -110,10 +97,9 @@
         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
         mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
         installChildProfile(MANAGED_PROFILE_USER_ID);
-        installQuietModeChildProfile(TURNED_OFF_PROFILE_USER_ID);
+        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
         when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
-        when(mUserManager.isUserRunning(eq(MANAGED_PROFILE_USER_ID))).thenReturn(true);
 
         when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
                 new Answer<Boolean>() {
@@ -139,12 +125,16 @@
         mPrimaryUserProfiles.add(userInfo);
         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
         return userInfo;
     }
 
-    private UserInfo installQuietModeChildProfile(int profileId) {
+    private UserInfo installAndTurnOffChildProfile(int profileId) {
         final UserInfo userInfo = installChildProfile(profileId);
         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
         return userInfo;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
index cfc3962..25cc426 100644
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
@@ -98,14 +98,14 @@
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final long turnedOffprofileSid =
+        final long turnedOffProfileSid =
                 mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
         assertTrue(primarySid != 0);
         assertTrue(profileSid != 0);
         assertTrue(profileSid != primarySid);
-        assertTrue(turnedOffprofileSid != 0);
-        assertTrue(turnedOffprofileSid != primarySid);
-        assertTrue(turnedOffprofileSid != profileSid);
+        assertTrue(turnedOffProfileSid != 0);
+        assertTrue(turnedOffProfileSid != primarySid);
+        assertTrue(turnedOffProfileSid != profileSid);
 
         // clear auth token and wait for verify challenge from primary user to re-generate it.
         mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
@@ -119,7 +119,7 @@
         assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
 
-        // Verify that profile which arent't running (e.g. turn off work) don't get unlocked
+        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
         assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
 
         /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 3671e4b..ad8303a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -1500,7 +1500,7 @@
         final FutureAnswer<String> futureAnswer = new FutureAnswer<String>(2);
         doAnswer(futureAnswer).when(mNotifManager).enqueueNotificationWithTag(
                 anyString(), anyString(), anyString() /* capture here (index 2)*/,
-                anyInt(), isA(Notification.class), isA(int[].class), anyInt());
+                anyInt(), isA(Notification.class), anyInt());
         return futureAnswer;
     }
 
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/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
index f971971..9014539 100644
--- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java
@@ -19,6 +19,7 @@
 import static android.util.DebugUtils.valueToString;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -36,8 +37,10 @@
 import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
+import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -91,11 +94,14 @@
 
     private static final String EXTRA_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer";
 
-    private static final int WAIT_FOR_INSTALL_TIMEOUT_MS = 2000; // 2 sec
+    private static final long BATTERY_OFF_TIMEOUT_MS = 2000; // 2 sec
+    private static final long BATTERY_OFF_CHECK_INTERVAL_MS = 200; // 0.2 sec
 
-    private static final int NETWORK_CHECK_TIMEOUT_MS = 6000; // 6 sec
+    private static final long WAIT_FOR_INSTALL_TIMEOUT_MS = 2000; // 2 sec
 
-    private static final int SCREEN_ON_DELAY_MS = 500; // 0.5 sec
+    private static final long NETWORK_CHECK_TIMEOUT_MS = 6000; // 6 sec
+
+    private static final long SCREEN_ON_DELAY_MS = 500; // 0.5 sec
 
     private static final String NETWORK_STATUS_SEPARATOR = "\\|";
 
@@ -104,6 +110,8 @@
     private static Context mContext;
     private static UiDevice mUiDevice;
     private static int mTestPkgUid;
+    private static BatteryManager mBatteryManager;
+    private static ConnectivityManager mConnectivityManager;
 
     @BeforeClass
     public static void setUpOnce() throws Exception {
@@ -114,6 +122,10 @@
         mContext.getPackageManager().setApplicationEnabledSetting(TEST_PKG,
                 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
         mTestPkgUid = mContext.getPackageManager().getPackageUid(TEST_PKG, 0);
+
+        mBatteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
     }
 
     @AfterClass
@@ -130,6 +142,9 @@
 
     @Test
     public void testStartActivity_batterySaver() throws Exception {
+        if (!isNetworkAvailable()) {
+            fail("Device doesn't have network connectivity");
+        }
         setBatterySaverMode(true);
         try {
             testConnOnActivityStart("testStartActivity_batterySaver");
@@ -140,6 +155,9 @@
 
     @Test
     public void testStartActivity_dataSaver() throws Exception {
+        if (!isNetworkAvailable()) {
+            fail("Device doesn't have network connectivity");
+        }
         setDataSaverMode(true);
         try {
             testConnOnActivityStart("testStartActivity_dataSaver");
@@ -150,6 +168,9 @@
 
     @Test
     public void testStartActivity_dozeMode() throws Exception {
+        if (!isNetworkAvailable()) {
+            fail("Device doesn't have network connectivity");
+        }
         setDozeMode(true);
         try {
             testConnOnActivityStart("testStartActivity_dozeMode");
@@ -160,6 +181,9 @@
 
     @Test
     public void testStartActivity_appStandby() throws Exception {
+        if (!isNetworkAvailable()) {
+            fail("Device doesn't have network connectivity");
+        }
         try{
             turnBatteryOff();
             setAppIdle(true);
@@ -174,6 +198,9 @@
 
     @Test
     public void testStartActivity_backgroundRestrict() throws Exception {
+        if (!isNetworkAvailable()) {
+            fail("Device doesn't have network connectivity");
+        }
         updateRestrictBackgroundBlacklist(true);
         try {
             testConnOnActivityStart("testStartActivity_backgroundRestrict");
@@ -271,6 +298,15 @@
 
     private void turnBatteryOff() throws Exception {
         executeCommand("cmd battery unplug");
+        assertBatteryOff();
+    }
+
+    private void assertBatteryOff() throws Exception {
+        final long endTime = SystemClock.uptimeMillis() + BATTERY_OFF_TIMEOUT_MS;
+        while (mBatteryManager.isCharging() && SystemClock.uptimeMillis() < endTime) {
+            SystemClock.sleep(BATTERY_OFF_CHECK_INTERVAL_MS);
+        }
+        assertFalse("Power should be disconnected", mBatteryManager.isCharging());
     }
 
     private void turnBatteryOn() throws Exception {
@@ -309,6 +345,11 @@
                 + maxTries + " attempts. Last result: '" + result + "'");
     }
 
+    private boolean isNetworkAvailable() throws Exception {
+        final NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
+        return networkInfo != null && networkInfo.isConnected();
+    }
+
     private void startActivityAndCheckNetworkAccess() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         final Intent launchIntent = new Intent().setComponent(
diff --git a/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
index b5a6178..3fd1d55 100644
--- a/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java
@@ -120,15 +120,7 @@
     }
 
     public void testGetUserSize() throws Exception {
-        int[] appIds = null;
-
-        final PackageManager pm = getContext().getPackageManager();
-        for (ApplicationInfo app : pm.getInstalledApplications(0)) {
-            final int appId = UserHandle.getAppId(app.uid);
-            if (!ArrayUtils.contains(appIds, appId)) {
-                appIds = ArrayUtils.appendInt(appIds, appId);
-            }
-        }
+        final int[] appIds = getAppIds(UserHandle.USER_SYSTEM);
 
         final PackageStats stats = new PackageStats("android");
         final PackageStats quotaStats = new PackageStats("android");
@@ -147,13 +139,15 @@
     }
 
     public void testGetExternalSize() throws Exception {
+        final int[] appIds = getAppIds(UserHandle.USER_SYSTEM);
+
         mManual.start();
-        final long[] stats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM, 0);
+        final long[] stats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM, 0, appIds);
         mManual.stop();
 
         mQuota.start();
         final long[] quotaStats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM,
-                Installer.FLAG_USE_QUOTA);
+                Installer.FLAG_USE_QUOTA, appIds);
         mQuota.stop();
 
         for (int i = 0; i < stats.length; i++) {
@@ -161,6 +155,18 @@
         }
     }
 
+    private int[] getAppIds(int userId) {
+        int[] appIds = null;
+        for (ApplicationInfo app : getContext().getPackageManager().getInstalledApplicationsAsUser(
+                PackageManager.MATCH_UNINSTALLED_PACKAGES, userId)) {
+            final int appId = UserHandle.getAppId(app.uid);
+            if (!ArrayUtils.contains(appIds, appId)) {
+                appIds = ArrayUtils.appendInt(appIds, appId);
+            }
+        }
+        return appIds;
+    }
+
     private static void checkEquals(String msg, PackageStats a, PackageStats b) {
         checkEquals(msg + " codeSize", a.codeSize, b.codeSize);
         checkEquals(msg + " dataSize", a.dataSize, b.dataSize);
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
index f68e06a..a599427 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -19,7 +19,6 @@
 import android.app.ActivityManager;
 import android.content.res.Configuration;
 import android.graphics.Rect;
-import android.os.Debug;
 import android.view.DisplayInfo;
 import org.junit.Test;
 
@@ -53,11 +52,11 @@
      */
     @Test
     public void testRootConfigurationBounds() throws Exception {
-        final DisplayInfo info = sDisplayContent.getDisplayInfo();
+        final DisplayInfo info = mDisplayContent.getDisplayInfo();
         info.appWidth = 1024;
         info.appHeight = 768;
 
-        final Configuration config = sWm.computeNewConfiguration(sDisplayContent.getDisplayId());
+        final Configuration config = sWm.computeNewConfiguration(mDisplayContent.getDisplayId());
         // The bounds should always be positioned in the top left.
         assertEquals(config.appBounds.left, 0);
         assertEquals(config.appBounds.top, 0);
@@ -116,8 +115,8 @@
      */
     @Test
     public void testFullScreenFreeFormBounds() throws Exception {
-        final Rect fullScreenBounds = new Rect(0, 0, sDisplayInfo.logicalWidth,
-                sDisplayInfo.logicalHeight);
+        final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth,
+                mDisplayInfo.logicalHeight);
         testStackBoundsConfiguration(null /*stackId*/, mParentBounds, fullScreenBounds,
                 mParentBounds);
     }
@@ -126,16 +125,16 @@
     private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
         final StackWindowController stackController = stackId != null ?
-                createStackControllerOnStackOnDisplay(stackId, sDisplayContent)
-                : createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnStackOnDisplay(stackId, mDisplayContent)
+                : createStackControllerOnDisplay(mDisplayContent);
 
-        final Configuration parentConfig = sDisplayContent.getConfiguration();
+        final Configuration parentConfig = mDisplayContent.getConfiguration();
         parentConfig.setAppBounds(parentBounds);
 
         final Configuration config = new Configuration();
         stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
                 new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
-                false /*overrideHeight*/, sDisplayInfo.logicalDensityDpi, config, parentConfig);
+                false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig);
         // Assert that both expected and actual are null or are equal to each other
 
         assertTrue((expectedConfigBounds == null && config.appBounds == null)
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index d206407..dcbedb6 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -48,14 +48,14 @@
                 createAppWindowController();
 
         // Assert token was added to display.
-        assertNotNull(sDisplayContent.getWindowToken(controller.mToken.asBinder()));
+        assertNotNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
         // Assert that the container was created and linked.
         assertNotNull(controller.mContainer);
 
-        controller.removeContainer(sDisplayContent.getDisplayId());
+        controller.removeContainer(mDisplayContent.getDisplayId());
 
         // Assert token was remove from display.
-        assertNull(sDisplayContent.getWindowToken(controller.mToken.asBinder()));
+        assertNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
         // Assert that the container was removed.
         assertNull(controller.mContainer);
     }
@@ -68,11 +68,11 @@
         // Assert orientation is unspecified to start.
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
 
-        controller.setOrientation(SCREEN_ORIENTATION_LANDSCAPE, sDisplayContent.getDisplayId(),
+        controller.setOrientation(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getDisplayId(),
                 EMPTY /* displayConfig */, false /* freezeScreenIfNeeded */);
         assertEquals(SCREEN_ORIENTATION_LANDSCAPE, controller.getOrientation());
 
-        controller.removeContainer(sDisplayContent.getDisplayId());
+        controller.removeContainer(mDisplayContent.getDisplayId());
         // Assert orientation is unspecified to after container is removed.
         assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
 
@@ -99,7 +99,7 @@
         controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
         waitUntilHandlersIdle();
-        final AppWindowToken atoken = controller.getAppWindowToken();
+        final AppWindowToken atoken = controller.getAppWindowToken(mDisplayContent);
         assertHasStartingWindow(atoken);
         controller.removeStartingWindow();
         waitUntilHandlersIdle();
@@ -119,8 +119,8 @@
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
                 true, true, false, true);
         waitUntilHandlersIdle();
-        assertNoStartingWindow(controller1.getAppWindowToken());
-        assertHasStartingWindow(controller2.getAppWindowToken());
+        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
+        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
     }
 
     @Test
@@ -129,7 +129,7 @@
                 createAppWindowController();
         final WindowTestUtils.TestAppWindowContainerController controller2 =
                 createAppWindowController();
-        sPolicy.setRunnableWhenAddingSplashScreen(() -> {
+        ((TestWindowManagerPolicy) sWm.mPolicy).setRunnableWhenAddingSplashScreen(() -> {
 
             // Surprise, ...! Transfer window in the middle of the creation flow.
             controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
@@ -139,14 +139,14 @@
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true);
         waitUntilHandlersIdle();
-        assertNoStartingWindow(controller1.getAppWindowToken());
-        assertHasStartingWindow(controller2.getAppWindowToken());
+        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
+        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
     }
 
     @Test
     public void testReparent() throws Exception {
         final StackWindowController stackController =
-            createStackControllerOnDisplay(sDisplayContent);
+            createStackControllerOnDisplay(mDisplayContent);
         final WindowTestUtils.TestTaskWindowContainerController taskController1 =
                 new WindowTestUtils.TestTaskWindowContainerController(stackController);
         final WindowTestUtils.TestAppWindowContainerController appWindowController1 =
@@ -183,7 +183,8 @@
     }
 
     private WindowTestUtils.TestAppWindowContainerController createAppWindowController() {
-        return createAppWindowController(new WindowTestUtils.TestTaskWindowContainerController());
+        return createAppWindowController(
+                new WindowTestUtils.TestTaskWindowContainerController(this));
     }
 
     private WindowTestUtils.TestAppWindowContainerController createAppWindowController(
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 7a7ca3f..876008b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import org.junit.Test;
-import org.junit.Ignore;
 import org.junit.runner.RunWith;
 
 import android.platform.test.annotations.Presubmit;
@@ -52,7 +51,7 @@
     @Test
     public void testAddWindow_Order() throws Exception {
         final WindowTestUtils.TestAppWindowToken token =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
 
         assertEquals(0, token.getWindowsCount());
 
@@ -80,7 +79,7 @@
     @Test
     public void testFindMainWindow() throws Exception {
         final WindowTestUtils.TestAppWindowToken token =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
 
         assertNull(token.findMainWindow());
 
@@ -102,10 +101,10 @@
         sWm.mDisplayEnabled = true;
 
         // Create an app window with token on a display.
-        final TaskStack stack = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
         final WindowTestUtils.TestAppWindowToken appWindowToken =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task.addChild(appWindowToken, 0);
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
                 TYPE_BASE_APPLICATION);
@@ -115,17 +114,17 @@
 
         // Set initial orientation and update.
         appWindowToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-        sWm.updateOrientationFromAppTokens(sDisplayContent.getOverrideConfiguration(), null,
-                sDisplayContent.getDisplayId());
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, sDisplayContent.getLastOrientation());
+        sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+                mDisplayContent.getDisplayId());
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
         appWindow.resizeReported = false;
 
         // Update the orientation to perform 180 degree rotation and check that resize was reported.
         appWindowToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
-        sWm.updateOrientationFromAppTokens(sDisplayContent.getOverrideConfiguration(), null,
-                sDisplayContent.getDisplayId());
+        sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+                mDisplayContent.getDisplayId());
         sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
-        assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, sDisplayContent.getLastOrientation());
+        assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
         assertTrue(appWindow.resizeReported);
         appWindow.removeImmediately();
     }
@@ -170,7 +169,7 @@
     @Test
     public void testGetOrientation() throws Exception {
         final WindowTestUtils.TestAppWindowToken token =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         token.setFillsParent(false);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 837ce56..e8dc69f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -52,74 +52,74 @@
     @Test
     public void testForAllWindows() throws Exception {
         final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
-                sDisplayContent, "exiting app");
+                mDisplayContent, "exiting app");
         final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
         exitingAppToken.mIsExiting = true;
         exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
 
         assertForAllWindowsOrder(Arrays.asList(
-                sWallpaperWindow,
+                mWallpaperWindow,
                 exitingAppWindow,
-                sChildAppWindowBelow,
-                sAppWindow,
-                sChildAppWindowAbove,
-                sDockedDividerWindow,
-                sStatusBarWindow,
-                sNavBarWindow,
-                sImeWindow,
-                sImeDialogWindow));
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow,
+                mImeWindow,
+                mImeDialogWindow));
     }
 
     @Test
     public void testForAllWindows_WithAppImeTarget() throws Exception {
         final WindowState imeAppTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
 
         sWm.mInputMethodTarget = imeAppTarget;
 
         assertForAllWindowsOrder(Arrays.asList(
-                sWallpaperWindow,
-                sChildAppWindowBelow,
-                sAppWindow,
-                sChildAppWindowAbove,
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
                 imeAppTarget,
-                sImeWindow,
-                sImeDialogWindow,
-                sDockedDividerWindow,
-                sStatusBarWindow,
-                sNavBarWindow));
+                mImeWindow,
+                mImeDialogWindow,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow));
     }
 
     @Test
     public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
-        sWm.mInputMethodTarget = sChildAppWindowAbove;
+        sWm.mInputMethodTarget = mChildAppWindowAbove;
 
         assertForAllWindowsOrder(Arrays.asList(
-                sWallpaperWindow,
-                sChildAppWindowBelow,
-                sAppWindow,
-                sChildAppWindowAbove,
-                sImeWindow,
-                sImeDialogWindow,
-                sDockedDividerWindow,
-                sStatusBarWindow,
-                sNavBarWindow));
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mImeWindow,
+                mImeDialogWindow,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow));
     }
 
     @Test
     public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
-        sWm.mInputMethodTarget = sStatusBarWindow;
+        sWm.mInputMethodTarget = mStatusBarWindow;
 
         assertForAllWindowsOrder(Arrays.asList(
-                sWallpaperWindow,
-                sChildAppWindowBelow,
-                sAppWindow,
-                sChildAppWindowAbove,
-                sDockedDividerWindow,
-                sStatusBarWindow,
-                sImeWindow,
-                sImeDialogWindow,
-                sNavBarWindow));
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mImeWindow,
+                mImeDialogWindow,
+                mNavBarWindow));
     }
 
     @Test
@@ -127,28 +127,28 @@
         // This window is set-up to be z-ordered between some windows that go in the same token like
         // the nav bar and status bar.
         final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
-                sDisplayContent, "voiceInteractionWindow");
+                mDisplayContent, "voiceInteractionWindow");
 
         assertForAllWindowsOrder(Arrays.asList(
-                sWallpaperWindow,
-                sChildAppWindowBelow,
-                sAppWindow,
-                sChildAppWindowAbove,
-                sDockedDividerWindow,
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
                 voiceInteractionWindow,
-                sStatusBarWindow,
-                sNavBarWindow,
-                sImeWindow,
-                sImeDialogWindow));
+                mStatusBarWindow,
+                mNavBarWindow,
+                mImeWindow,
+                mImeDialogWindow));
     }
 
     @Test
     public void testComputeImeTarget() throws Exception {
         // Verify that an app window can be an ime target.
-        final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin");
+        final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
         appWin.setHasSurface(true);
         assertTrue(appWin.canBeImeTarget());
-        WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(appWin, imeTarget);
 
         // Verify that an child window can be an ime target.
@@ -156,7 +156,7 @@
                 TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
         childWin.setHasSurface(true);
         assertTrue(childWin.canBeImeTarget());
-        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(childWin, imeTarget);
     }
 
@@ -182,12 +182,12 @@
         assertEquals(dc, token.getDisplayContent());
 
         // Move stack to first display.
-        sDisplayContent.moveStackToDisplay(stack, true /* onTop */);
-        assertEquals(sDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
-        assertEquals(sDisplayContent, stack.getParent().getParent());
-        assertEquals(sDisplayContent, stack.getDisplayContent());
-        assertEquals(sDisplayContent, task.getDisplayContent());
-        assertEquals(sDisplayContent, token.getDisplayContent());
+        mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
+        assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
+        assertEquals(mDisplayContent, stack.getParent().getParent());
+        assertEquals(mDisplayContent, stack.getDisplayContent());
+        assertEquals(mDisplayContent, task.getDisplayContent());
+        assertEquals(mDisplayContent, token.getDisplayContent());
     }
 
     /**
@@ -195,8 +195,8 @@
      */
     @Test
     public void testDisplayOverrideConfigUpdate() throws Exception {
-        final int displayId = sDisplayContent.getDisplayId();
-        final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
+        final int displayId = mDisplayContent.getDisplayId();
+        final Configuration currentOverrideConfig = mDisplayContent.getOverrideConfiguration();
 
         // Create new, slightly changed override configuration and apply it to the display.
         final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
@@ -206,7 +206,7 @@
         sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
 
         // Check that override config is applied.
-        assertEquals(newOverrideConfig, sDisplayContent.getOverrideConfiguration());
+        assertEquals(newOverrideConfig, mDisplayContent.getOverrideConfiguration());
     }
 
     /**
@@ -214,7 +214,7 @@
      */
     @Test
     public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
-        final Configuration currentConfig = sDisplayContent.getConfiguration();
+        final Configuration currentConfig = mDisplayContent.getConfiguration();
 
         // Create new, slightly changed override configuration and apply it to the display.
         final Configuration newOverrideConfig = new Configuration(currentConfig);
@@ -239,7 +239,7 @@
     public void testFocusedWindowMultipleDisplays() throws Exception {
         // Create a focusable window and check that focus is calcualted correctly
         final WindowState window1 =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "window1");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
         assertEquals(window1, sWm.mRoot.computeFocusedWindow());
 
         // Check that a new display doesn't affect focus
@@ -264,30 +264,30 @@
         final int baseHeight = 2560;
         final int baseDensity = 300;
 
-        sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
 
         final int maxWidth = 300;
         final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
         final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
 
-        sDisplayContent.setMaxUiWidth(maxWidth);
-        verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
+        mDisplayContent.setMaxUiWidth(maxWidth);
+        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
 
         // Assert setting values again does not change;
-        sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
-        verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);
+        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
 
         final int smallerWidth = 200;
         final int smallerHeight = 400;
         final int smallerDensity = 100;
 
         // Specify smaller dimension, verify that it is honored
-        sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
-        verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+        mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
+        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
 
         // Verify that setting the max width to a greater value than the base width has no effect
-        sDisplayContent.setMaxUiWidth(maxWidth);
-        verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+        mDisplayContent.setMaxUiWidth(maxWidth);
+        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
     }
 
     /**
@@ -295,17 +295,17 @@
      */
     @Test
     public void testPinnedStackLocation() {
-        createStackControllerOnStackOnDisplay(PINNED_STACK_ID, sDisplayContent);
-        final int initialStackCount = sDisplayContent.getStackCount();
+        createStackControllerOnStackOnDisplay(PINNED_STACK_ID, mDisplayContent);
+        final int initialStackCount = mDisplayContent.getStackCount();
         // Ensure that the pinned stack was placed at the end
-        assertEquals(initialStackCount - 1, sDisplayContent.getStaskPosById(PINNED_STACK_ID));
+        assertEquals(initialStackCount - 1, mDisplayContent.getStaskPosById(PINNED_STACK_ID));
         // By default, this should try to create a new stack on top
-        createTaskStackOnDisplay(sDisplayContent);
-        final int afterStackCount = sDisplayContent.getStackCount();
+        createTaskStackOnDisplay(mDisplayContent);
+        final int afterStackCount = mDisplayContent.getStackCount();
         // Make sure the stack count has increased
         assertEquals(initialStackCount + 1, afterStackCount);
         // Ensure that the pinned stack is still on top
-        assertEquals(afterStackCount - 1, sDisplayContent.getStaskPosById(PINNED_STACK_ID));
+        assertEquals(afterStackCount - 1, mDisplayContent.getStaskPosById(PINNED_STACK_ID));
     }
 
     private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
@@ -319,7 +319,7 @@
         final LinkedList<WindowState> actualWindows = new LinkedList();
 
         // Test forward traversal.
-        sDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
+        mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
         assertEquals(expectedWindows.size(), actualWindows.size());
         for (WindowState w : expectedWindows) {
             assertEquals(w, actualWindows.pollFirst());
@@ -327,7 +327,7 @@
         assertTrue(actualWindows.isEmpty());
 
         // Test backward traversal.
-        sDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
+        mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
         assertEquals(expectedWindows.size(), actualWindows.size());
         for (WindowState w : expectedWindows) {
             assertEquals(w, actualWindows.pollLast());
diff --git a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
index 61f7f57..d9b99ee 100644
--- a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
@@ -42,7 +42,7 @@
     @Test
     public void testRemoveContainer() throws Exception {
         final StackWindowController stackController =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final WindowTestUtils.TestTaskWindowContainerController taskController =
                 new WindowTestUtils.TestTaskWindowContainerController(stackController);
 
@@ -62,7 +62,7 @@
     @Test
     public void testRemoveContainer_deferRemoval() throws Exception {
         final StackWindowController stackController =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final WindowTestUtils.TestTaskWindowContainerController taskController =
                 new WindowTestUtils.TestTaskWindowContainerController(stackController);
 
@@ -89,7 +89,7 @@
     public void testReparent() throws Exception {
         // Create first stack on primary display.
         final StackWindowController stack1Controller =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final TaskStack stack1 = stack1Controller.mContainer;
         final WindowTestUtils.TestTaskWindowContainerController taskController =
                 new WindowTestUtils.TestTaskWindowContainerController(stack1Controller);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
index e6975e7..887def7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -22,16 +22,12 @@
 import org.junit.runner.RunWith;
 
 import android.graphics.Rect;
-import android.os.Binder;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.Display;
 
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
 import static com.android.server.wm.WindowManagerService.dipToPixel;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
@@ -61,7 +57,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        final Display display = sDisplayContent.getDisplay();
+        final Display display = mDisplayContent.getDisplay();
         final DisplayMetrics dm = new DisplayMetrics();
         display.getMetrics(dm);
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index c61076d..a23a6b22 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -16,28 +16,13 @@
 
 package com.android.server.wm;
 
-import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
-import static android.graphics.GraphicBuffer.USAGE_SW_READ_NEVER;
-import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
-import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_NEVER;
-import static android.graphics.GraphicBuffer.create;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 
-import android.app.ActivityManager.TaskSnapshot;
-import android.content.res.Configuration;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.GraphicBuffer;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Debug;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 2752340..2b4d9fb 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -75,12 +75,12 @@
     @Test
     public void testGetSnapshotMode() throws Exception {
         final WindowState disabledWindow = createWindow(null,
-                FIRST_APPLICATION_WINDOW, sDisplayContent, "disabledWindow");
+                FIRST_APPLICATION_WINDOW, mDisplayContent, "disabledWindow");
         disabledWindow.mAppToken.setDisablePreviewSnapshots(true);
         assertEquals(SNAPSHOT_MODE_APP_THEME,
                 sWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
         final WindowState normalWindow = createWindow(null,
-                FIRST_APPLICATION_WINDOW, sDisplayContent, "normalWindow");
+                FIRST_APPLICATION_WINDOW, mDisplayContent, "normalWindow");
         assertEquals(SNAPSHOT_MODE_REAL,
                 sWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
index 82ea2313..5feda41 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -51,12 +51,13 @@
     public void setUp() throws Exception {
         super.setUp();
         mPinnedStack = new StackWindowController(PINNED_STACK_ID, null,
-                sDisplayContent.getDisplayId(), true /* onTop */, new Rect(), sWm).mContainer;
+                mDisplayContent.getDisplayId(), true /* onTop */, new Rect(), sWm).mContainer;
 
         // Stack should contain visible app window to be considered visible.
         final Task pinnedTask = createTaskInStack(mPinnedStack, 0 /* userId */);
         assertFalse(mPinnedStack.isVisible());
-        final WindowTestUtils.TestAppWindowToken pinnedApp = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final WindowTestUtils.TestAppWindowToken pinnedApp = new WindowTestUtils.TestAppWindowToken(
+                mDisplayContent);
         pinnedTask.addChild(pinnedApp, 0 /* addPos */);
         assertTrue(mPinnedStack.isVisible());
     }
@@ -69,8 +70,8 @@
     @Test
     public void testStackPositionChildAt() throws Exception {
         // Test that always-on-top stack can't be moved to position other than top.
-        final TaskStack stack1 = createTaskStackOnDisplay(sDisplayContent);
-        final TaskStack stack2 = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+        final TaskStack stack2 = createTaskStackOnDisplay(mDisplayContent);
 
         final WindowContainer taskStackContainer = stack1.getParent();
 
@@ -94,7 +95,7 @@
     @Test
     public void testStackPositionBelowPinnedStack() throws Exception {
         // Test that no stack can be above pinned stack.
-        final TaskStack stack1 = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
 
         final WindowContainer taskStackContainer = stack1.getParent();
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
index 267e5f7..b846fd0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -45,7 +45,7 @@
 
     @Test
     public void testStackPositionChildAt() throws Exception {
-        final TaskStack stack = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
 
@@ -62,16 +62,16 @@
 
     @Test
     public void testClosingAppDifferentStackOrientation() throws Exception {
-        final TaskStack stack = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
         WindowTestUtils.TestAppWindowToken appWindowToken1 =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task1.addChild(appWindowToken1, 0);
         appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
         WindowTestUtils.TestAppWindowToken appWindowToken2 =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task2.addChild(appWindowToken2, 0);
         appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
@@ -82,16 +82,16 @@
 
     @Test
     public void testMoveTaskToBackDifferentStackOrientation() throws Exception {
-        final TaskStack stack = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task1 = createTaskInStack(stack, 0 /* userId */);
         WindowTestUtils.TestAppWindowToken appWindowToken1 =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task1.addChild(appWindowToken1, 0);
         appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
         WindowTestUtils.TestAppWindowToken appWindowToken2 =
-                new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+                new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task2.addChild(appWindowToken2, 0);
         appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
@@ -102,17 +102,17 @@
 
     @Test
     public void testStackRemoveImmediately() throws Exception {
-        final TaskStack stack = createTaskStackOnDisplay(sDisplayContent);
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
         assertEquals(stack, task.mStack);
-        assertTrue(sDisplayContent.mDimLayerController.hasDimLayerUser(stack));
-        assertTrue(sDisplayContent.mDimLayerController.hasDimLayerUser(task));
+        assertTrue(mDisplayContent.mDimLayerController.hasDimLayerUser(stack));
+        assertTrue(mDisplayContent.mDimLayerController.hasDimLayerUser(task));
 
         // Remove stack and check if its child is also removed.
         stack.removeImmediately();
         assertNull(stack.getDisplayContent());
         assertNull(task.mStack);
-        assertFalse(sDisplayContent.mDimLayerController.hasDimLayerUser(stack));
-        assertFalse(sDisplayContent.mDimLayerController.hasDimLayerUser(task));
+        assertFalse(mDisplayContent.mDimLayerController.hasDimLayerUser(stack));
+        assertFalse(mDisplayContent.mDimLayerController.hasDimLayerUser(task));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
index 98d20a2..1dd9365 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
@@ -41,7 +41,7 @@
     @Test
     public void testRemoveContainer() throws Exception {
         final WindowTestUtils.TestTaskWindowContainerController taskController =
-                new WindowTestUtils.TestTaskWindowContainerController();
+                new WindowTestUtils.TestTaskWindowContainerController(this);
         final WindowTestUtils.TestAppWindowContainerController appController =
                 new WindowTestUtils.TestAppWindowContainerController(taskController);
 
@@ -54,7 +54,7 @@
     @Test
     public void testRemoveContainer_deferRemoval() throws Exception {
         final WindowTestUtils.TestTaskWindowContainerController taskController =
-                new WindowTestUtils.TestTaskWindowContainerController();
+                new WindowTestUtils.TestTaskWindowContainerController(this);
         final WindowTestUtils.TestAppWindowContainerController appController =
                 new WindowTestUtils.TestAppWindowContainerController(taskController);
 
@@ -79,11 +79,11 @@
     @Test
     public void testReparent() throws Exception {
         final StackWindowController stackController1 =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final WindowTestUtils.TestTaskWindowContainerController taskController =
                 new WindowTestUtils.TestTaskWindowContainerController(stackController1);
         final StackWindowController stackController2 =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final WindowTestUtils.TestTaskWindowContainerController taskController2 =
                 new WindowTestUtils.TestTaskWindowContainerController(stackController2);
 
@@ -96,7 +96,7 @@
         assertTrue("Should not be able to reparent to the same parent", gotException);
 
         final StackWindowController stackController3 =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         stackController3.setContainer(null);
         gotException = false;
         try {
@@ -117,13 +117,13 @@
     public void testReparent_BetweenDisplays() throws Exception {
         // Create first stack on primary display.
         final StackWindowController stack1Controller =
-                createStackControllerOnDisplay(sDisplayContent);
+                createStackControllerOnDisplay(mDisplayContent);
         final TaskStack stack1 = stack1Controller.mContainer;
         final WindowTestUtils.TestTaskWindowContainerController taskController =
                 new WindowTestUtils.TestTaskWindowContainerController(stack1Controller);
         final WindowTestUtils.TestTask task1 = (WindowTestUtils.TestTask) taskController.mContainer;
         task1.mOnDisplayChangedCalled = false;
-        assertEquals(sDisplayContent, stack1.getDisplayContent());
+        assertEquals(mDisplayContent, stack1.getDisplayContent());
 
         // Create second display and put second stack on it.
         final DisplayContent dc = createNewDisplay();
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 9392e8e..be53667 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -23,7 +23,6 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doAnswer;
 
-import android.content.pm.ActivityInfo;
 import android.os.PowerSaveState;
 import org.mockito.invocation.InvocationOnMock;
 
@@ -199,7 +198,7 @@
         final com.android.server.wm.WindowState window;
         final AppWindowToken atoken;
         synchronized (sWm.mWindowMap) {
-            atoken = WindowTestsBase.sDisplayContent.getAppWindowToken(appToken);
+            atoken = sWm.mRoot.getAppWindowToken(appToken);
             window = WindowTestsBase.createWindow(null, TYPE_APPLICATION_STARTING, atoken,
                     "Starting window");
             atoken.startingWindow = window;
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 0eaf5bc..5a4bb27 100644
--- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -36,8 +36,6 @@
 @RunWith(AndroidJUnit4.class)
 public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
 
-    private WindowManagerService mWm;
-
     @Before
     public void setUp() throws Exception {
         super.setUp();
@@ -46,7 +44,7 @@
 
     @Test
     public void testFlow() throws Exception {
-        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         sWm.mUnknownAppVisibilityController.notifyLaunched(token);
         sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
         sWm.mUnknownAppVisibilityController.notifyRelayouted(token);
@@ -58,8 +56,8 @@
 
     @Test
     public void testMultiple() throws Exception {
-        final AppWindowToken token1 = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
-        final AppWindowToken token2 = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final AppWindowToken token1 = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
+        final AppWindowToken token2 = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         sWm.mUnknownAppVisibilityController.notifyLaunched(token1);
         sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
         sWm.mUnknownAppVisibilityController.notifyLaunched(token2);
@@ -74,7 +72,7 @@
 
     @Test
     public void testClear() throws Exception {
-        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         sWm.mUnknownAppVisibilityController.notifyLaunched(token);
         sWm.mUnknownAppVisibilityController.clear();;
         assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
@@ -82,7 +80,7 @@
 
     @Test
     public void testAppRemoved() throws Exception {
-        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         sWm.mUnknownAppVisibilityController.notifyLaunched(token);
         sWm.mUnknownAppVisibilityController.appRemoved(token);
         assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
index 956735c..f1e15d9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index a2aa058..8fe4116 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -96,8 +96,7 @@
 
     @Before
     public void setUp() throws Exception {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        sWm = TestWindowManagerPolicy.getWindowManagerService(context);
+        super.setUp();
 
         // Just any non zero value.
         sWm.mSystemDecorLayer = 10000;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
index d5e6b6d..e1f318d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowLayersControllerTests.java
@@ -45,45 +45,45 @@
     @Test
     public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
         sWm.mInputMethodTarget = null;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         // The Ime has an higher base layer than app windows and lower base layer than system
         // windows, so it should be above app windows and below system windows if there isn't an IME
         // target.
-        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindowAbove);
-        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
-        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
-        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
+        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
+        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
+        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
-        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
     }
 
     @Test
     public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
         final WindowState imeAppTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
         sWm.mInputMethodTarget = imeAppTarget;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         // Ime should be above all app windows and below system windows if it is targeting an app
         // window.
-        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
-        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindowAbove);
-        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
-        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
-        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
+        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
+        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
+        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
+        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
-        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
     }
 
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
         final WindowState imeAppTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
         final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
                 TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
                 "imeAppTargetChildAboveWindow");
@@ -92,84 +92,84 @@
                 "imeAppTargetChildBelowWindow");
 
         sWm.mInputMethodTarget = imeAppTarget;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         // Ime should be above all app windows except for child windows that are z-ordered above it
         // and below system windows if it is targeting an app window.
-        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
-        assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, sImeWindow);
-        assertWindowLayerGreaterThan(sImeWindow, imeAppTargetChildBelowWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindowAbove);
-        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
-        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
-        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
+        assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, mImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, imeAppTargetChildBelowWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
+        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
+        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
+        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
-        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
     }
 
     @Test
     public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
         final WindowState appBelowImeTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appBelowImeTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "appBelowImeTarget");
         final WindowState imeAppTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
         final WindowState appAboveImeTarget =
-                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appAboveImeTarget");
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "appAboveImeTarget");
 
         sWm.mInputMethodTarget = imeAppTarget;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         // Ime should be above all app windows except for non-fullscreen app window above it and
         // below system windows if it is targeting an app window.
-        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
-        assertWindowLayerGreaterThan(sImeWindow, appBelowImeTarget);
-        assertWindowLayerGreaterThan(appAboveImeTarget, sImeWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindowAbove);
-        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
-        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
-        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, imeAppTarget);
+        assertWindowLayerGreaterThan(mImeWindow, appBelowImeTarget);
+        assertWindowLayerGreaterThan(appAboveImeTarget, mImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
+        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
+        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
+        assertWindowLayerGreaterThan(mStatusBarWindow, mImeWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
-        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
     }
 
     @Test
     public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
         final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
-                sDisplayContent, "imeSystemOverlayTarget",
+                mDisplayContent, "imeSystemOverlayTarget",
                 true /* ownerCanAddInternalSystemWindow */);
 
         sWm.mInputMethodTarget = imeSystemOverlayTarget;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         // The IME target base layer is higher than all window except for the nav bar window, so the
         // IME should be above all windows except for the nav bar.
-        assertWindowLayerGreaterThan(sImeWindow, imeSystemOverlayTarget);
-        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindowAbove);
-        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
-        assertWindowLayerGreaterThan(sImeWindow, sStatusBarWindow);
-        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeWindow, imeSystemOverlayTarget);
+        assertWindowLayerGreaterThan(mImeWindow, mChildAppWindowAbove);
+        assertWindowLayerGreaterThan(mImeWindow, mAppWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mDockedDividerWindow);
+        assertWindowLayerGreaterThan(mImeWindow, mStatusBarWindow);
+        assertWindowLayerGreaterThan(mNavBarWindow, mImeWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
-        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
+        assertWindowLayerGreaterThan(mImeDialogWindow, mImeWindow);
     }
 
     @Test
     public void testStackLayers() throws Exception {
         WindowState pinnedStackWindow = createWindowOnStack(null, PINNED_STACK_ID,
-                TYPE_BASE_APPLICATION, sDisplayContent, "pinnedStackWindow");
+                TYPE_BASE_APPLICATION, mDisplayContent, "pinnedStackWindow");
         WindowState dockedStackWindow = createWindowOnStack(null, DOCKED_STACK_ID,
-                TYPE_BASE_APPLICATION, sDisplayContent, "dockedStackWindow");
+                TYPE_BASE_APPLICATION, mDisplayContent, "dockedStackWindow");
         WindowState assistantStackWindow = createWindowOnStack(null, ASSISTANT_STACK_ID,
-                TYPE_BASE_APPLICATION, sDisplayContent, "assistantStackWindow");
+                TYPE_BASE_APPLICATION, mDisplayContent, "assistantStackWindow");
 
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
-        assertWindowLayerGreaterThan(dockedStackWindow, sAppWindow);
+        assertWindowLayerGreaterThan(dockedStackWindow, mAppWindow);
         assertWindowLayerGreaterThan(assistantStackWindow, dockedStackWindow);
         assertWindowLayerGreaterThan(pinnedStackWindow, assistantStackWindow);
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index ae3eb52..47ced99 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -92,7 +92,7 @@
     public static class TestAppWindowToken extends AppWindowToken {
 
         TestAppWindowToken(DisplayContent dc) {
-            super(WindowTestsBase.sWm, null, false, dc, true /* fillsParent */,
+            super(dc.mService, null, false, dc, true /* fillsParent */,
                     null /* overrideConfig */, null /* bounds */);
         }
 
@@ -137,7 +137,7 @@
         }
 
         TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
-            super(WindowTestsBase.sWm, mock(IBinder.class), type, persistOnEmpty, dc,
+            super(dc.mService, mock(IBinder.class), type, persistOnEmpty, dc,
                     false /* ownerCanManageAppTokens */);
         }
 
@@ -201,8 +201,8 @@
      */
     public static class TestTaskWindowContainerController extends TaskWindowContainerController {
 
-        TestTaskWindowContainerController() {
-            this(WindowTestsBase.createStackControllerOnDisplay(WindowTestsBase.sDisplayContent));
+        TestTaskWindowContainerController(WindowTestsBase testsBase) {
+            this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
         }
 
         TestTaskWindowContainerController(StackWindowController stackController) {
@@ -219,7 +219,8 @@
                     }, stackController, 0 /* userId */, null /* bounds */,
                     EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE,
                     false /* supportsPictureInPicture */, false /* homeTask*/, true /* toTop*/,
-                    true /* showForAllUsers */, new ActivityManager.TaskDescription(), WindowTestsBase.sWm);
+                    true /* showForAllUsers */, new ActivityManager.TaskDescription(),
+                    stackController.mService);
         }
 
         @Override
@@ -246,8 +247,8 @@
                     true /* showForAllUsers */, 0 /* configChanges */, false /* voiceInteraction */,
                     false /* launchTaskBehind */, false /* alwaysFocusable */,
                     0 /* targetSdkVersion */, 0 /* rotationAnimationHint */,
-                    0 /* inputDispatchingTimeoutNanos */, WindowTestsBase.sWm, null /* overrideConfig */,
-                    null /* bounds */);
+                    0 /* inputDispatchingTimeoutNanos */, taskController.mService,
+                    null /* overrideConfig */, null /* bounds */);
             mToken = token;
         }
 
@@ -265,8 +266,8 @@
                     controller, overrideConfig, bounds);
         }
 
-        AppWindowToken getAppWindowToken() {
-            return (AppWindowToken) WindowTestsBase.sDisplayContent.getWindowToken(mToken.asBinder());
+        AppWindowToken getAppWindowToken(DisplayContent dc) {
+            return (AppWindowToken) dc.getWindowToken(mToken.asBinder());
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 218af73..0167654 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -16,9 +16,9 @@
 
 package com.android.server.wm;
 
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.View.VISIBLE;
 
-import android.app.ActivityManager.TaskDescription;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerGlobal;
 import android.view.Display;
@@ -61,85 +61,67 @@
  */
 class WindowTestsBase {
     static WindowManagerService sWm = null;
-    static TestWindowManagerPolicy sPolicy = null;
-    private final static IWindow sIWindow = new TestIWindow();
-    private final static Session sMockSession = mock(Session.class);
+    private static final IWindow sIWindow = new TestIWindow();
+    private static final Session sMockSession = mock(Session.class);
     // The default display is removed in {@link #setUp} and then we iterate over all displays to
     // make sure we don't collide with any existing display. If we run into no other display, the
     // added display should be treated as default. This cannot be the default display
-    private static int sNextDisplayId = Display.DEFAULT_DISPLAY + 1;
+    private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
     private static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
 
     private static boolean sOneTimeSetupDone = false;
-    static DisplayContent sDisplayContent;
-    static DisplayInfo sDisplayInfo = new DisplayInfo();
-    static WindowLayersController sLayersController;
-    static WindowState sWallpaperWindow;
-    static WindowState sImeWindow;
-    static WindowState sImeDialogWindow;
-    static WindowState sStatusBarWindow;
-    static WindowState sDockedDividerWindow;
-    static WindowState sNavBarWindow;
-    static WindowState sAppWindow;
-    static WindowState sChildAppWindowAbove;
-    static WindowState sChildAppWindowBelow;
-    static HashSet<WindowState> sCommonWindows;
+    DisplayContent mDisplayContent;
+    DisplayInfo mDisplayInfo = new DisplayInfo();
+    WindowLayersController mLayersController;
+    WindowState mWallpaperWindow;
+    WindowState mImeWindow;
+    WindowState mImeDialogWindow;
+    WindowState mStatusBarWindow;
+    WindowState mDockedDividerWindow;
+    WindowState mNavBarWindow;
+    WindowState mAppWindow;
+    WindowState mChildAppWindowAbove;
+    WindowState mChildAppWindowBelow;
+    HashSet<WindowState> mCommonWindows;
 
     @Before
     public void setUp() throws Exception {
-        if (sOneTimeSetupDone) {
-            return;
+        if (!sOneTimeSetupDone) {
+            sOneTimeSetupDone = true;
+            MockitoAnnotations.initMocks(this);
         }
-        sOneTimeSetupDone = true;
-        MockitoAnnotations.initMocks(this);
+
         final Context context = InstrumentationRegistry.getTargetContext();
         AttributeCache.init(context);
         sWm = TestWindowManagerPolicy.getWindowManagerService(context);
-        sPolicy = (TestWindowManagerPolicy) sWm.mPolicy;
-        sLayersController = new WindowLayersController(sWm);
+        mLayersController = new WindowLayersController(sWm);
 
-        // Make sure that display ids don't overlap, so there won't be several displays with same
-        // ids among RootWindowContainer children.
-        for (DisplayContent dc : sWm.mRoot.mChildren) {
-            if (dc.getDisplayId() >= sNextDisplayId) {
-                sNextDisplayId = dc.getDisplayId() + 1;
-            }
-
-            // The default display must be preserved as some tests require it to function
-            // (such as policy rotation).
-            if (dc.getDisplayId() != Display.DEFAULT_DISPLAY) {
-                // It is safe to remove these displays as new displays will always be created with
-                // new ids.
-                dc.removeImmediately();
-            }
-        }
-
-        context.getDisplay().getDisplayInfo(sDisplayInfo);
-        sDisplayContent = createNewDisplay();
+        context.getDisplay().getDisplayInfo(mDisplayInfo);
+        mDisplayContent = createNewDisplay();
         sWm.mDisplayEnabled = true;
         sWm.mDisplayReady = true;
 
         // Set-up some common windows.
-        sCommonWindows = new HashSet();
-        sWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
-        sImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "sImeWindow");
-        sWm.mInputMethodWindow = sImeWindow;
-        sImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG, "sImeDialogWindow");
-        sStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "sStatusBarWindow");
-        sNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "sNavBarWindow");
-        sDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER, "sDockedDividerWindow");
-        sAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "sAppWindow");
-        sChildAppWindowAbove = createCommonWindow(sAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
-                "sChildAppWindowAbove");
-        sChildAppWindowBelow = createCommonWindow(sAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
-                "sChildAppWindowBelow");
+        mCommonWindows = new HashSet();
+        mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
+        mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
+        sWm.mInputMethodWindow = mImeWindow;
+        mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG, "mImeDialogWindow");
+        mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
+        mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
+        mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER, "mDockedDividerWindow");
+        mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
+        mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
+                "mChildAppWindowAbove");
+        mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
+                "mChildAppWindowBelow");
     }
 
     @After
     public void tearDown() throws Exception {
         final LinkedList<WindowState> nonCommonWindows = new LinkedList();
         sWm.mRoot.forAllWindows(w -> {
-            if (!sCommonWindows.contains(w)) {
+            if (!mCommonWindows.contains(w)) {
                 nonCommonWindows.addLast(w);
             }
         }, true /* traverseTopToBottom */);
@@ -148,12 +130,13 @@
             nonCommonWindows.pollLast().removeImmediately();
         }
 
+        mDisplayContent.removeImmediately();
         sWm.mInputMethodTarget = null;
     }
 
-    private static WindowState createCommonWindow(WindowState parent, int type, String name) {
+    private WindowState createCommonWindow(WindowState parent, int type, String name) {
         final WindowState win = createWindow(parent, type, name);
-        sCommonWindows.add(win);
+        mCommonWindows.add(win);
         // Prevent common windows from been IMe targets
         win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
         return win;
@@ -172,7 +155,7 @@
         sWm.mAnimationHandler.runWithScissors(() -> { }, 0);
     }
 
-    private static WindowToken createWindowToken(DisplayContent dc, int stackId, int type) {
+    private WindowToken createWindowToken(DisplayContent dc, int stackId, int type) {
         if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
             return new WindowTestUtils.TestWindowToken(type, dc);
         }
@@ -186,30 +169,30 @@
         return token;
     }
 
-    static WindowState createWindow(WindowState parent, int type, String name) {
+    WindowState createWindow(WindowState parent, int type, String name) {
         return (parent == null)
-                ? createWindow(parent, type, sDisplayContent, name)
+                ? createWindow(parent, type, mDisplayContent, name)
                 : createWindow(parent, type, parent.mToken, name);
     }
 
-    static WindowState createWindowOnStack(WindowState parent, int stackId, int type,
+    WindowState createWindowOnStack(WindowState parent, int stackId, int type,
             DisplayContent dc, String name) {
         final WindowToken token = createWindowToken(dc, stackId, type);
         return createWindow(parent, type, token, name);
     }
 
     WindowState createAppWindow(Task task, int type, String name) {
-        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(sDisplayContent);
+        final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
         task.addChild(token, 0);
         return createWindow(null, type, token, name);
     }
 
-    static WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
         final WindowToken token = createWindowToken(dc, INVALID_STACK_ID, type);
         return createWindow(parent, type, token, name);
     }
 
-    static WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
             boolean ownerCanAddInternalSystemWindow) {
         final WindowToken token = createWindowToken(dc, INVALID_STACK_ID, type);
         return createWindow(parent, type, token, name, ownerCanAddInternalSystemWindow);
@@ -233,23 +216,23 @@
     }
 
     /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */
-    static TaskStack createTaskStackOnDisplay(DisplayContent dc) {
+    TaskStack createTaskStackOnDisplay(DisplayContent dc) {
         return createStackControllerOnDisplay(dc).mContainer;
     }
 
-    static StackWindowController createStackControllerOnDisplay(DisplayContent dc) {
+    StackWindowController createStackControllerOnDisplay(DisplayContent dc) {
         final int stackId = ++sNextStackId;
         return createStackControllerOnStackOnDisplay(stackId, dc);
     }
 
-    static StackWindowController createStackControllerOnStackOnDisplay(int stackId,
+    StackWindowController createStackControllerOnStackOnDisplay(int stackId,
             DisplayContent dc) {
         return new StackWindowController(stackId, null, dc.getDisplayId(),
                 true /* onTop */, new Rect(), sWm);
     }
 
     /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
-    static Task createTaskInStack(TaskStack stack, int userId) {
+    Task createTaskInStack(TaskStack stack, int userId) {
         return WindowTestUtils.createTaskInStack(sWm, stack, userId);
     }
 
@@ -257,8 +240,8 @@
     DisplayContent createNewDisplay() {
         final int displayId = sNextDisplayId++;
         final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
-                sDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
-        return new DisplayContent(display, sWm, sLayersController, new WallpaperController(sWm));
+                mDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
+        return new DisplayContent(display, sWm, mLayersController, new WallpaperController(sWm));
     }
 
     /** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index 4f7ad41..692e08b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -47,7 +47,7 @@
     @Test
     public void testAddWindow() throws Exception {
         final WindowTestUtils.TestWindowToken token =
-                new WindowTestUtils.TestWindowToken(0, sDisplayContent);
+                new WindowTestUtils.TestWindowToken(0, mDisplayContent);
 
         assertEquals(0, token.getWindowsCount());
 
@@ -76,7 +76,7 @@
 
     @Test
     public void testChildRemoval() throws Exception {
-        final DisplayContent dc = sDisplayContent;
+        final DisplayContent dc = mDisplayContent;
         final WindowTestUtils.TestWindowToken token = new WindowTestUtils.TestWindowToken(0, dc);
 
         assertEquals(token, dc.getWindowToken(token.token));
@@ -97,7 +97,7 @@
     @Test
     public void testAdjustAnimLayer() throws Exception {
         final WindowTestUtils.TestWindowToken token =
-                new WindowTestUtils.TestWindowToken(0, sDisplayContent);
+                new WindowTestUtils.TestWindowToken(0, mDisplayContent);
         final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
         final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
         final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
@@ -109,7 +109,7 @@
 
         // We assign layers once, to get the base values computed by
         // the controller.
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
 
         final int window1StartLayer = window1.mWinAnimator.mAnimLayer;
         final int window11StartLayer = window11.mWinAnimator.mAnimLayer;
@@ -120,7 +120,7 @@
         // Then we set an adjustment, and assign them again, they should
         // be offset.
         int adj = token.adj = 50;
-        sLayersController.assignWindowLayers(sDisplayContent);
+        mLayersController.assignWindowLayers(mDisplayContent);
         final int highestLayer = token.getHighestAnimLayer();
 
         assertEquals(window1StartLayer + adj, window1.mWinAnimator.mAnimLayer);
@@ -138,18 +138,18 @@
     @Test
     public void testTokenRemovalProcess() throws Exception {
         final WindowTestUtils.TestWindowToken token =
-                new WindowTestUtils.TestWindowToken(TYPE_TOAST, sDisplayContent,
+                new WindowTestUtils.TestWindowToken(TYPE_TOAST, mDisplayContent,
                         true /* persistOnEmpty */);
 
         // Verify that the token is on the display
-        assertNotNull(sDisplayContent.getWindowToken(token.token));
+        assertNotNull(mDisplayContent.getWindowToken(token.token));
 
         final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1");
         final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2");
 
-        sDisplayContent.removeWindowToken(token.token);
+        mDisplayContent.removeWindowToken(token.token);
         // Verify that the token is no longer mapped on the display
-        assertNull(sDisplayContent.getWindowToken(token.token));
+        assertNull(mDisplayContent.getWindowToken(token.token));
         // Verify that the token is still attached to its parent
         assertNotNull(token.getParent());
         // Verify that the token windows are still around.
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 094c7bd..2ebf5fc 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -235,7 +235,14 @@
             final int appId = UserHandle.getUserId(appInfo.uid);
             final String[] packageNames = new String[] { packageName };
             final long[] ceDataInodes = new long[1];
-            final String[] codePaths = new String[] { appInfo.getCodePath() };
+            String[] codePaths = new String[0];
+
+            if (appInfo.isSystemApp() && !appInfo.isUpdatedSystemApp()) {
+                // We don't count code baked into system image
+            } else {
+                codePaths = ArrayUtils.appendElement(String.class, codePaths,
+                        appInfo.getCodePath());
+            }
 
             final PackageStats stats = new PackageStats(TAG);
             try {
@@ -261,12 +268,18 @@
 
         final String[] packageNames = mPackage.getPackagesForUid(uid);
         final long[] ceDataInodes = new long[packageNames.length];
-        final String[] codePaths = new String[packageNames.length];
+        String[] codePaths = new String[0];
 
         for (int i = 0; i < packageNames.length; i++) {
             try {
-                codePaths[i] = mPackage.getApplicationInfoAsUser(packageNames[i],
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES, userId).getCodePath();
+                final ApplicationInfo appInfo = mPackage.getApplicationInfoAsUser(packageNames[i],
+                        PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+                if (appInfo.isSystemApp() && !appInfo.isUpdatedSystemApp()) {
+                    // We don't count code baked into system image
+                } else {
+                    codePaths = ArrayUtils.appendElement(String.class, codePaths,
+                            appInfo.getCodePath());
+                }
             } catch (NameNotFoundException e) {
                 throw new ParcelableException(e);
             }
@@ -297,15 +310,7 @@
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
         }
 
-        int[] appIds = null;
-        for (ApplicationInfo app : mPackage.getInstalledApplicationsAsUser(
-                PackageManager.MATCH_UNINSTALLED_PACKAGES, userId)) {
-            final int appId = UserHandle.getAppId(app.uid);
-            if (!ArrayUtils.contains(appIds, appId)) {
-                appIds = ArrayUtils.appendInt(appIds, appId);
-            }
-        }
-
+        final int[] appIds = getAppIds(userId);
         final PackageStats stats = new PackageStats(TAG);
         try {
             mInstaller.getUserSize(volumeUuid, userId, getDefaultFlags(), appIds, stats);
@@ -330,12 +335,14 @@
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
         }
 
+        final int[] appIds = getAppIds(userId);
         final long[] stats;
         try {
-            stats = mInstaller.getExternalSize(volumeUuid, userId, getDefaultFlags());
+            stats = mInstaller.getExternalSize(volumeUuid, userId, getDefaultFlags(), appIds);
 
             if (SystemProperties.getBoolean(PROP_VERIFY_STORAGE, false)) {
-                final long[] manualStats = mInstaller.getExternalSize(volumeUuid, userId, 0);
+                final long[] manualStats = mInstaller.getExternalSize(volumeUuid, userId, 0,
+                        appIds);
                 checkEquals("External " + userId, manualStats, stats);
             }
         } catch (InstallerException e) {
@@ -347,9 +354,22 @@
         res.audioBytes = stats[1];
         res.videoBytes = stats[2];
         res.imageBytes = stats[3];
+        res.appBytes = stats[4];
         return res;
     }
 
+    private int[] getAppIds(int userId) {
+        int[] appIds = null;
+        for (ApplicationInfo app : mPackage.getInstalledApplicationsAsUser(
+                PackageManager.MATCH_UNINSTALLED_PACKAGES, userId)) {
+            final int appId = UserHandle.getAppId(app.uid);
+            if (!ArrayUtils.contains(appIds, appId)) {
+                appIds = ArrayUtils.appendInt(appIds, appId);
+            }
+        }
+        return appIds;
+    }
+
     private static int getDefaultFlags() {
         if (SystemProperties.getBoolean(PROP_DISABLE_QUOTA, false)) {
             return 0;
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 31595a6..bb453a9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -63,6 +63,7 @@
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Random;
 import java.util.Scanner;
 import java.util.Set;
 
@@ -537,6 +538,7 @@
                     oldFunctions = UsbManager.USB_FUNCTION_NONE;
                 }
 
+                Slog.i(TAG, "Setting adb to " + String.valueOf(enable));
                 setEnabledFunctions(oldFunctions, true, mUsbDataUnlocked);
                 updateAdbNotification();
             }
@@ -764,15 +766,16 @@
 
             // send broadcast intent only if the USB state has changed
             if (!isUsbStateChanged(intent)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
-                }
+                Slog.i(TAG, "skip broadcasting " + intent + " extras: " + intent.getExtras());
                 return;
             }
-
-            if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
-            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
             mBroadcastedIntent = intent;
+
+            Random rand = new Random();
+            intent.putExtra("random_tag", rand.nextInt(1000));
+            Slog.i(TAG, "broadcasting " + intent + " extras: " + intent.getExtras());
+            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+            intent.removeExtra("random_tag");
         }
 
         private void updateUsbFunctions() {
@@ -840,6 +843,10 @@
 
                     updateUsbNotification();
                     updateAdbNotification();
+                    if (mBootCompleted) {
+                        Slog.i(TAG, "update state " + mConnected + " " + mConfigured);
+                        updateUsbStateBroadcastIfNeeded(false);
+                    }
                     if (UsbManager.containsFunction(mCurrentFunctions,
                             UsbManager.USB_FUNCTION_ACCESSORY)) {
                         updateCurrentAccessory();
@@ -847,9 +854,9 @@
                     if (mBootCompleted) {
                         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;
@@ -880,6 +887,7 @@
                     break;
                 case MSG_SET_CURRENT_FUNCTIONS:
                     String functions = (String) msg.obj;
+                    Slog.i(TAG, "Getting setFunction command for " + functions);
                     setEnabledFunctions(functions, false, msg.arg1 == 1);
                     break;
                 case MSG_UPDATE_USER_RESTRICTIONS:
@@ -887,6 +895,8 @@
                     final boolean forceRestart = mUsbDataUnlocked
                             && isUsbDataTransferActive()
                             && !isUsbTransferAllowed();
+                    Slog.i(TAG, "Updating user restrictions, force restart is "
+                            + String.valueOf(forceRestart));
                     setEnabledFunctions(
                             mCurrentFunctions, forceRestart, mUsbDataUnlocked && !forceRestart);
                     break;
@@ -901,6 +911,7 @@
                         updateUsbStateBroadcastIfNeeded(false);
                         mPendingBootBroadcast = false;
                     }
+                    Slog.i(TAG, "Boot complete, setting default functions");
                     setEnabledFunctions(null, false, false);
                     if (mCurrentAccessory != null) {
                         getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -918,6 +929,7 @@
                             Slog.v(TAG, "Current user switched to " + msg.arg1
                                     + "; resetting USB host stack for MTP or PTP");
                             // avoid leaking sensitive data from previous user
+                            Slog.i(TAG, "User Switched, kicking usb stack");
                             setEnabledFunctions(mCurrentFunctions, true, false);
                         }
                         mCurrentUser = msg.arg1;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 7998359..dc0c485 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -865,6 +865,7 @@
      * {@link Call#sendRttRequest()}
      */
     public static final class RttModifyStatus {
+        private RttModifyStatus() {}
         /**
          * Session modify request was successful.
          */
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 0342da7..0a47a98 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -16,6 +16,7 @@
 
 import android.Manifest;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
@@ -46,6 +47,7 @@
  * permissions declared in its manifest file. Where permissions apply, they are noted in the method
  * descriptions.
  */
+@SuppressAutoDoc
 public class TelecomManager {
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8ee6454..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,22 +876,54 @@
     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";
 
     /**
      * USSD return code success.
+     * @hide
      */
     public static final int USSD_RETURN_SUCCESS = 100;
 
     /**
-     * USSD return code for failure case.
+     * Failed code returned when the mobile network has failed to complete a USSD request.
+     * <p>
+     * Returned via {@link TelephonyManager.UssdResponseCallback#onReceiveUssdResponseFailed(
+     * TelephonyManager, String, int)}.
      */
     public static final int USSD_RETURN_FAILURE = -1;
 
     /**
-     * USSD return code for failure case.
+     * Failure code returned when a USSD request has failed to execute because the Telephony
+     * service is unavailable.
+     * <p>
+     * Returned via {@link TelephonyManager.UssdResponseCallback#onReceiveUssdResponseFailed(
+     * TelephonyManager, String, int)}.
      */
     public static final int USSD_ERROR_SERVICE_UNAVAIL = -2;
 
@@ -906,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());
     }
@@ -919,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;
@@ -942,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();
@@ -966,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 {
@@ -992,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());
     }
@@ -1004,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;
@@ -1024,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());
     }
@@ -1035,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;
@@ -1095,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();
@@ -1133,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());
     }
@@ -1147,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();
@@ -1167,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());
     }
@@ -1190,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();
@@ -1554,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);
@@ -1721,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();
@@ -1751,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
@@ -1774,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()));
     }
@@ -1784,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();
@@ -1810,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();
@@ -2228,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());
     }
@@ -2241,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();
@@ -2267,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());
     }
@@ -2285,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();
@@ -2315,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());
     }
@@ -2327,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();
@@ -2351,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();
@@ -2372,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();
@@ -2397,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());
     }
@@ -2414,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 {
@@ -2497,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());
     }
@@ -2511,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 {
@@ -2566,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());
     }
@@ -2579,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();
@@ -2602,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());
     }
@@ -2613,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();
@@ -2635,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();
@@ -2724,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
@@ -2734,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();
@@ -2766,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
@@ -2863,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.
@@ -2877,6 +2899,7 @@
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.SEND_SMS)
     public void sendVisualVoicemailSmsForSubscriber(int subId, String number, int port,
             String text, PendingIntent sentIntent) {
         try {
@@ -2981,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
@@ -2993,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();
@@ -3007,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
@@ -3020,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();
@@ -3034,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();
@@ -3068,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());
     }
@@ -3079,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();
@@ -3396,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();
@@ -3432,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());
     }
@@ -3446,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();
@@ -3468,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());
     }
@@ -3480,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();
@@ -3567,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();
@@ -4427,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);
     }
@@ -4440,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();
@@ -5133,27 +5124,39 @@
         return new int[0];
     }
 
-    /* The caller of {@link #sendUssdRequest(String, UssdResponseCallback, Handler} provides
-     * once the network returns a USSD message or if there is failure.
-     * Either {@link #onReceiveUssdResponse(TelephonyManager, String, CharSequence} or
-     * {@link #onReceiveUssdResponseFailed(TelephonyManager, String, int} will be called.
+    /**
+     * Used to notify callers of
+     * {@link TelephonyManager#sendUssdRequest(String, UssdResponseCallback, Handler)} when the
+     * network either successfully executes a USSD request, or if there was a failure while
+     * executing the request.
+     * <p>
+     * {@link #onReceiveUssdResponse(TelephonyManager, String, CharSequence)} will be called if the
+     * USSD request has succeeded.
+     * {@link #onReceiveUssdResponseFailed(TelephonyManager, String, int)} will be called if the
+     * USSD request has failed.
      */
     public static abstract class UssdResponseCallback {
        /**
-        * Called when USSD has succeeded. The calling app can choose to either display the message
-        * or interpret the message.
+        * Called when a USSD request has succeeded.  The {@code response} contains the USSD
+        * response received from the network.  The calling app can choose to either display the
+        * response to the user or perform some operation based on the response.
+        * <p>
+        * USSD responses are unstructured text and their content is determined by the mobile network
+        * operator.
+        *
         * @param telephonyManager the TelephonyManager the callback is registered to.
-        * @param request the ussd code sent to the network.
-        * @param response the response from the network.
+        * @param request the USSD request sent to the mobile network.
+        * @param response the response to the USSD request provided by the mobile network.
         **/
        public void onReceiveUssdResponse(final TelephonyManager telephonyManager,
                                          String request, CharSequence response) {};
 
        /**
-        * Called when USSD has failed.
-        * @param telephonyManager the TelephonyManager the callback is registered to
-        * @param request the ussd code.
-        * @param failureCode failure code, should be either of
+        * Called when a USSD request has failed to complete.
+        *
+        * @param telephonyManager the TelephonyManager the callback is registered to.
+        * @param request the USSD request sent to the mobile network.
+        * @param failureCode failure code indicating why the request failed.  Will be either
         *        {@link TelephonyManager#USSD_RETURN_FAILURE} or
         *        {@link TelephonyManager#USSD_ERROR_SERVICE_UNAVAIL}.
         **/
@@ -5162,8 +5165,8 @@
     }
 
     /**
-     * Sends an Unstructured Supplementary Service Data (USSD) request to the cellular network and
-     * informs the caller of the response via {@code callback}.
+     * Sends an Unstructured Supplementary Service Data (USSD) request to the mobile network and
+     * informs the caller of the response via the supplied {@code callback}.
      * <p>Carriers define USSD codes which can be sent by the user to request information such as
      * the user's current data balance or minutes balance.
      * <p>Requires permission:
@@ -6123,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/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index caf1a55..a3f33dc 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -32,7 +32,6 @@
 import static android.net.ConnectivityManager.TETHERING_USB;
 import static android.net.ConnectivityManager.TETHERING_WIFI;
 import static com.android.server.connectivity.tethering.IControlsTethering.STATE_AVAILABLE;
-import static com.android.server.connectivity.tethering.IControlsTethering.STATE_LOCAL_HOTSPOT;
 import static com.android.server.connectivity.tethering.IControlsTethering.STATE_TETHERED;
 import static com.android.server.connectivity.tethering.IControlsTethering.STATE_UNAVAILABLE;
 
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/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 1852feb..229aa97 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -125,6 +125,10 @@
 
     void setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
 
+    boolean startSoftAp(in WifiConfiguration wifiConfig);
+
+    boolean stopSoftAp();
+
     int getWifiApEnabledState();
 
     WifiConfiguration getWifiApConfiguration();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 7268ee5..ed54c3b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -16,6 +16,7 @@
 
 package android.net.wifi;
 
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -1731,6 +1732,39 @@
     }
 
     /**
+     * Start SoftAp mode with the specified configuration.
+     * Note that starting in access point mode disables station
+     * mode operation
+     * @param wifiConfig SSID, security and channel details as
+     *        part of WifiConfiguration
+     * @return {@code true} if the operation succeeds, {@code false} otherwise
+     *
+     * @hide
+     */
+    public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) {
+        try {
+            return mService.startSoftAp(wifiConfig);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stop SoftAp mode.
+     * Note that stopping softap mode will restore the previous wifi mode.
+     * @return {@code true} if the operation succeeds, {@code false} otherwise
+     *
+     * @hide
+     */
+    public boolean stopSoftAp() {
+        try {
+            return mService.stopSoftAp();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Gets the Wi-Fi enabled state.
      * @return One of {@link #WIFI_AP_STATE_DISABLED},
      *         {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
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
      */